tags:

views:

49

answers:

3

I have a DOM element similar to Facebook's "View friends" popup. I have a table with a list of rows, on which I can add tags to those rows:

<tr id="124"></tr>

When the row is clicked there's a modal popup that is created and lets the user choose tags they want associated with that row, sort of like this:

<div class="popup">
  <div class="popup-body-row" id="3434">Add tag 3434</div>
  <div class="popup-body-row" id="2112">Add tag 2112</div>
  //etc.
</div>

I have the following javascript:

    $('.popup-body-row').live('click', function(event) {
         var popupRowId = event.currentTarget.id
         // post for sending this to the server omitted
    });

That gets the popupRowId, but doesn't get the originating element to associate with the popupRowId. I could build the popup so that the tr id is associated with it:

<div class="popup" id="124">
// everything else is same as before
</div>

And then add this line to my javascript:

var trRowId = e.currentTarget.parentNode.id;

That works, but if I start adding elements to my popup div so that the parent node isn't the parent node any longer, it breaks and I'll have to rewrite it.

Any advice would be appreciated, but the way I'm doing it has a certain "code smell." Thanks!

Edit: Short version, I have a row element, each associated with a unique object. I put the object's id as the attribute. When I click that row element a (potentially) complex DOM element is created giving the user a choice of tags to associated with the row element. If I use "parentNode" to find which row was clicked it breaks if my designer comes by and adds elements to the popup. What's the best solution for this? Associating the tr row id with the class "popup" and then searching the entire DOM for the class when a tag is added? Or putting the tr id on all div elements in the popup so even if my designer adds a new parent, the id will propagate to it?

A: 

I'm not sure what the exact trouble you're have but at least you can use jQuery functionality to get the ids:

$('.popup-body-row').live('click', function(event) {
     var popupRowId = $(this).attr('id');
     var trRowId = $(this).parent().attr('id');
});
fantactuka
+2  A: 

I think there's nothing wrong with adding the id of the clicked row to the popup. But you cannot store it as in an id attribute as they are supposed to be unique. Instead use HTML5's data attributes which works perfectly with older browsers too.

If you are worried about the restructuring of the popup div, then don't rely explicitly on the parentNode relationship, but instead rely on the popup class for example (which must be unique within the popup for disambiguation), or a specific attribute, both of which must only exist on the root popup node.

Here's the flow of events I'm proposing:

  1. User clicks table row with id="124"
  2. Show popup and record the id there - <div class="popup" data-current-row="124">..
  3. When a row inside the popup is clicked, then find the closest parent having the attribute data-current-row and fetch its value.

Setup the popup live click handler as:

$('.popup-body-row').live('click', function() {
    // by searching for closest popup, you break the 
    // explicit parentNode relationship. By storing the data
    // inside an HTML5 data attribute, you are not duplicating id's.
    // Basically, a win-win situation for all.
    var popup = $(this).closest('[data-current-row]');
    var associatedRowId = popup.attr('data-current-row');
});
Anurag
Thanks, I was looking at adding a custom attribute but when I was looking at popular javascript heavy sites, I noticed it was rarely done. Is there any reason for not adding custom attributes? This seems like the best way to go about it.
chum of chance
People sort of looked down upon it until the HTML5 spec legitimized it. Now we are all comfortable with it, lol :)
Anurag
Probably because of the strictness of XHTML, even though most pages aren't rendered strict people have that mentality. Now HTML5 just wants everyone to have fun.
jasongetsdown
yeah, people kept away from writing their own XHTML namespaces for custom attributes for some reason, the reason being why w3 incorporated data-* into the global namespace and in HTML.
Anurag
A: 

You could try something like this:

$(document).delegate('.popup-body-row', 'click', function(e) {
    var
        me = $(this),
        id = me.attr('id'),
        rowId = me.closest('tr').attr('id');

    // Do something with them
});
peol