views:

896

answers:

6

I currently rely on anchor tags to perform AJAX requests on my web application (using jQuery). For example:

<script type="text/javascript">
    $(document).ready(function() {
        $("#test").click(function() {
            // Perform AJAX call and manipulate the DOM
        });
    });

    <a id="test" href="">Click me!</a>
</script>

However, these anchor tags pretty much become useless if the user disables javascript in their browser. What's the best way to handle graceful degradation of these anchor tags? Is my only option to switch them all to buttons inside form tags?

Edit: I should be more clear and specify that my AJAX call is an HTTP POST to a URL that I cannot, for security reasons, expose to normal HTTP GETs (e.g. think of a delete url "/items/delete/1"). With that in mind, I can't change the href of the anchor to be "/items/delete/1" in order to satisfy users with javascript turned off since it poses a security risk.

+1  A: 

Read about Unobtrusive JavaScript to learn how to separate JS behavior from your actual markup. Anything else I post will just be a rehash of what someone else has said better elsewhere

Kevin
The javascript in my example is unobtrusive, in that the JS behavior is separated from the markup (it's set in the jQuery ready event). The problem is that the functionality isn't preserved)
Kevin Pang
Having the href="javascript:void(0)" is most certainly not obtrusive. The idea is that the href should point to something useful, not a JS function
Kevin
I would argue that if you're using the javascript: href at all, you're JavaScript isn't unobtrusive.
foxxtrot
Well I can remove the href as it's not really pertinent to the question.
Kevin Pang
+2  A: 

Simple, don't use the javascript: URI syntax as the href, at least, not in the HTML delivered to the client.

Deliver the HTML from the server with the href taking the user to whatever page you want to take them, and then replace the href (or capture the onclick event) for the anchor tag and do whatever you wish, being sure to prevent the default action for the event fire.

<script type="text/javascript">
    $(document).ready(function() {
        $("#test").click(function(e) {
            // Perform AJAX call and manipulate the DOM
            e.preventDefault();
        });
    });

    <a id="test" href="/Proper/URI">Click me!</a>
</script>

And I fully agree with the suggestion to read Unobtrusive JavaScript.

foxxtrot
I should have been more clear. My AJAX call is actually an HTTP POST. You usually don't want to expose certain urls to GET requests (e.g. delete operations).
Kevin Pang
So I can't just do <a id="test" href="/items/delete/1">Click me!</a> since it's a security risk. The delete has to be done server side using a POST, which kind of limits my options on the HTML to use it seems (either require javascript or change to a form).
Kevin Pang
Since you need to provide a non-JS version, links should not be used for POST. Design for Non JS and enhance it with Ajax, don't degrade.
Diodeus
It is no more *secure* to use a POST instead of a GET in this case, but if you absoluately must use a POST, then yes, you'll need to use a Form.
foxxtrot
+1. @Kevin: your use of the <a> tag to do an HTTP POST operation is conflicting. <a> was designed for HTTP GET. You won't find a satisfactory answer here if you keep the semantics of your operation embedded in an <a> tag. See http://www.w3.org/2001/tag/doc/whenToUseGet.html
Crescent Fresh
It is more secure according to this: http://stephenwalther.com/blog/archive/2009/01/21/asp.net-mvc-tip-46-ndash-donrsquot-use-delete-links-because.aspx
Kevin Pang
That point is understood. If you must support the non-JS case, perhaps use an intermediate page where they confirm their desire to delete?
foxxtrot
+5  A: 

One option (for which I'm sure I'll get downvoted), is to not bother with people who have javascript off. Display a message in a <noscript> tag informing the user that your site requires Javascript.

It'll affect two groups of people: those who have knowingly disabled javascript and presumably know how to turn it back on, and those who are viewing your site on an older mobile device.

Consider how important these groups of people are before you go on spending hours and hours developing for them.

nickf
Also, one thing devs often forget is that you can sprinkle <noscript> tags all over the page as needed (ie, next to the buttons and links that need javascript to run), that way the users w/ js off still get most of your page, with warnings about the parts that won't work.
Crescent Fresh
+1, valid point, although the problem is what people think will take "hours and hours" (it's usually not that difficult)
orip
and the third type is browsing from behind a corporate firewall
bandi
firewalls can block javascript?
nickf
Yeah. Lots of govt people have JS turned off by paranoid IT departments.
Paolo Bergantino
A: 

See the Stack Overflow question What is the difference between the different methods of putting javascript in an <a> and my answer.

cowgod
+2  A: 

The answer I was looking for is buried in one of the comments:

your use of the <a> tag to do an HTTP POST operation is conflicting. <a> was designed for HTTP GET. You won't find a satisfactory answer here if you keep the semantics of your operation embedded in an <a> tag. See http://www.w3.org/2001/tag/doc/whenToUseGet.html

Kevin Pang
+1  A: 

Your best bet for no-JS would probably be to have a form with a submit button, and point the form's action to your URL.

You can style the button to look like a link (or like anything else):

<button class="linkstyle" type="submit">Foo</button>
<style type="text/css">
button.linkstyle { border:none; background:none; padding:0; }
<style>

There's a good example of styling buttons in Particletree's article: Rediscovering the Button Element

orip