📜 ⬆️ ⬇️

We work with jQuery Templates. Part Three, jQuery Templates Plus

Two weeks ago, I talked about the basic features of the jQuery Templates plugin and promised not to stop there. Promises must be fulfilled, so today I will talk about additional functions that are not included in the main code of the plugin.

Additional features of the plugin include:
  1. A set of commands that significantly simplify changing rendered templates when changing their associated data;
  2. The rendered event, which is triggered after the rendered template is added to the document structure.

The code for additional functions is in the jquery.tmplPlus.js file, so in order to use them you must add a link to this file:

<script src="Scripts/jquery-1.5.js" type="text/javascript"></script> <script src="Scripts/jquery.tmpl.js" type="text/javascript"></script> <script src="Scripts/jquery.tmplPlus.js" type="text/javascript"></script> 

')

Commands for modifying rendered templates


Command call


To call all commands, use the jQuery.tmplCmd () method.

This method has three forms of calling:
  1. jQuery.tmplCmd (command, tmplItem)
  2. jQuery.tmplCmd (command, tmplItems)
  3. jQuery.tmplCmd (command, data, tmplItems)

The command parameter is used to specify the command name ( update , remove , replace, or find ).

The tmlItem parameter is used to send a link to the template instance that the command will work with. Accordingly, the tmplItems parameter is used to transfer an array of references to template instances.

The data parameter can be a reference to a data element or an array of such references and is used to filter the tmplItems array. If this parameter is specified, not all template instances will be involved in the operation, but only those that are associated with the data elements specified in the data parameter:



Which of these three forms of call are applicable for each command, I will indicate in the description of these commands.

Replace command


The replace command is perhaps the most interesting of all, it changes the order of the rendered templates in the document structure in accordance with the order given by its arguments, and without re-rendering the templates.

This command allows three forms of challenge, but only one of them has practical application:
  1. jQuery.tmplCmd ('replace', data, tmplItems)

After the call to replace, the rendered templates will be rearranged in the order in which data element references follow in the data array. The perfect sorting solution!

Let's now see how this works. The data I will work with in this and other examples from this section are in the dataItems array (the full code of the example is in the Samples.htm file):

 var dataItems = [ { firstName: '', lastName: '' }, { firstName: ' ', lastName: '' }, ... ]; 

To display this data, I use the following template:

 <script id="item_tmpl" type="text/x-jquery-tmpl"> <tr class="item"> <td>${firstName}</td> <td>${lastName}</td> <td> <img src="Images/item-edit.png" class="item-edit" title="Edit" /> <img src="Images/item-delete.png" class="item-delete" title="Delete" > </td> </tr> </script> 

After rendering, I save references to all instances of the template in the tmplItems array:

 $('#item_tmpl').tmpl(dataItems, options).appendTo('#items_bag'); tmplItems = $('#items_bag .item').map(function () { return $.tmplItem(this); }).get(); 

I attach event handlers to pictures marked with the sort-asc and sort-desc classes in the table header. The optional attribute x-field-name contains the name of the field that will be sorted:

 <table id="items_bag"> <tr> <th>First Name <img src="Images/sort-asc.png" class="sort-asc" x-field-name="firstName" alt="" /> <img src="Images/sort-desc.png" class="sort-desc" x-field-name="firstName" alt="" /> </th> <th>Last Name <img src="Images/sort-asc.png" class="sort-asc" x-field-name="lastName" alt="" /> <img src="Images/sort-desc.png" class="sort-desc" x-field-name="lastName" alt="" /> </th> <th></th> </tr> </table> 

The code for sorting ascending is shown below:

 $('#items_bag').delegate('.sort-asc', 'click', function () { var fieldName = $(this).attr('x-field-name'); dataItems.sort(function (a, b) { return compareStrings(a[fieldName], b[fieldName]); }); tmplItems = $.tmplCmd('replace', dataItems, tmplItems); }); 

Here I first get the name of the field by which sorting is performed:

 var fieldName = $(this).attr('x-field-name'); 

Then I sort the array with the data elements:

 dataItems.sort(function (a, b) { return compareStrings(a[fieldName], b[fieldName]); }); 

Finally, I invoke the replace command to display the changed data in the document:

 tmplItems = $.tmplCmd('replace', dataItems, tmplItems); 

The replace command returns an array of references to template instances located in the same order as the rendered templates in the document, so I save the result of the execution of replace in tmplItems .

The code for sorting in descending order is similar:

 $('#items_bag').delegate('.sort-desc', 'click', function () { var fieldName = $(this).attr('x-field-name'); dataItems.sort(function (a, b) { return compareStrings(a[fieldName], b[fieldName]); }).reverse(); tmplItems = $.tmplCmd('replace', dataItems, tmplItems); }); 

How it works is shown in the video below:



Update command


The update command initiates a re-rendering of templates. In fact, this is equivalent to the update () method of the template instance with additional options. Its most logical use is to update the document after changing the data.

This command allows three forms of invocation, and, unlike the replace command, all of these forms have practical applications:
  1. jQuery.tmplCmd ('update', tmplItem)
  2. jQuery.tmplCmd ('update', tmplItems)
  3. jQuery.tmplCmd ('update', data, tmplItems)

