I have a fairly simple table created using a Backbone Marionette CompositeView. The only requirements on this table are that it display data and allow the user to sort it by clicking the header row. When the table is sorted, the columns used to sort the header column are tagged with classes to allow an arrow to be displayed using CSS (e.g. 'class="sort asc"').
Here is the problem: When the header row is clicked, the element that is passed to the callback (via event.target) is not part of the table that is on the DOM. Instead, using Chrome's debugging tools it appears that the target element is actually part of the template script block, and not the element the user actually sees.
The best work-around I've got right now is to lookup the element actually attached to the DOM by retrieving unique info from its clone in the template.
Here's the composite view code (borrowed from one of Derick Bailey's sample Fiddle's):
// The grid view
var GridView = Backbone.Marionette.CompositeView.extend({
tagName: "table",
template: "#grid-template",
itemView: GridRow,
events: {
'click th': 'doSort'
},
doSort: function(event) {
var target = $(event.target);
this.collection.sortByField(target.data('sortby'));
target.parent('tr').find('.sort').removeAttr('class');
target.addClass('sort ' + this.collection.sortdir);
debugger; // NOTE: no change to elements in the DOM. WTH?
target = this.$('[data-sortby=' + target.data('sortby') + ']');
target.parent('tr').find('.sort').removeAttr('class');
target.addClass('sort ' + this.collection.sortdir);
debugger; // NOTE: DOM updated.
},
appendHtml: function(collectionView, itemView) {
collectionView.$("tbody").append(itemView.el);
}
});
The template is simple as well:
<script id="grid-template" type="text/template">
<thead>
<tr>
<th data-sortby="username">Username</th>
<th data-sortby="fullname">Full Name</th>
</tr>
</thead>
<tbody></tbody>
</script>
A fork of Derek's original demo Fiddle modified to demonstrate the problem can be found here: http://jsfiddle.net/ccamarat/9stvM/14/
I've meandered a bit. My question is, I appear to have a spawned a Zombie View of sorts; is this a jQuery/Backbone/Underscore bug, or am I simply going about this all wrong?
** EDIT ** Here's the console output showing the different parent hierarchies of the two elements:
console.log(target, targetb):
[<th data-sortby="username" class="sort asc">Username</th>] [<th data-sortby="username">Username</th>]
console.log(target.parents(), targetb.parents()):
[<tr>…</tr>, <thead>…</thead>] [<tr>…</tr>, <thead>…</thead>, <table>…</table>, <div id="grid">…</div>, <body>…</body>, <html>…</html>]
console.log(target === targetb):
false