Search code examples
jquery-uiknockout.jsjquery-ui-resizable

How to watch styles with Knockout


What I want to do is track the (top, left, width, height, zIndex) style attributes. But since the element that holds these styles doesn't exist until after third party code gets pulled in, i can't do it the normal way.

Here's what I've got thus far:

    my.Module = function (module) {
    return {
            top: ko.observable(200);,
            left: ko.observable(100);,
            width: ko.observable(100);,
            height: ko.observable(100);,
            zIndex: ko.observable(0);,
        };
    };

This would be the normal binding context:

<div data-bind="style:{width:width, top:top, left:left, height:height, zindex:zIndex}"></div>

But the third party stuff ends up wrapping the div i pass it within another, and this is something I cannot change. So instead I've started creating a custom bindinghandler:

 ko.bindingHandlers.Window = {
        init: function (element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor());

            //Do third party creation stuff here...

            ko.applyBindingsToNode(elemToActuallyWatch, {
                style: {
                    width: value.width() + 'px',
                    height: value.height() + 'px',
                    top: value.top() + 'px',
                    left: value.left() + 'px',
                    zIndex: value.zIndex()
                }
            });
        },

Now this applies the above styles to the appropriate div, but i still need the above values to change when both the data changes and when the element changes.

I feel like the 'px' that i have to tack on the ends shouldn't be needed but that was the only way i could get them to apply.

Is there a way from this point on, that lets say I'm using jqueryUI draggable and resizable, and a user moves/resizes the element that the values will automatically update the viewmodel data? Of course a non jquery specific answer would be best.


Solution

  • style is a one-way binding, from model to view. It won't update the model from the view. You'll probably need to use the resize option and update the model from there.