Wilsonhut

Deal with it or don't

Tag Archives: jquery

$.gasp is published!

jQuery Gasp is published. It’s almost as if they let just anyone on the internet. Am I right?

Advertisements

$.defer renamed to $.whereas, and published

Only because the name $.defer was already taken.

jQuery Whereas

A promisified, progress revealing, cancellable setTimeout

$.defer for advanced promise users – progress, only when you need it!

EDIT: $.defer was renamed to $.whereas

[If you’re not familiar with $.defer, you can go read about it, or just go look at the code.]

Let’s say you have an long-running script inside a function, and you only want to do that work once, even though the function might get called more than once. That function might look like this:

function initializeTheDifficultStuff(){
 if ($(".importantStuff").data("isInitialized")){
   return;
 }
 // Do the difficult stuff

  $(".importantStuff").data("isInitialized", true);
}

The difficult stuff might be some ajax or some other long-running, dom-manipulating javascript.

Now, lets say you decide to make that use the $.Deferred() / promise jQuery feature. Modifying the code above, you could do something like this:

function initializeTheDifficultStuff(){
  if ($(".importantStuff").data("isInitialized")){
    return $.when(); // $.when() returns a resolved promise.
  }
  var d = $.Deferred();
  // Do the difficult stuff
  $(".importantStuff").data("isInitialized", true);
  d.resolve();  
  return d.promise();
}

Now that doesn’t get you much, except the ability to use the .then/.done methods when you call initializeTheDifficultStuff(), since the ‘difficult stuff’ is not asyncronous. If the ‘difficult stuff’ was an ajax call, and you put the d.resolve() in its callback, then you’d have something.

I discussed all of this in a previous post, but now I want to take it a step further…

What if you want to use the progress callback to show a ‘please wait…’ message?

What if you want to use the above method like this? (Here, I’m using the $.blockUI plug-in)

initializeTheDifficultStuff()
  .progress(function(){
    $.blockUI();
  })
  .done(function(){
    //.. show something, do something else.
    $.unblockUI();
  });

The reason you might WANT to do that is so that you could keep the $.blockUI call from happening if the “isInitialized” is already set. That’s what you want, since it’s not going to have to do the hard work in that case, and the $.blockUI call starts a fade-in which would be unnecessary.

Now that gets more difficult with the above implementation of initializeTheDifficultStuff, because, unlike the done and then, events, the progress is never called on a pre-resolved promise. So what can you do? You can return the d.promise, like above, but just before that, put a call to d.notify and d.resolve in a setTimeout. That would start to look ugly real fast. I’m not even going to show that.

$.defer handles this all for you.

You can use the initializeTheDifficultStuff() with the progress and done events, and have clean looking code by using $.defer, like so:

function initializeTheDifficultStuff(){
  if ($(".importantStuff").data("isInitialized")){
    return $.when(); // $.when() returns a resolved promise.
  }

  $(".importantStuff").data("isInitialized", true);
  return $.defer()
       .then(function(){
         // Do the difficult stuff
       });
}

The $.when() returns a resolved promise, so your progress event handler doesn’t get called!
$.defer returns an un-resolved promise. And in this example, it would wait the minimum number of milliseconds, then do the magic. Here’s what it will do for you…
It will first cause your progress event handler to get called. Then it runs the ‘difficult stuff’ for you. Then it is resolved so that your done event handler gets called.

It’s all so pretty and neat, and you get the progress event only when you need it!

Go get the $.defer plug-in from github today!

Introducing… jQuery Gasp – Give a little breathing room to your browser-intensive jQuery

Have you ever done something like…

$("td").someBigNastyPlugin();

…and it was just too much processing for your browser? (I’m looking at you, IE)

It would be nice if your browser had a little bit of time to catch its breath while it’s trying to do all that processing.

jQuery.gasp to the rescue!

Include my gasp plug-in, and replace that code above with the following, and you’ll have a happy browser.

$("td").gasp(function(){
  $(this).someBigNastyPlugin();
});

Essentially, it’s like jquery’s .each function, but it puts a setTimeout around each one, and chains them together, one after the other. If you saw my defer plug-in, this will make more sense.

Now this is asyncronous, but it returns a promise, so you have to treat it accordingly:

