Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ajax requests with unobtrusive javascript over lists of elements

So I really prefer using unobtrusive javascript to inline javascript. I find it much easier to work with.

The problem that I keep running into, is that I don't know how to get data for each specific element that I want to work with.

For example:

I have a list, and I generate the following HTML (this is pseudo-code here)

<%for e in list%>
    <a href="#" class="delete"><%=e%></a> <!-- <%= e.id %> ??-->
<%end%>

So I want to attach javascript to each of these <a> tags that will invoke an ajax post, but I need the "id" to delete the correct element from the back end.

$('a.delete').click(function() {
    // Ajax request using "e.id"
});

Some things that I have tried:

  1. Building the href and using the attr method to send the ajax request to that url. (I don't really like this for POST requests, but it does work.
  2. Using a rel attribute to store the data I need.
  3. Using HTML5 data attributes. (I don't know about the availability of this in all browsers, and since we need to support IE6+ I don't really like the idea using this.)
  4. Creating a form for each <a> tag and serializing that. (This seems like a lot of extra code, but it also seems really clean.)

What are the best practices for achieving this?

like image 303
partkyle Avatar asked May 09 '11 17:05

partkyle


3 Answers

Use the id attribute to store a string w/ the id like so:

<%for e in list%>     
    <a id="link_<%= e.id %>" href="#" class="delete"><%=e%></a> 
<%end%> 

And the read the id by splitting on something like an underscore:

$('#list a').click(function(){
    //old var id = $(this).attr('id').split('_')[1];
    var id = this.id.split('_')[1]; //thx @mu

    $.ajax({
        url: 'http://www.someurl.com/delete.aspx?id=' + id,
        //...more
    })
});
like image 172
pixelbobby Avatar answered Oct 14 '22 10:10

pixelbobby


I often store this kind of data in the tag like so:

Attribute tag method

   <div id="list">
      <a href="/link" post_id="68">Some post</a>
   </div>

Then in jQuery do something like:

 $('#list').delegate('a.delete', 'click', function(event) {
     event.preventDefault(); // Stop default click event
    
     // ajax stuff here
     // $(this).attr('post_id') = 68
 });

Update: The .attr('post_id') doesn't work in IE6.


Alternative methods? Hmm....

All of these use the above delegate function.

In a dedicated element, using class, or id, to define the elements data:

   <div id="list">
    <a href="/link"><span class="hide post_id">66</span>Some post</a>
   </div>
  • Access by: $('span.post_id', this).text()

Probably one of the worser ideas for just simple ids, but if you need to store complex data then adding it inside an element could be an option.


In the href...

   <div id="list">
      <a href="/link/66">Some post</a>
   </div>
  • Access by: $(this).attr('href').match(/\/([0-9]+)$/)[1]

This method is obviously dependant on your url. This is one of the most unobtrusive methods, assuming your url structure isn't too complex or change often.


It's a ID. It's unique. Let's ID:

   <div id="list">
      <a href="/link" id="post_66">Some post</a>
   </div>
  • Access by: $(this).attr('id').split('_')[1]

Benefit to this method is you can also style elements based on specific IDs -- sometimes useful. It also makes the most sense. Your ID is unique. That anchor link relates to that post, that unique ID, so using the id attribute makes sense.

like image 38
Gary Green Avatar answered Oct 14 '22 10:10

Gary Green


You can attach an ID to each <a> element like this <a href=".." id="delete_<%e.id%>" > then when you attach event to this link you can find ID via string indexOf and use related ajax function.

like image 40
caltuntas Avatar answered Oct 14 '22 09:10

caltuntas