Deleting Items

Now let's move on to deleting items from the board.  Using jQuery event delegation, and ExoWeb change tracking, the code required to do this is extremely simple.

$(document.documentElement).on("click"".board-list-deleteitem"function (e) {
         var item = $parentContextData(thisnullnull, ListItem);
         item.get_List().get_Items().remove(item);
         e.stopPropagation();
});

Now when you click the delete button, the item is removed and your changes are saved automatically.

It may not be apparent in the UI, but our sequences are out of sync.  Technically we could get by with gaps in the sequence, but we really want the sequence to accurately reflect the item's index in the list.  Instead of writing more procedural code to update the sequences, which is merely a side-effect of the delete, we can write a rule that requences items in the list due to changes, regardless of what UI behavior might be driving it.  (More on writing rules server-side later.)

To accomplish this we'll sort the items by their sequence, and then simply update each item in the list to have a sequence equal to it's index in the list.  We could use the native JavaScript sort function for this, but it manipulates the array as opposed to creating a copy, which could have unintended side-effects.  Plus, to sort by sequence you have to write the logic to compare two items' sequences and determine which comes first.  ExoWeb comes with a handy little class that can do that for us.  We used it indirectly in our template when we specified a "transform" option.

new ExoWeb.Model.Rule(List.meta, {
         onChangeOf: "Items",
         execute: function(list) {
                 $transform(list.get_Items()).orderBy('Sequence').forEach(function(item, index) {
                          item.set_Sequence(index);
                 });
         }
});

Our rule will run automatically when the "Items" property of the List type changes.  The $transform function wraps the given array and adds on a few handy functions: filter, orderBy, groupBy, select, and live.  The orderBy function accepts a comparison function, just like the native sort function, or a property name or list of property names to sort based on (similar to a SQL order by clause).


  1. Create the javascript file board-list-deleteitem.js under scripts
  2. Insert the following snippet into scripts/board-list-deleteitem.js:
    $(document.documentElement).on("click", ".board-list-deleteitem", function (e) {
    	var item = $parentContextData(this, null, null, ListItem);
    	item.get_List().get_Items().remove(item);
    	e.stopPropagation();
    });
    				
  3. Append the following code snippet in Views\Home\Index.cshtml under the list of script references:
    <script src="@Url.Content("~/scripts/board-list-deleteitem.js")"></script>
    				
  4. Insert the following snippet into Views\Home\Index.cshtml, above the Exo-model declaration section:
    @*
    Re-sequencing
    *@
    
    <script type="text/javascript">
    
    	$extend("List", function() {
    		new ExoWeb.Model.Rule(List.meta, {
    			onChangeOf: "Items",
    			execute: function(list) {
    				$transform(list.get_Items()).orderBy('Sequence').forEach(function(item, index) {
    					item.set_Sequence(index);
    				});
    			}
    		});
    	});
    
    </script>