$("td").gasp(function(){
  $(this).someBigNastyPlugin();
})
.done(function(){
  console.log("This will run when it's complete");
});
console.log("This will run before the gasping is finished");

The code for this plug-in is below, but the code below requires my jquery.defer plugin.

The jquery.gasp plug-in (on github) includes the jquery.defer code. Just seemed easier (for you) that way.

In later posts, I’ll show you some other cool things you can do with this other than give your browser a little relief. (Spoiler: Remember that $(…) can take things other than a selector string as an argument.)

;(function ($) {
    var defaults = {
		breathTime: 0,
		wait: 0
	};
	$.fn.gasp = function (func, options, promise) {
		options = $.extend({}, defaults, options);
		promise = promise || $.when();
		var isFirst = true;
		this.each(function () {
			var self = this;
			promise = promise.then(function () {
				var p = $.defer(function (el) {
					func.call(el);
				}, (isFirst? options.wait : options.breathTime), self);
				isFirst = false;
				return p;
			});
		});
		return promise;
	};
})(jQuery);

jquery-defer (a jQuery Deferred-ified/promisified setTimeout) is on github

jQuery Deferred-ified window.setTimeout

EDIT: $.defer was renamed to $.whereas

[Code] [jsfiddle sample][on github]

“Too bad you can’t use window.setTimout and have it implement the jQuery Deferred interface.”

We’re all upset about that. So…

“Wait. What? Now you can?!?”

Right. Now you can. I searched the internet and couldn’t find an existing one, to my surprise. I wrote it for you though.

You can skip right to the Code below, skip to a jsfiddle sample, or keep reading for more explanation.

It’s almost as simple as my sample code in my last post explaining the basics of Deferred with the addition of an actual setTimeout… Make a $.Deferred. Call the provided func in a setTimeout, using the provided delay and parameters. After the call to the provided func, call .resolve, and in a catch block, call .reject.

“How do you use it?”

Use it just like setTimeout
setTimeout:

setTimeout(function(){
    console.log("I'm in the future. " + new Date());
}, 2000);

My new $.defer method:

$.defer(function(){
    console.log("I'm in the future. " + new Date());
}, 2000);

It’s the same. You can even pass parameters, just like setTimout. (I didn’t bother implementing the overload that takes a string and eval’s it, because who cares)

“So what’s the big deal?”

  • It works the same way as your beloved setTimeout, only with the $.defer, you can chain callbacks on the end…
    $.defer(function(){
        console.log("I'm in the future. " + new Date());
    }, 2000)
    .done(function(){
        console.log("All done");
    });
    

    and you get all the benefits of the rest of the callbacks – done/fail/then/always, etc.

  • You can use it anywhere that expects a promise – for example, you can use it as a participant in jQuery’s $.when()!
  • Since there are callbacks, you have a way to get the return value of the function that you called.
    $.defer(function(){
        return "no you didn't";
    }, 2000)
    .done(function(x){
        console.log(x); // x is "no you didn't" 
    });
    
  • It’s cancel-able.
    $.defer(function(){
       console.log("Doing work...");
    }, 2000)
    .progress(function(){
        console.log("Sorry to have to cancel this.");
        this.cancel();
    })
    .done(function(){
        console.log("Won't get here.");
    })
    .fail(function(){
        console.log("This will happen");
    });
  • You can use it without the function parameter to return a promise that will resolve in [delay] milliseconds

    return $.defer(100);
    

    The delay is optional too. The default delay of 0 (zero) will be used.

    return $.defer(function(){alert("ASYNC!");});
    

    or

    return $.defer();
    

“You had me at ‘Promise’, now shut up and give me the code”

Here it is. It’s a little longer than the way I explained it above, but that’s just because it has the code for cancelling, and I like for the actually code to look long and complex to make me look smarter.


THE CODE


