tags:

views:

56

answers:

4

Hi,

I'm generating a page using jsp, it has a list element which shows a few report names. When generating the list, I'd like to hide the id of each report in the list item element so that when the user clicks that item, I can use ajax to fetch it from the server, since I know the id. What's a good way to do this such that it's easy for jquery to pick up the id on a click? Right now I have something like:

// jsp pseudocode
<ul id='reports'>
    <%
    for (all reports) {
        %><li><%= report.getTitle() %>
            <div class='hidden'><%= report.getId() %></div> // the hidden id for this item
          </li>
        <%
    }
</ul>

// click handler for the list.
$('#reports').delegate('li', 'click', function() {
    var idOfTheClickedReport = ?;
    fetchReportById(idOfTheClickedReport);
    ...
});

Is there a better way to do this?

Thank you

+2  A: 

What you're doing is entirely reasonable.

An alternative approach would be to use jQuery's data() call to store arbitrary data on an element.

cletus
How would he get the information from the server to the client to begin with so he could use the `data` attribute?
Doug Neiner
@Doug Neiner The way to get the data to match up with the LIs would be to output it into a JS array in the same order as the LIs are output, then iterate over the LIs and the array, assigning the value to each one's data storage.
Alex JL
+2  A: 

You can store the id as an arbitary html property like

<li reportid='<%= report.getId() %>'><%= report.getTitle() %></li>

Will work, you can then get the id like var idOfTheClickedReport = $(this).attr('reportid');

it's not standard compliant HTML, but it should work fine in any browser.

Alex JL
Custom attributes / expandos are widely used for this use case.
unomi
Such markup will fail validation. While it will *probably* work across browsers, it isn't guaranteed. Also you need to be concerned with things like escaping certain characters (like single quotes and angle brackets in this case).
cletus
If you are going to add random attributes, at least use the new html5 `data-` prefix and then the html5 doctype of course.
Doug Neiner
There's no question it will fail validation, not that failing validation has any actual effect of course. It does work reliably across browsers, as they tend to ignore attributes about which they are not concerned. Google does this all the time, for instance. jQuery adds attributes in a similar way (check out your HTML in IE's Dev Toolbar when using jQuery). Good point, we may as well be using `data-`, with HTML5 in mind.
Alex JL
+2  A: 

The HTML5 way to do it would be to store the data in an element attribute whose name starts with data-, like this:

<li data-reportid='<%= report.getId() %>'><%= report.getTitle() %></li>
Matt Ball
+1 Nice use of the `data-` attributes!
Doug Neiner
This looks cool too, but are all browsers supporting html 5? What if the user is using ie7 etc, will I be able to use jquery to get that data out?
Yes, browsers just see this as an extra attribute, and the html5 doctype is supported in all modern browsers including ie6.
Doug Neiner
+1  A: 

I would not suggest using a hidden div that way. It is a lot of extra markup for an id, and you are not currently using the id or rel attribute (Both potential candidates for holding this information):

Since there is already the concept of an ID in HTML, I think it makes the most sense to leverage that:

<ul id='reports'>
   <% for (all reports) { %>
      <li id="report-<%= report.getId() %>"><%= report.getTitle() %></li>
   <% } %>
</ul>

This would output:

<ul id='reports'>
      <li id="report-1">Title Here</li>
      <li id="report-19">Title Here</li>
      <li id="report-27">Title Here</li> 
</ul>

Then in your jQuery part (Assumes id will not contain a -):

$('#reports').delegate('li', 'click', function() {
    var idOfTheClickedReport = this.id.split('-').pop();
    fetchReportById(idOfTheClickedReport);
    ...
});
Doug Neiner
Be careful when overloading id. There should only be one instance of any id within a page. id collisions are a violation of the spec and can cause unexpected behavior with things like getElementById.
dgrijalva
@dgrijalva Thats why I used a prefix, as long as the OP uses a different prefix on any further iteration on the same page, this solution will work really well. Also, its a natural assumption that an ID is unique on the server as well, so the risk is very low.
Doug Neiner
Yeah, this seems to work for me, I'll investigate the data- solution too, just am not sure how older browsers deal with it, thank you.