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

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events