;(function($) {
	var slice = Array.prototype.slice;
	$.defer = function( /*[func] [, delay] [, funcParameters]*/) {
		var args = arguments,
		    isFunc = $.isFunction(args[0]),
		    func = isFunc ? args[0] : $.noop,
		    delay = (isFunc ? args[1] : args[0]) || 0,
		    funcArgs = isFunc ? slice.call(args, 2) : [],
		    isCancelled = false,
		    cancel = function(reject /* = true */) {
			    clearTimeout(timerId);
			    isCancelled = true;
			    if ((!arguments.length || reject) && deferred.state() === "pending") {
				    deferred.rejectWith(null, funcArgs);
			    }
		    },
		    deferred = $.Deferred(),
		    timerId = setTimeout(function() {
			    deferred.notifyWith(promise, funcArgs);
			    if (isCancelled) {
				    return;
			    }
			    try {
				    var result = func.apply(this, funcArgs);
				    deferred.resolveWith(result, funcArgs);
			    } catch(e) {
				    deferred.rejectWith(e, funcArgs);
			    }
		    }, delay),
		    promise = $.extend(deferred.promise(), {
			    cancel: cancel
		    });
		return promise;
	};
})(jQuery);

The simplest explanation of jQuery Deferred

I spent a while trying to get to the bottom of the question, “What is the jQuery Deferred all about?”

I couldn’t find the simple answer (They all seem to include ajax examples), so I decided that the internet needed a very short post about the basics.

Deferred is all about callbacks

Let’s say you are the developer of some asynchronous method. You need to provide a way to callback to the consuming code so that it can be aware of success and failure. One way to do this is to make use of a $.Deferred().

As the author of the method, you would create a new $.Deferred(), and use that* as the return value of the function.
When the real meat of your code has completed, you call the deferred’s .resolve method, and if the meat of your code fails, you call the deferred’s .reject method.

When you call .resolve or .reject, all of the appropriate callbacks that the consumer set up get called.

As the basics, that’s it. Make a Deferred. Call resolve or reject, then the done or fail callbacks get called.

Here’s an example.

function playMonopoly(){
    // long-running code.
    throw new Error("A player gave up.");
}

function thisMightTakeAWhile(){
    var deferred = $.Deferred();
    try{
        playMonopoly();
        deferred.resolve();
    }catch(e){
        deferred.reject();
    }
    return deferred; // *
}

thisMightTakeAWhile()
.done(function(){
    console.log("Finished? Wow!");
})
.fail(function(){
    console.log("Someone always gives up.");
});

(You can see it in action on this jsfiddle)

That’s a bad way to use it because nothing there is asynchronous, but that’s the simplicity that I felt the internet was missing.

* Really, you should return deferred.promise()

So what is the difference between a Deferred and a Promise?

The promise is just like returning the Deferred, but with the promise, the consuming code doesn’t have access to the .resolve .reject, and other methods that CHANGE the state. Using the promise, the consuming code only has access to the .done, .fail, etc.

Knockout + jQueryUI draggable/droppable – the end

In earlier posts, I went through the simple and a slightly more than simple implementations of using jQueryUI’s dragon drop with knockout. Now I’m going to round it out with my final post on the topic. This time, I’ll add binding capability to other properties of the draggables and droppables. I’m only going to demonstrate binding the ‘disabled’ option of both the draggable and the droppable, but you can use the same process for binding any of the options.

Example

The contrived example this time is a teacher’s seating chart. Go ahead and check out the example. The “Locked” checkbox is bound to the draggables ‘disabled’ option. The droppables get disabled when the seat already has a student in it.

The Code [Find the latest on GitHub]

(function ($, ko) {

  var _dragged, _hasBeenDropped, _draggedIndex;

  ko.bindingHandlers.drag = {

    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {

      var dragElement = $(element);

      var dragOptions = {

        helper: function () {

          return dragElement.clone().addClass(“ui-dragon”);

        },

        revert: true,

        revertDuration: 0,

        start: function () {

          _hasBeenDropped = false;

          _dragged = ko.utils.unwrapObservable(valueAccessor().value);

          if ($.isFunction(valueAccessor().value)) {

            valueAccessor().value(undefined);

            dragElement.draggable(“option”, “revertDuration”, 500);

          } else if (valueAccessor().array) {

            _draggedIndex = valueAccessor().array.indexOf(_dragged);

            valueAccessor().array.splice(_draggedIndex, 1);

          }

        },

        stop: function (e, ui) {

          if (!_hasBeenDropped) {

            if ($.isFunction(valueAccessor().value)) {

              valueAccessor().value(_dragged);

            } else if (valueAccessor().array) {

              valueAccessor().array.splice(_draggedIndex, 0, _dragged);

            }

          }

        },

        cursor: ‘default’

      };

      dragElement.draggable(dragOptions).disableSelection();

    },

    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {

      var dragElement = $(element);

      var disabled = !!ko.utils.unwrapObservable(valueAccessor().disabled);

      dragElement.draggable(“option”, “disabled”, disabled);

    }

  };

  ko.bindingHandlers.drop = {

    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {

      var dropElement = $(element);

      var dropOptions = {

        tolerance: ‘pointer’,

        drop: function (event, ui) {

          _hasBeenDropped = true;

          valueAccessor().value(_dragged);

          ui.draggable.draggable(“option”, “revertDuration”, 0);

        }

      };

      dropElement.droppable(dropOptions);

    },

    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {

      var dropElement = $(element);

      var disabled = !!ko.utils.unwrapObservable(valueAccessor().disabled);

      //dropElement.droppable(“option”, “disabled”, disabled); didn’t work. jQueryUI bug?

      dropElement.droppable(“option”, “accept”, disabled ? “.nothing” : “*”);

    }

  };

})(jQuery, ko);