Let's see how it works on the example of a table editor (the full code of the example is in the Samples.htm file). The code for editing the item is shown below:

 $('#items_bag').delegate('.item-edit', 'click', function () { var tmplItem = $.tmplItem(this); var dataItem = tmplItem.data; editDialog.show(dataItem, function () { $.tmplCmd('update', tmplItem); }); }); 

Here, I first get a link to the template instance and a link to the data item:

 var tmplItem = $.tmplItem(this); var dataItem = tmplItem.data; 

Then I call a dialog box to which I give the link to the data item and the callback function, which will be called if the user clicks OK, and the data has been changed:

 editDialog.show(dataItem, function () { $.tmplCmd('update', tmplItem); }); 

And in the callback function, I call the update command, giving it a link to the template instance, which causes it to be rendered again:

 $.tmplCmd('update', tmplItem); 

How it works is shown in the video below:



Remove command


The remove command, as it is easy to guess, removes the rendered templates from the document structure. Like the update command, it has three forms of calling:
  1. jQuery.tmplCmd ('remove', tmplItem)
  2. jQuery.tmplCmd ('remove', tmplItems)
  3. jQuery.tmplCmd ('remove', data, tmplItems)

A feature of this command is that it not only removes the rendered templates from the document structure, but also removes references to the corresponding template instances from the tmplItems array!

This, in my opinion, is a rather unusual approach - on the one hand, it somewhat reduces the effort required to maintain the tmplItems array in a consistent state, and on the other, it can create an unpleasant situation. Perhaps I would prefer this team to have no side effects.

The code for deleting a table element is shown below:

 $('#items_bag').delegate('.item-delete', 'click', function () { var tmplItem = $.tmplItem(this); var dataItem = tmplItem.data; if (confirm('Do you really want to delete "' + dataItem.firstName + ' ' + dataItem.lastName + '"?')) { dataItems.splice(jQuery.inArray(dataItem, dataItems), 1); $.tmplCmd('remove', dataItem, tmplItems); updateDebugInfo(); } }); 

Here, I first get a link to the template instance and a link to the data item:

 var tmplItem = $.tmplItem(this); var dataItem = tmplItem.data; 

And after receiving confirmation from the user, first delete the corresponding element from the dataItems array:

 dataItems.splice(jQuery.inArray(dataItem, dataItems), 1); 

And then I delete the corresponding rendered template from the document structure and at the same time delete the link to the template instance from the tmplItems array:

 $.tmplCmd('remove', dataItem, tmplItems); 

The function code updateDebugInfo () is shown below:

 function updateDebugInfo() { $('#data_items_length').text(dataItems.length); $('#tmpl_items_length').text(tmplItems.length); } 

This function is intended to demonstrate the side effect of the remove command.

How it works is shown in the video below:



Find command


The find command is used to search for instances of the template associated with specific data. Together with the update and remove commands, it can be used for a “point” update of a document when re-rendering all templates takes too much time.

This command allows only one form of call:
  1. jQuery.tmplCmd ('find', data, tmplItems)

The result of this command is an array of references to the template instances associated with the data passed through the data argument.

An example of using the find command is given below (the full code of the example is in the Samples.htm file):

 $('#item_rnd').click(function () { var dataItem = dataItems[Math.round(Math.random() * (dataItems.length - 1))]; var tmplItem = $.tmplCmd('find', dataItem, tmplItems)[0]; $(tmplItem.nodes).css('background-color', '#ff0000'); $(tmplItem.nodes).animate({ 'background-color': '#ffffff' }, 1500); }); 

In this example, I randomly select a data item:

 var dataItem = dataItems[Math.round(Math.random() * (dataItems.length - 1))]; 

Then, using the find command, I find an instance of the template with which this data item is associated:

 var tmplItem = $.tmplCmd('find', dataItem, tmplItems)[0]; 

And finally, I highlight the corresponding row in the table:

 $(tmplItem.nodes).css('background-color', '#ff0000'); $(tmplItem.nodes).animate({ 'background-color': '#ffffff' }, 1500); 

In a real application, updated data can be obtained, for example, using an AJAX request.

How it works is shown in the video below:



Event rendered


The rendered event is defined for the template instance and is called after the rendered template is placed in the document structure.

To set an event handler, use the options parameter of calling .tmpl () :

 var options = { rendered: function (tmplItem) { if (window.console) { console.log("rendered: %s %s", tmplItem.data.firstName, tmplItem.data.lastName); } } }; $('#item_tmpl').tmpl(dataItems, options).appendTo('#items_bag'); 

The most obvious scenario where this event may be required is debugging. In the example above, each time the template is rendered, a message is displayed in the debugging console, making it easy to verify that the replace command does not actually render again, and the update command from the above example updates only one row of the table.

How it works is shown in the video below:



Conclusion


The full code of the examples used in the article can be downloaded from this link .

I also remind you that you can download jQuery Templates from the ASP.NET CDN website or directly from the GitHub repository:

Documentation for jQuery Templates is available on the jQuery documentation site .

Source: https://habr.com/ru/post/113672/


All Articles