jQueryUI draggable and resizable with knockout.js
Jul 20, 2013
1 min read
Javascript

by m_kramar
Contributor
12k Views
Situation: viewModel is rendered on the client using knockout.js; part of the model is a collection of resizable and draggable divs.
The problem: once the div is dragged/resised how to update the model with new coordinates?
The solution is to use custom binding and handle the event of end of resize and end of drag. See jqDraggableResizable in the following example:
XML
<html>
<head>
<title></title>
<link href="http://www.codeproject.com/Styles/base/jquery.ui.all.css" rel="stylesheet" type="text/css" />
<link href="Styles/Site.css" rel="stylesheet" type="text/css" />
<script src="http://www.codeproject.com/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="http://www.codeproject.com/Scripts/jquery-ui-1.8.11.min.js" type="text/javascript"></script>
<script src="http://www.codeproject.com/Scripts/jquery.tmpl.js" type="text/javascript"></script>
<script src="http://www.codeproject.com/Scripts/knockout-1.2.0.js" type="text/javascript"></script>
<script>
var viewModel = {
Hotspots: ko.observableArray([
{
X: ko.observable(527),
Y: ko.observable(195),
H: ko.observable(121),
W: ko.observable(140)
},
{
X: ko.observable(699),
Y: ko.observable(193),
H: ko.observable(294),
W: ko.observable(269)
}
])
};
viewModel.currentHotspot = ko.observable({ Text: null });
viewModel.addNew = function () {
viewModel.Hotspots.push({ X: ko.observable(50), Y: ko.observable(50),
H: ko.observable(100), W: ko.observable(100), Text: ko.observable('new hotspot') });
};
//
$(document).ready(function () {
$('#btnSave').click(function () {
$.ajax({
url: '/Save.ashx',
contentType: "application/json; charset=utf-8",
type: 'POST',
dataType: 'json',
data: ko.toJSON(viewModel),
error: function () { alert("ajax error"); }
});
});
ko.bindingHandlers.jqDraggableResizable = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var obj = valueAccessor();
var $elem = $(element);
element.dataObj = obj;
$elem.resizable({
stop: function (event, ui) {
this.dataObj.H(ui.size.height);
this.dataObj.W(ui.size.width);
}
});
$elem.draggable({
stop: function (event, ui) {
this.dataObj.X(ui.position.left);
this.dataObj.Y(ui.position.top);
}
});
}
}
ko.applyBindings(viewModel);
});
</script>
</head>
<body>
<div class="main">
<div data-bind='template: "hotspotTemplate"'></div>
<input type='button' id='btnAdd' value="add new"
data-bind='click: function() { viewModel.addNew(); }' />
<input type='button' id='btnSave' value="save it!" />
<script id='hotspotTemplate' type='text/x-jquery-tmpl'>
{{each(i, h) Hotspots}}
<div class="resizable"
style="position:absolute; left: ${ X }px; top: ${ Y }px; width: ${ W }px; height: ${ H }px;"
data-bind="jqDraggableResizable : h">
</div>
{{/each}}
</script>
</div>
</body>
</html>
License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)