The thing that’s different from last time is the implementation of the ‘update’ methods in the binding handlers. The update method gets called when the value of any of the ko.observables change, so I just get the observable from the valueAccessor() and call ko.utils.unwrapObservable() with that sucka, and you have the value to update the options with.

Usage

The usage is very similar to the last example, with the addition of the disabled binding, as in the excerpt from the HTML in the jsfiddle example:

<span data-bind=“drag: {value: student, disabled: $root.isLocked}”>

…shows how I bind the value of the isLocked viewModel property to the ‘disabled’ option of the drag (The checkbox is also bound to the isLocked viewModel property), and…

<td data-bind=“drop: {value: student, disabled: !!student()}”>

…shows how I bind the ‘disabled’ option of the drop to the existence of a student in the seat.

Future

I might update this page sometime in the future to add other options bindings, or to add new functionality. For example, there’s a spot already for a hook to add a ‘revert‘ event to the draggable inside the if (!_hasBeenDropped)  block.

Knockout + jQueryUI Draggable/Droppable Follow-up

[Edit: The final edition in the Knockout + jQueryUI Draggable/Droppable series is in!]

This is the follow-up to my last post which described the simplest implementation possible of drag and drop with knockout.  In that example, the items in the list never moved, they were just cloned when dragged and dropped on the target. The goal accomplished was to drag data from one binding to another while allowing knockout to display the addition of data in the drop target.

Goals for This Iteration

  • I wanted to allow knockout to display the addition of the data in the drop target (as in the last post) and also display the removal of the data from the source when dragging begins.
  • I wanted the data item that is dragged to either be an element from an observable array OR a stand-alone observable – the former forcing the entire array’s UI to be redrawn without the element and the latter allowing just the space where the element was to be redrawn, allowing an empty space where the element was to remain, if you choose.

How it Works

The chain of events in this implementation is: 1) user clicks and begins a drag, then 2) JQueryUI clones the DOM element that will be used during the visual drag, then 3) the bound dragged data item is removed from the source. When the drop event happens on a droppable, 4a) the droppable’s bound data value is set to the dragged data item. If the drop event doesn’t happen, 4b) the dragged data item is added back to where it was removed in #3.

Code

(function ($, ko) {

  var _dragged, _hasBeenDropped, _draggedIndex;

  ko.bindingHandlers.drag = {

    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {

      var dragElement = $(element);

      var dragOptions = {

        helper: ‘clone’,

        revert: true,

        revertDuration: 0,

        start: function () {

          _hasBeenDropped = false;

          _dragged = ko.utils.unwrapObservable(valueAccessor().value);

          if ($.isFunction(valueAccessor().value)) {

            valueAccessor().value(undefined);

            dragElement.draggable(“option”, “revertDuration”, 500);

          } else if (valueAccessor().array) {

            _draggedIndex = valueAccessor().array.indexOf(_dragged);

            valueAccessor().array.splice(_draggedIndex, 1);

          }

        },

        stop: function (e, ui) {

          if (!_hasBeenDropped) {

            if ($.isFunction(valueAccessor().value)) {

              valueAccessor().value(_dragged);

            } else if (valueAccessor().array) {

              valueAccessor().array.splice(_draggedIndex, 0, _dragged);

            }

          }

        },

        cursor: ‘default’

      };

      dragElement.draggable(dragOptions).disableSelection();

    }

  };

  ko.bindingHandlers.drop = {

    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {

      var dropElement = $(element);

      var dropOptions = {

        tolerance: ‘pointer’,

        drop: function (event, ui) {

          _hasBeenDropped = true;

          valueAccessor().value(_dragged);

          ui.draggable.draggable(“option”, “revertDuration”, 0);

        }

      };

      dropElement.droppable(dropOptions);

    }

  };

})(jQuery, ko);

