jQueryUI draggable and resizable with knockout.js

Jul 20, 2013

1 min read

Javascript

Author picture

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)