Click here to Skip to main content
15,896,111 members
Articles / Programming Languages / Javascript
Technical Blog

jQueryUI draggable and resizable with knockout.js

Rate me:
Please Sign up or sign in to vote.
2.00/5 (1 vote)
20 Jul 2013CPOL 12K   3   1
jQueryUI draggable and resizable with knockout.js.

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)


Written By
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 2 Pin
stefanonepa23-Jul-13 2:11
professionalstefanonepa23-Jul-13 2:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.