Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unobtrusive JavaScript with server side values, best practice?

I'm used to do doing things like this:

<a href="Javascript:void(0);" onclick="GetCommentForGeneralObservation(<%# Eval("ID") %>)">

That would be in a repeater or such like btw. However I an now trying to use unobtrusive JavaScript and hence get rid of any JS in the markup. I was trying to figure out what the best practice is in cases like this? I've used attributes and then got the value using JQuery to pass to the AJAX call but it seems a bit of a hack.

Edit in light of first reply:

I was thinking more of the

Separation of functionality (the "behavior layer") from a Web page's structure/content and presentation.

part of unobtrusive JS as I understand it.

This happens to be for an application where I don't have to worry about Javascript being turned off on the client, it's hosted internally at my company. What I was getting at was how would I get the value from Eval("ID") into the JS call if I were to attach the onclick event in a separate .js file via JQuery.

Sorry for not being clearer. I appreciate the need for progressive enhancement in public facing apps.

like image 679
Jules 999 Avatar asked Sep 22 '09 15:09

Jules 999


4 Answers

In HTML 5 you are allowed to define your own attributes prefixed with 'data-'

e.g.

<a  
class="comment"
data-rendered-id="<%# Eval("ID") %>"
href="/getCommentForGeneralObservation/<%# Eval("ID") %>" >

And then use that attribute in jQuery in your click event handler.

$(".comment").click(function () {
  var id = $(this).attr("data-rendered-id");
  return GetCommentForGeneralObservation(id);
});

This will work in most pre-HTML5 browsers too as long as they support jQuery.

Note that in unobtrusive javascript you really should support non-javascript browsers, hence you need an href attribute that works as well.

like image 158
DanSingerman Avatar answered Oct 19 '22 10:10

DanSingerman


I'd start with:

<a href="/getCommentForGeneralObservation/<%# Eval("ID") %>" class="getCommentForGeneralObservation">

and then attach an event handler that looked something like this:

function (event) {
    var href = this.href;
    var id = href.search(/\/(\d+)/);
    return GetCommentForGeneralObservation(id);  
};
like image 4
Quentin Avatar answered Oct 19 '22 11:10

Quentin


I'm going to re-answer this because I understand the question now and the approach I usually use is different from what has been suggested so far.

When there's no way to avoid having dynamic content, I will usually do the following:

<script type="text/javascript">
  var myApp = {commentId:<%# Eval("ID") %>};
</script>
<script type="text/javascript" src="myAppScript.js"></script>

Now, in myAppScript.js, you can use myApp["commentId"] wherever you need that ID to be referenced. (I use a dictionary so as to not pollute the global namespace)

The advantage of this approach is that your myAppScript.js is still completely static and so you can serve it very fast. It also has the advantage of keeping the relevant information out of the URL and you can use Javascript objects, which can help a lot with complex and/or hard-to-parse data.

The disadvantage is that it requires inline Javascript, which isn't much of a disadvantage unless you're a web perfectionist.

I also really like DanSingerman's approach, which is more suited if your data is specific to a tag.

like image 3
Kai Avatar answered Oct 19 '22 10:10

Kai


You might wish to use JQuery metadata plugin, or the core data function.

http://docs.jquery.com/Core/data

http://plugins.jquery.com/project/metadata

like image 1
JAL Avatar answered Oct 19 '22 11:10

JAL