Practical ASP.NET

Implementing Deletes with Template Event Handlers

Peter Vogel implements deletes for rows in a template by adding event handlers to the template. He also looks at a feature of the tmpl plugin that he wasn't able to shoehorn into his sample project. (Part 3 of 4)

Over the last three columns, I built a page with basic updating, deleting, and display functionality using the new templating and data linking functionality in jQuery. You can click the links below to go to these earlier articles:

Setting Up for jQuery Templates
Displaying and Filtering Data with jQuery Templates
Supporting Updates with jQuery Data Linking

In this column I'm going to implement deleting objects (I won't implement adding new rows because I couldn't see a reasonable way of doing it that would show off the new jQuery extensions). The delete method is relatively easy to implement. First, I extend the template with a button for the user to click to delete that row:

<script id="OrdersGridTemplate" type="text/x-jquery-tmpl">
<tr>
  <td><input type="button" id="DeleteOrderButton" 
      value="Delete" /></td>
  <td><span id="OrderId">${OrderId}</span></td>
  ... rest of template... 

The next step is to attach a function to the buttons rendered in the template by using the live plugin. I add the following jQuery code after the code that renders my template. It attaches a function called DeleteOrder to the button(s) that have an id attribute set to DeleteOrderButton:

$("#DeleteOrderButton").live("click", DeleteOrder);

In the DeleteOrder function, I use the tmplItem extension, passing the keyword to retrieve the instance of the template that the button that triggered the event was in. Or, to put it another way, this retrieves the row that the Delete button is in:

function DeleteOrder() {
    var itm = $.tmplItem( this );

Once I've retrieved the instance of the template, I can use the data property on the instance to pull properties from the object displayed in the template. The following code gets the OrderId displayed in the template and passes it to the the DeleteOrder method on my Web Service (set up in ScriptManager). The other two parameters passed to the DeleteOrder method are the functions to call when the Web service returns its result and the function to call if there's an error in the Web Service:

    nwData.DeleteOrder(itm.data.OrderId, OrderDeleted, FailOrders);
}

The Web service that handles deletes is relatively simple: It retrieves the object corresponding to the OrderId passed to it, deletes it, and pushes the updates back to the database. The order id is returned to the client so that the client can remove the now deleted order from its display:

<OperationContract()> _
    Public Function DeleteOrder(ByVal ordIdIn As String) As Integer
        Dim OrdId As Integer = CInt(ordIdIn)

        Dim nw As New northwndEntities
        Dim ord = (From o As Orders In nw.Orders _
                        Where (o.OrderID = OrdId) _
                        Select o).FirstOrDefault()
        If ord IsNot Nothing Then
            nw.DeleteObject(ord)
            nw.SaveChanges()
        End If

        Return OrdId
    End Function

On the client, in the OrderDeleted method that's called when the service returns a result, I use the Order Id that's returned to remove the corresponding item from the array of Order objects. After that, I call my function that generates the template to redisplay the (shorter) list and reattaches my DeleteOrder function to the DeleteOrderButton:

function OrderDeleted(orderid) {
    for (pos in ords) {
        if (ords[pos].OrderId == orderid) {
            ords.splice(pos, 1);
            break;
        }
    }
    GotOrders();
}

Before wrapping up, there's one piece of functionality related to the tmpl plugin that I didn't need in this project. I've already used the tmpl plugin that allows you to generate a template once for every object in a collection and incorporate data from the object into the template. The tmpl plugin also allows you to pass additional data to instances of the template that's unrelated to the objects driving the template.

To generate the HTML for the template, I used code like this that retrieved a compiled version of the template from OrderGridTemplateHold and passed it the collection of object in ords:

var gridHtml = $.tmpl(OrdersGridTemplateHold, ords).get();

I can pass additional data as the third parameter to the tmpl plugin. This example passes an anonymous object with two members (a property and a function):

$.tmpl(OrdersGridTemplateHold, ords,
    { 
        DeveloperFirstName: "Peter",
        DeveloperLastName:  function() { 
            return "Vogel";
        } 
    }).get(); 

Within the template, I can reference that additional data through the $item variable:

<script id="OrdersGridTemplate" type="text/x-jquery-tmpl">
  <tr>
    <td> ${$item.DeveloperFirstName}</td>
    <td> ${$item.DeveloperLastName()}</td>
  </tr>
</script>

That's as much time as I want to spend on working with the jQuery extensions in this column... except for drawing some conclusions. But that will have to wait for my next column, the final one in this series.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

Subscribe on YouTube