How to use it

In the example, the user will be sorting items, and when I think sorting, I think laundry. Go ahead and try it out

The elements on which you put the data-bind=”drag: {value: whatever}” can be done in a couple of ways:

Using an observable:

In the viewModel:

myArray: [

  { item: ko.observable({ name: “Willis” }) },

  { item: ko.observable({ name: “Arnold” }) },

  { item: ko.observable({ name: “Mr. D” }) }

],

In the html:

<ul data-bind=“foreach: myArray”>

  <li>

    <div data-bind=“drag: {value: item}”>

      <!– ko if:item –>

        <div data-bind=“text: name”></div>

      <!– /ko –>

    </div>

  </li>

</ul>

In this example, myArray doesn’t need to be an observable array unless items will be added to the list. The observables don’t even have to be in a list at all. This is the preferred way and allows for the most flexibility. If you want the space that the element occupied to remain after the element is ripped out (or you want control over that), use this method.  The jsfiddle example using this method will provide more details.

Using an obserableArray:

In the viewModel:

myArray: ko.observableArray([

  { name: “Willis” },

  { name: “Arnold” },

  { name: “Mr. D” }

]),

In the html:

<div data-bind=“foreach: myArray”>

    <div data-bind=“drag: {value: $data, array: $root.myArray}”>

        <div data-bind=“text: name”></div>

    </div>

</div>

If you use it in this way, the element that has the data-bind=”drag: …” needs to be the child of the element with the data-bind=”foreach: …”. If it is not, strange things happen when knockout re-renders the list. I have a laundry sorting jsfiddle example using this method, too, but still prefer using observables over observableArrays. You have to tell it what array the items are in (see the array: $root.myArray in the sample code above.). Sorry.

Conclusion

In my next post, I’ll put a bow on it and add a few more features, like data binding for other draggable and droppable properties. Maybe that’ll be cool.

Knockout + jQueryUI Draggable/Droppable

[Edit: The follow-up to this is in, as well as the final edition in the Knockout + jQueryUI Draggable/Droppable series is in!]

I recently wanted to create a simple game with my son that was very drag-n-drop-centric. I knew I’d use JqueryUI for the drag/drop, so I coded it up, took a step back, and realized that my code was seriously ugly. There was way too much DOM interaction in my code. What it needed was some Knockoutjs!

So this blog post will be the first in a series building up a drag-n-drop knockout custom binding. I’ll start out simple in this post, and build it up to be more feature-rich in later posts. In this post, we’ll learn about:

  • data binding using knockout
  • Jquery draggables and droppables
…as well as some slightly more advanced Knockout features such as…

The contrived task… a pizza builder. Take a list of toppings for a pizza that are in json, and drag the toppings onto the pizza, resulting in toppings data in my pizza json.

Knockout is all about binding data to the UI, so my drag-n-drop implementation will drag and drop DATA, and the UI will just represent that… you’ll see what I mean – especially if you look at the jsfiddle of it.

Here’s the html:

    1 <ul id=“toppings” data-bind=“foreach: toppings”>

    2   <li data-bind=“text: $data, drag: {value: $data}”></li>

    3 </ul>

    4 <br>

    5 <!– ko with: pizza –>

    6 <div id=“pizza” data-bind=“drop: {value: latestTopping}”>

    7   <div data-bind=“visible:(!!latestTopping())”>

    8     <p>

    9       Thanks for adding <span data-bind=“text:latestTopping”></span>!</p>

   10     <span>So far, you’ve added:</span>

   11     <ul data-bind=“foreach: toppingStack”>

   12       <li data-bind=“text: $data”></li>

   13     </ul>

   14   </div>

   15 </div>

   16 <!– /ko –>

