views:

263

answers:

7

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.

+3  A: 

Unobtrusive means you don't depend on Javascript for functionality and therefore your code is extended with Javascript rather than replaced by it.

In your case, you're embedding Javascript directly in the link, and worse off, the link won't work at all without Javascript enabled. Instead you'll want something like this, which is pure HTML without any reference to Javascript:

<a id="commentLink" href="comment.asp">Get Comment</a>

And your Javascript (assuming you're not using a framework) would be something like:

function GetCommentForGeneralObservation(evt) {
  // Extra javascript functionality here
}

document.getElementById("commentLink").onclick = GetCommentForGeneralObservation;

With Jquery I believe you could just do:

$("#commentLink").click(GetCommentForGeneralObservation);
Kai
This is a good answer, but doesn't actually answer the question!
RichardOD
Oops! Thanks for clarifying the question OP.
Kai
Actually, $("#commentLink").click(GetCommentForGeneralObservation);
Nosredna
@Nosredna Thanks, I updated this.
Kai
+4  A: 

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);  
};
David Dorward
I was thinking along these lines, but parsing the URL is still somewhat hacky
DanSingerman
The URLs fit a standard pattern (so are safe to parse like this), and are needed for the server side fallback to work. This is the only approach I can think of that doesn't duplicate information.
David Dorward
+10  A: 

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.

DanSingerman
I do the same thing currently, just using the 'name' attribute. So it looks like var id=$(this).attr('name');
Alex JL
Yeah attributes is the method I've tried as one answer to this though I didn't know about the "data-" prefix so thanks for that, makes it feel like less of a hack that it's an accepted way of attaching data to elements.
Jules 999
+1  A: 

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

Alex JL
+1  A: 

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.

Kai
Yeah I've sorta used this approach for data which isn't attached to tags though using a object is a nice touch which I had not thought of so thanks for that.
Jules 999
A: 

How about making sure it is fully unobtrusive?

In the head of the HTML document

<script src="path/to/php/or/other/equivalent/server/side/file"></script>

In the path/to/php/or/other/equivalent/server/side/file:

 var SiteServerVariablesEtc = { 
    someProperty: <?php echo "hello" ?> 
 }

In your normal JS file:

var myVar = SiteServerVariablesEtc.someProperty;
Adoro Media
A: 

You could use the rel attribute of the anchor tag to store the value you want to associate with the link.

<a href="#n" class="comment" rel="<%# Eval("ID") %>">Click Here</a>

Then in your jQuery code you can check the rel attribute to get the value you're looking for.

$(".comment").click(function () {
  return GetCommentForGeneralObservation(this.rel);
});

(Pretty sure this is accurate for jQuery, but I'm more of a MooTools guy...)

Shawn Steward