Unobtrusive JavaScript with server side values, best practice?
Asked Answered
C

7

6

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.

Copra answered 22/9, 2009 at 15:6 Comment(0)
L
12

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.

Lovesick answered 22/9, 2009 at 15:40 Comment(3)
I do the same thing currently, just using the 'name' attribute. So it looks like var id=$(this).attr('name');Technician
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.Copra
This is a very late response, but the preferred approach to getting a data attribute through jQuery is the data API: api.jquery.com/data. In this case you'd use var id = $(this).data('rendered-id');Untruth
D
4

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);  
};
Dreddy answered 22/9, 2009 at 15:28 Comment(2)
I was thinking along these lines, but parsing the URL is still somewhat hackyLovesick
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.Dreddy
V
3

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);
Verbosity answered 22/9, 2009 at 15:13 Comment(3)
This is a good answer, but doesn't actually answer the question!Superdreadnought
Oops! Thanks for clarifying the question OP.Verbosity
Actually, $("#commentLink").click(GetCommentForGeneralObservation);Comma
V
2

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.

Verbosity answered 22/9, 2009 at 16:4 Comment(1)
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.Copra
T
1

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

Technician answered 22/9, 2009 at 16:2 Comment(0)
H
0

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...)

Heady answered 20/11, 2009 at 15:7 Comment(0)
U
-1

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;
Ulund answered 15/10, 2009 at 14:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.