Introduction
The solution here presented talks about how to bind jQuery interactions like Resizable, Draggable with the KnockoutJs MVVM. In this tip, I am going to demonstrate how to bind jQuery UI resizable to a Knockout Observable.

We are going to build a div
and make it resizable so that the div
can be resized. The width and the height of the expanded div
would appear on the textbox
es below as we resize the div
.
Background
Basic Introduction about KnockoutJs:
KnockoutJS is a client side JavaScript library which implements the MVVM pattern. There is an excellent article written on MVVM pattern - http://www.codeproject.com/Articles/100175/Model-View-ViewModel-MVVM-Explained
KnockoutJS is built on three core features:
- Observables and Dependency Tracking
- Declarative Bindings
- Templating
Observables are special JavaScript that notify subscribers about changes and can automatically detect dependencies. Declarative Bindings are to link View Model to the View.
jQuery UI:
jQueryUI is a client side JavaScript library developed by the jQuery Team, which provides us with a collection of UI Widgets, visual effects, themes etc. Along with these, it provides us with the following interactions:
- Draggable
- Droppable
- Resizable
- Selectable
- Sortable
Let’s Begin
This sample is created using ASP.NET MVC application, and you can create this in any web application.
Open Visual Studio and create an ASP.NET MVC Empty Application. Create a Home Controller within the Controller Folder. Create a folder inside "View" folder named "Home". Right click, create a view "index.cshtml"
Open Package Manager Console, Run the following command to install the KnockoutJS
library:
PM> Install-Package knockoutjs
This will bring the KnockoutJS
library inside the Scripts Folder.
Open the Layout.cshtml remove all the references for the @scripts
and place the following code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>KnockoutJs Sandbox</title>
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<script src="~/Scripts/knockout-3.3.0.js"></script>
</head>
<body>
@RenderBody()
</body>
</html>
Let us create the HTML first. We will create a div
, which would be made resizable and then two labels below that showing the width
and the height
respectively.
<div style="padding: 20px;">
<div style="background-color:green">
</div>
<div>
Height: <label></label>
Width: <label></label>
</div>
</div>
Then, we create the view model, containing two observables -> one to hold the width
of the div
and one to hold the height
of the div
. Since it needs to be bound to the div
, we need to create two computed observables for returning the value in pixels.
<script>
$(function () {
var box = function (hght, wdth) {
var self = this;
self.ht = ko.observable(hght);
self.wt = ko.observable(wdth);
self.formattedht = ko.computed(function () {
return self.ht() + "px";
});
self.formattedwt = ko.computed(function () {
return self.wt() + "px";
});
}
ko.applyBindings(new box(50, 200));
});
</script>
Now let us get back to the HTML and wire the observables to the DIV
property. The Style
Binding is applied and set the height
and the width
of the property has been set to the "formattedht
" and "formattedwt
" property respectively. The label
text are bound to the same variable to see the value.
<div style="padding: 20px;">
<div class="box" style="background-color:green"
data-bind="style:{ height:formattedht, width: formattedwt }">
</div>
<div>
Height: <label data-bind="text:formattedht" ></label>
Width: <label data-bind="text:formattedwt" ></label>
</div>
</div>
Now if we make the div
resizable by calling the jQuery UI method, $(".box").resizable();
the value in the box will not change when the div
is resized. Hence, we need to create a custom binding. Inside the script
tag, insert the following code. Give a name to the custom binding name -> ko.bindingHandlers."resizable"
ko.bindingHandlers.resizable = {
init: function (element, valueAccessor, allBindings, vModel, bindingContext) {
$(element).resizable({
resize: function (event, ui) {
vModel.ht(ui.size.height);
vModel.wt(ui.size.width);
}
});
},
update: function (element, valueAccessor, allBindings, vModel, bindingContext) {
}
};
In the "init
" event, make the element resizable, attach the event handler "resize
" get the height
and width
and set it to the viewModel
"ht
" and "wt
" observable. That’s it. Now when you resize the div
– box, the value of the width
and the height
gets displayed on the label
s.