views:

24

answers:

4

I'm using the jQuery template plug-in (official jquery-tmpl plugin) to build up a an HTML list. The template basically defines <li> elements and looks something like this:

<script id="item-display-template"> type="text/html">
  <li>
    <div class="item-display-container">
        <p>${SomeData1} .... ${SomeData2} etc....</p>
        <a onclick="editRow();">Edit This Item</a>
    </div>
  </li>
</script>

Each item in the resulting list will have an 'Edit This Item' link that will invoke an 'editRow' function. I need to be able to provide this function with the primary key (id) of the database record for the item being edited. The 'id' is included in the JSON being bound to the template. My first thought was to do this with the 'Edit This Item' link:

<a onclick="editRow(${Id});">Edit This Item</a>

I think that will work, but I'm not sure that this is the "right way".

Is it possible to invoke the 'jQuery.data()' method within the template to attach the Id value to one of the DOM elements as the template is being rendered?

+1  A: 
Pointy
+2  A: 

Change your template to be something like:

<script id="item-display-template" type="text/html">
  <li>
    <div class="item-display-container" data-itemid="${Id}">
        <p>${SomeData1} .... ${SomeData2} etc....</p>
        <a class="editrow">Edit This Item</a>
    </div>
  </li>
</script>

By placing the id on the div.item-display-container you make it very easy to add other functionality that can easily access that same id, say like a delete link.

Then on the <ul> element you are inserting these <li> element in to do this:

$('ul').delegate('.editrow','click',function(e) {
    e.preventDefault();
    var id = parseInt($(this).parents('.item-display-container').attr('data-itemid'), 10);
    editRow(id);
});
PetersenDidIt
+2  A: 

I would use a data attribute, like this:

<script id="item-display-template"> type="text/html">
  <li>
    <div class="item-display-container">
        <p>${SomeData1} .... ${SomeData2} etc....</p>
        <a class="edit" href="#" data-id="${Id}">Edit This Item</a>
    </div>
  </li>
</script>

Then a .live() or .delegate() handler, like this:

$("a.edit").live("click", function() {
  var id = $(this).attr("data-id");
  //use the id
});

Or .delegate():

$("#myUL").delegate("a.edit", "click", function() {
  var id = $(this).attr("data-id");
  //use the id
});

As a side note: In jQuery 1.4.3+ coming out later this week, you can use .data() like this:

var id = $(this).data("id");
//or:
var id = $.data(this, "id");

It'll fall back to the data-id attribute to get a value if there isn't one in it's data collection.

Nick Craver
+1  A: 
<script id="item-display-template"> type="text/html">
  <li>
    <div class="item-display-container">
        <p>${SomeData1} .... ${SomeData2} etc....</p>
        <a id="id_${Id}" class="link-for-edit">Edit This Item</a>
    </div>
  </li>
</script>

var eventEdit = function(ev) {
    //...
    var id = $(this).attr('id').split('_');
};

var items = $('#item-display-template').tmpl(data);

$(items).find('a.link-for-edit').bind('click', eventEdit);
$(items).appendTo('ul');
andres descalzo