views:

237

answers:

2

I need to send click information on my website to a third party server using ajax (json). I am using jquery and I added the click event to certain links. In the click event I am making a json request to a remote server with the location of the click (heat map) and some other information. The problem is that the ajax function doesn't fire in time before the default link action happens. Setting async to false doesn't seem to work on remote ajax calls. I have tried preventDefault(), but then I don't know how to run the default action after the successful ajax call. Here is what I want to do:

$('a').click(submit_click);

function submit_click(e,fireAjax){
    e.preventDefault();
    cd_$.ajax({
        url: jsonUrl, //remote server
        dataType: 'json',
        data: jsonData,
        async: false,
        success: function(reply){
            //Run the default action here if I have to disable the default action
        },
    });
}

Any suggestions?

A: 

So in other words, you're trying to do two things at the same moment in time:

<a ID="SOMETAG" href="...">link</a>

and

function onClick() {
    // Attached to "#SOMETAG" and does an AJAX call ...
}

and you want to leave the HREF of SOMETAG in case they have javascript turned off?

I think the solution is when you attach to the onclick handler you should remove the href via javascript, then have the onSuccess call the href programmatically.

Because I don't see where you can have the browser spawn a new process to finish the AJAX call for you, that rather defeats the model. If I navigate away from a page (or close the tab) I don't want the browser to keep talking to the server on my behalf...

drachenstern
I probably wouldn't actually remove the href from the DOM completely - just have the onClick "return false"
Matthew J Morrison
@Matthew J Morrison ~ I don't see the difference in removing the HREF or returning false, two sides of the same coin, no?
drachenstern
That would be ONLY in this case though. Removing href makes it no longer a valid A element so why not just return false like you would in any other case you call code on an A element and don't actually want to follow the link? I'm saying in the spirit of best-practice here...
Dan Heberden
@drachenstern if you remove the href but you need that url to be able to redirect the page to when you're ajax is finished, you're going to wish you hadn't removed it.
Matthew J Morrison
@Matthew J Morrison ~ But not if you either a) store it in the data of the element, or b) use a specific onClick that already knows to point to that page. || @Dan Heberden ~ like people don't regularly abuse dom elements all the time? ;) || I just put how I would do it, but then again I would assume that any functionality not required without javascript to not be this mission critical, so I think it's an unsound strategy to rely on this behavior to begin with. Not my design, not my project, not my code. I only answered how I figured to solve the particular problem.
drachenstern
+1  A: 

Yeah, you'll have to

  • capture the href value of the link
  • return false in your submit_click function
  • change the page's url on your success function to the stored href value

    $('a').click(submit_click);

    function submit_click(e,fireAjax){
        e.preventDefault();
        var oldHref = $(this).attr('href'); // store the old url
        cd_$.ajax({
            url: jsonUrl, //remote server
            dataType: 'json',
            data: jsonData,
            async: false,
            success: function(reply){
                //Run the default action here if I have to disable the default action
                window.location.href = oldHref; // go to the new url
            },
        });
        return false; // don't actually go to the href
    }
    
Dan Heberden
Dang, so if I wanted to do the same thing on a submit button, I would have to detect the type of thing that was clicked, and call the appropriate action (submit the form, or go to the link)?
Clint
Well on the submit button, you'd be better off using the submit handler of the actual form.. `$('#myForm').submit(function() {` and do your stuff
Dan Heberden
Thanks Dan! That seems to be working fine. I still wish there was a way to take the event object and trigger the default event... (e.g. e.fireOriginalEvent(), but your way will work fine.
Clint
I want to +1 this, but I've exceeded my max votes today... this is how I would do it! (I'll come back and +1 later)
Matthew J Morrison
@Clint - but then you'd fire the whole process over again :) if you are bound to the event and fire it, you are going to keep sending the ajax, refiring, sending, refiring...
Dan Heberden
I'll +1 it too ;) I like his answers as much or more than my own. That is why I come here, to learn and challenge myself :D
drachenstern
I appreciate the compliments :) And ditto about why I come here - keeps me sharp ;)
Dan Heberden