Notice the drag: {value: ___} and drop: {value: ___}. That just says that I’m dragging one of the values from the toppings (see the foreach on line 1) and when it’s dropped, it’ll update the the latestTopping property (line 6) on the pizza (line 5). Small note: I could have simply used drag:$data instead of drag: {value:$data}, but I know I’ll have more options to add later.

The viewModel that I’m calling ko.applyBindings on looks like this:

var pizzaria = {

  toppings: [“Pepperoni”, “Olives”, “Sausage”, “Bacon”, “Canadian Bacon”, “Chilean Bacon”],

  pizza: new Pizza()

};

…and the Pizza function just defines a latestTopping property that is a knockout observable.

I wanted to know all the toppings ever added to the pizza, so the latestTopping property makes use of ko.computed so that the write adds the value to an array and the read just reads the most recently added topping. So here’s the Pizza:

    1 function Pizza() {

    2   this.toppingStack = ko.observableArray();

    3   this.latestTopping = ko.computed({

    4     read: function () {

    5       return this.toppingStack().length ? this.toppingStack()[0] : “”;

    6     },

    7     write: function (value) {

    8       if (value) {

    9         this.toppingStack.unshift(value);

   10       } else {

   11         this.toppingStack.shift();

   12       }

   13     },

   14     owner: this

   15   });

   16 }

   17

Then of course, there’s this important magical line of javascript:

ko.applyBindings(pizzaria);

So here it is… my simplest-thing-that-could-work dragon drop knockout custom binding with jqueryui draggable and droppable:

    1 (function () {

    2   var _dragged, _noOp = function () { };

    3   ko.bindingHandlers.drag = {

    4     init: function (element, valueAccessor, allBindingsAccessor, viewModel) {

    5       var dragElement = $(element);

    6       var dragOptions = {

    7         helper: ‘clone’,

    8         revert: true,

    9         revertDuration: 0,

   10         start: function () {

   11           _dragged = ko.utils.unwrapObservable(valueAccessor().value);

   12         },

   13         cursor: ‘default’

   14       };

   15       dragElement.draggable(dragOptions).disableSelection();

   16     }

   17   };

   18

   19   ko.bindingHandlers.drop = {

   20     init: function (element, valueAccessor, allBindingsAccessor, viewModel) {

   21       var dropElement = $(element);

   22       var dropOptions = {

   23         drop: function (event, ui) {

   24           valueAccessor().value(_dragged);

   25         }

   26       };

   27       dropElement.droppable(dropOptions);

   28     }

   29   };

   30 })();

First thing to note is that it is inside a self-executing function (note the “()” on the last line). The reason that is done is so that the variables declared at the top are hidden from the global scope.

A couple of notes about the variable “_dragged”:

  1. I named it with an underscore just so it would stand out to me as a closure from a scope outside where it is written and read. No big deal.
  2. I didn’t have to use a variable for that. I could have stuck it in the data of the html element being dragged (that is: $(element).data(“key”, “value”)), but I made the assumption that only one thing could be dragged at a time and I figured with a single variable to hold it, I wouldn’t leave data lying around tied to DOM elements or have to worry about cleaning them up.

For a custom bindingHandler, you have to implement one or both of the methods init and update. For now, I only need the init. Inside the drag’s init method and the drop’s init method, everything looks pretty typical for the jqueryui draggable and droppable, except for just a few things.

Notable items from the drag’s init function:

  • I used the option “helper: ‘clone'” and “revert: true” because I wanted to only effectively drag around DATA, and not actually move DOM elements around. I let the bindings do their magic and leave the DOM elements where they originate. Don’t worry, in a later post, I’ll discuss how to make it appear that the elements are actually moving, but in this example, the pizza toppings stay in the toppings list forever. They do appear to be ‘added’ to the pizza, but that is just plain-old data binding at work.  Besides, you probably want to be able to add bacon to the pizza multiple times.
  • Line 11 is where the _dragged variable is set from the observable you declared to be draggable in the data-bind=”drag:{value: ___}”

Notable items from the drop’s init function:

  • line 24 is where the observable you declared to be droppable in the data-bind=”drop: {value: ___}” gets set from the _dragged variable.

That’s pretty much it for the simple example.

Please check out the jsfiddle for this example to see it in action. More to come on this later.