views:

495

answers:

3

Scenario:

I have a partial view that is used in several places across my ASP.NET MVC application. The partial view contains a list of "objects" to select, i.e. something similar to:

<ul>
    <%
        foreach (var person in Model.Persons)
        {
    %>
    <li><a href="#" class="person">
        <%= person.Name %></a></li>
    <%
        }        
    %>
</ul>

Each person has a unique id.

I use jQuery for my AJAXy stuff, and up until now I have added click functionality to the links in the following way (although it has a very non-jQuery-like smell)

<a href="#" class="person" onclick="return selectPerson('<%= person.Id %>');">
            <%= person.Name %></a>

It works and all, however it also requires me to have a selectPerson() javascript function on each page using this partial view (since what happens in the select is "special" for each view).

I just stumbled upon the jQuery Data() method and it seems to be able to support my needs, i.e. in the views using my partial person list view I could do something like:

$("a.person").click(function() { alert($(this).data("personId")); return false; });

If I have the Id's attached to the "personId" data property on the DOM elements.

Now the problem I have is that I do the HTML rendering server side, but the attaching of the "personId" data property to the DOM elements must be done client side. I.e. either during the foreach loop or in a separate JS loop but I would prefer to avoid that.

Maybe I'm going down the wrong path, I dunno, but maybe somebody has a solution for this or maybe a better approach?

Edit (updated for clarity):

Somehow execute

$(select the "current" anchor).data("personId", set to value of person.Id);

A: 

A better approach would be to use unobtrusive javascript. You generate your link as normal:

<a class="person" href="http://example.com/persons/select?id=&lt;%= person.Id %>"><%= person.Name %></a>
<!-- or use helpers to generate the link -->
<%= Html.RouteLink(person.Name, "Default", new RouteValueDictionary(new { controller = "Persons", action = "Select", id = person.Id })) %>

and then ajaxify it:

jQuery(function() {
    jQuery('a.person').click(function(evt) {
        jQuery.ajax({
            url: this.href,
            success: function(data) {
                // Do something with the returned content
            }
        });
    });
});

I didn't quite understand why would you want to use JQuery.data()

Darin Dimitrov
I haven't really thought of something like this, however I can't use a link/url. This could equally well be used in a Drag-n-Drop situation, where I then async. add a person to say a group (which could be created like you suggest). I need to know "which person" or an alt. approach.
veggerby
A: 

Why don't you "dump" your person id into the ID field of the link.

<a href="#" class="person" id="person_<%= person.Id %>"><%= person.Name %></a>

Now that you have the id, you can use you jQuery to attach the click event to each link with the person class, like darin showed:

jQuery(function() {
    jQuery('a.person').click(function(evt) {
        return selectPerson(this);
    });
});

Now in the selectPerson function, or in the above stated function you have to get the id of the element (which will be like person_234) and take off the person_ part and you're done.

Gidon
Of course that could work and I have thought of that, but IMHO - and you can call me idealistic :) - but there has got to be a better/cleaner way of doing this i.e. keep my data "structured". Also with jQuery.data() I could potentially attach an entire object not just "the key".
veggerby
Albeit not the best solution, this was the path I chose, due to "lack" of a better way :( / :)
veggerby
A: 

You can use the jQuery Metadata plugin.. basically it's using json data in the class property, which is automatically serialized when accessed..

But it adds a lot of markup though..

see http://plugins.jquery.com/project/metadata for reference.

Cheers,

Erik

Erik