views:

51

answers:

3

A quick question of perhaps a more speculative nature. I've been getting heavy into jquery lately to handle all the ajax in my web apps.

Right now I'm building a bidding system in PHP that makes heavy use of mod_rewrite. I'm using jQuery with a confirm dialog to send an Ajax request that will spend some of the user's predeposited credits on a bid. The ajax request to spend is sent with the cost as a post parameter to a PHP controller that spends the users credits and then echos the output, which jQuery then places back into the document.

It's working fine, but what I'm wondering is if there is a better way to make jQuery handle the refusal of the purchase if the user has insufficient credits. Right now I have the php answering with an echo that displays this message with a link to the make a deposit page... but I'd rather have a redirect happen automatically.

Is there some way my jQuery script could be notified with the boolean of success or failure before .load finishes, and then redirect in the case of failure? Possibly through HTTP headers determining the handling? The only way I could think of is to place a true or false in an html element that gets check in the callback after .load() and in the case of a false perform a redirect.

Thanks and sorry for the explanation length.

A: 

if the callback function is like "function (data) {" then you could return "NSF" or something like that, and simply compare 'data' to 'NSF', and do the redirection with window.location

Fosco
+2  A: 

If every bidding attempt requires going somewhere else, why use AJAX in the first place?

Anyway, if you look at jQuery's API documentation you'll see that load() is not the only function available. Most of the are simplified versions of ajax(); if you use this one, you can control all possible events right from there. No need to mess with HTTP headers!

I suggest you redesign your server-side script so it returns a JSON object. Then, you can send back all the different types of responses:

{
    biddingSuccessful: true,
    linkToDepositPage: "http://example.com",
    textToDisplay: "Your bidding was successful"
}
Álvaro G. Vicario
This is the best solution IMO.
jarcoal
+1  A: 

Use the lower level $.ajax call to have full maximum control over the request. Ideally, instead of sending a success 2xx response, send an error response which will automatically get sent to your error callback.

$.ajax({
    url: '..',
    success: function() {
        // if it gets here, then assume credits were used
    },
    error: function() {
        // some error happened
        // if error was about insufficient funds, then redirect
    }
});

From the server, send the success response as you are doing right now. However for errors, change the response header, and send a JSON object or plain text indicating what the error was. And there is a header for exactly what you are looking for. It's 402 - Payment Required :)

header('HTTP/1.1 402 Payment Required');

send a JSON object as response with more details:

{
    status: 'error',
    reason: 'Insufficient Funds',
    balance: '$2.78',
    amountRequested: '$3.50'
}

For the updated comment, you need to use a closure (better than global variables :) Suppose the outer function gets the element name/ID, wraps that value through a closure in the success callback. Please let me know if this is not what you intended.

function makeAJAXCall(elementName) {
    $.ajax({
        success: function(...) {
            // elementName is available here through a closure
            alert(elementName);
        }
    });    
}
Anurag
Thanks so much for the guidance. This worked like a charm and also helped with some of the error handling!
DeaconDesperado
@DeaconDesperado - You're very welcome. I'm glad it was helpful :)
Anurag
Just one question, I've structure everything exactly as you described - how can pass an additional argument to the callback to allow my callback function to know which div to update in the case of success?
DeaconDesperado
@DeaconDesperado - is that additional argument coming from the server, or do you know it beforehand when making the request? Also, when writing a comment, if you put @UserName, it will generate a notification for the user :)
Anurag
@Anurag - It's coming from the confirm dialog- I'd post the code but it gets wicked ugly in a comment - should I open a new question? Basically a yes answer to the confirm dialog activates the function that uses the code you've given me, and this anonymous function gets the element identifier that I need to update. I need a way to pass this into the success anon function you have here without breaking the arguments for the response that jquery automatically hands to the indentified success callback. Am I making sense? Sorry.
DeaconDesperado
@DeaconDesperado - I've updated the answer, you can use closures to capture the id of the element inside the success callback.
Anurag
@Anurag - Thanks for your help - by looking through the documentation, I realized that what I was looking for was the context setting of the Ajax method. That allowed me to pass about the div I was looking to manipulate between functions. Awesome stuff! Thanks again!
DeaconDesperado