views:

40

answers:

2

Hi there

I am integrating the mailchimp API and just wanted to make it a little more user friendly by displaying a loading animator while it submitted the data. I've got it displaying the animator and on success, it hides the div with the animation.

The problem is however if the script returns an error such as the email being incorrect, I need the loader to hide as well - which it doesn't based on what I've tried so far.

Any ideas on where I would need to insert the hide() function for my animator in the following script?

<script type="text/javascript">
var fnames = new Array();var ftypes = new Array();fnames[0]='EMAIL';ftypes[0]='email';fnames[1]='FNAME';ftypes[1]='text';fnames[2]='LNAME';ftypes[2]='text';var err_style = '';
try{
    err_style = mc_custom_error_style;
} catch(e){
    err_style = 'margin: 1em 0 0 0; padding: 1em 0.5em 0.5em 0.5em; background: ERROR_BGCOLOR none repeat scroll 0% 0%; font-weight: bold; float: left; z-index: 1; width: 80%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: ERROR_COLOR;';
}
$(document).ready( function($) {
  var options = { errorClass: 'mce_inline_error', errorElement: 'div', errorStyle: err_style, onkeyup: function(){}, onfocusout:function(){}, onblur:function(){}  };
  var mce_validator = $("#mc-embedded-subscribe-form").validate(options);
  options = { url: 'http://somethingorother.us2.list-manage.com/subscribe/post-json?u=a9cf617dfdf4f2eaoeuaoeub75b&amp;id=4b3aoeu1e2a0&amp;c=?', type: 'GET', dataType: 'json', contentType: "application/json; charset=utf-8",
                beforeSubmit: function(){
                    $('#mc_embed_signup .mc-field-group p').hide();
                    $('#subscribe_loading').fadeIn();
                    $('#mce_tmp_error_msg').remove();
                    $('.datefield','#mc_embed_signup').each(
                        function(){
                            var txt = 'filled';
                            var fields = new Array();
                            var i = 0;
                            $(':text', this).each(
                                function(){
                                    fields[i] = this;
                                    i++;
                                });
                            $(':hidden', this).each(
                                function(){
                                  if ( fields[0].value=='MM' && fields[1].value=='DD' && fields[2].value=='YYYY' ){
                                    this.value = '';
                              } else if ( fields[0].value=='' && fields[1].value=='' && fields[2].value=='' ){
                                    this.value = '';
                  } else {
                                      this.value = fields[0].value+'/'+fields[1].value+'/'+fields[2].value;
                                  }
                                });
                        });
                    return mce_validator.form();
                }, 
                success: mce_success_cb
            };
  $('#mc-embedded-subscribe-form').ajaxForm(options);

});
function mce_success_cb(resp){
    $('#subscribe_loading').hide();
    $('#mce-success-response').hide();
    $('#mce-error-response').hide();
    if (resp.result=="success"){
        $('#mce-'+resp.result+'-response').show();
        $('#mce-'+resp.result+'-response').html(resp.msg);
        $('#mc-embedded-subscribe-form').each(function(){
            this.reset();
      });
    } else {
        var index = -1;
        var msg;
        try {
            var parts = resp.msg.split(' - ',2);
            if (parts[1]==undefined){
                msg = resp.msg;
            } else {
                i = parseInt(parts[0]);
                if (i.toString() == parts[0]){
                    index = parts[0];
                    msg = parts[1];
                } else {
                    index = -1;
                    msg = resp.msg;
                }
            }
        } catch(e){
            index = -1;
            msg = resp.msg;
        }
        try{
            if (index== -1){
                $('#mce-'+resp.result+'-response').show();
                $('#mce-'+resp.result+'-response').html(msg);            
            } else {
                err_id = 'mce_tmp_error_msg';
                html = '<div id="'+err_id+'" style="'+err_style+'"> '+msg+'</div>';

                var input_id = '#mc_embed_signup';
                var f = $(input_id);
                if (ftypes[index]=='address'){
                    input_id = '#mce-'+fnames[index]+'-addr1';
                    f = $(input_id).parent().parent().get(0);
                } else if (ftypes[index]=='date'){
                    input_id = '#mce-'+fnames[index]+'-month';
                    f = $(input_id).parent().parent().get(0);
                } else {
                    input_id = '#mce-'+fnames[index];
                    f = $().parent(input_id).get(0);
                }
                if (f){
                    $(f).append(html);
                    $(input_id).focus();
                } else {
                    $('#mce-'+resp.result+'-response').show();
                    $('#mce-'+resp.result+'-response').html(msg);
                }
            }
        } catch(e){
            $('#mce-'+resp.result+'-response').show();
            $('#mce-'+resp.result+'-response').html(msg);
        }
    }
}
</script>
+1  A: 

The ajaxForm plugin specifically says that you can make use of the options supported by .ajax()

Note that the Options Object can also be used to pass values to jQuery's $.ajax method. If you are familiar with the options supported by $.ajax you may use them in the Options Object passed to ajaxForm and ajaxSubmit.

So, the same way you make a function that executes on success, you can make one that executes on error. Take a look at the jQuery .ajax() page under:

error(XMLHttpRequest, textStatus, errorThrown):

A function to be called if the request fails. The function is passed three arguments: The XMLHttpRequest object, a string describing the type of error that occurred and an optional exception object, if one occurred. Possible values for the second argument (besides null) are "timeout", "error", "notmodified" and "parsererror". This is an Ajax Event.


In your case, simply hide the image on error in the same manner you use on success... something like:

// ... code
options = {
    // ... code
    success: function(responseXML)
             { mce_success_cb(responseXML); }, // <== mce_... takes an argument
    error:   function() { $('#subscribe_loading').hide(); 
                          // any other stuff to do on error;
                         }
};
// ... code

You can use the arguments (XMLHttpRequest, textStatus, errorThrown) for the anonymous function to get information about the error and store it and / or display it.


If you want to handle the case where there is a successful AJAX response, but there is an error within the response, change mce_success_cb()... It looks like it's already set up to handle errors of this sort, so it's just a matter of adding the extra functionality you want:

// ...
function mce_success_cb(resp){
    $('#subscribe_loading').hide();
    $('#mce-success-response').hide();
    $('#mce-error-response').hide();
    if (resp.result=="success"){
        // ...
        // This stuff happens if resp.result == "success"
        // ...
    } else {
        // Add in the error handling functionality you want here
        var index = -1;
        var msg;
        //...

Some general problems

Take care to count all your parens and brackets, since it looks like you left some opened.

The beginning of your doc ready should look like:

$(document).ready( function() {  // <== No need to pass anything to this
    // This will all be executed when the document is ready.
    // ...
});             // <== Maker sure to close all parens and brackets!!!

Additionally, the success callback is going to give you multiple parameters, so you can't use a reference to a function for your success callback, it's gotta look more like this:

    success: function(responseXML)
    {
        mce_success_cb(responseXML);
    }

make sure you look at the AJAXForm plugin documentation describing the arguments passed to the success callback.

Peter Ajtai
Thanks Peter. but what you suggested is is an error if the ajax load doesn't actually work. This script is returning an error without the actual ajax load being an error. Does that make sense? I did try what you suggested though but no luck.
KeenLearner
@Keen - I'm not sure how that's possible. The Ajax call either succeeds or it doesn't. If it succeeds then the first line executed it ` $('#subscribe_loading').hide();` if you put this code in, then if it fails ` $('#subscribe_loading').hide();` will also happen.... so theoretically there's no way the loading image cannot be hidden. ----- Is the image being hidden when there are no errors?
Peter Ajtai
It hides when there are no errors. But the error I'm talking about is mailchimp returning something like "please enter a valid email" if the email field is empty. My understanding is that this error message is coming back as the data in the success return.
KeenLearner
...or somewhere in the validator functions.
KeenLearner
@Keen - Then you have to handle that in the `success` function based upon the value of `data`. `if (data.test(/^Please enter a/)) { ... };`
Peter Ajtai
@Peter that makes sense I'm a little challenged seeing where something like that would fit in the code above.
KeenLearner
@Keen - It actually looks like there's already some sort of mechanism for it.... in `mce_success_db`... `if (resp.result=="success"){ /* ... */ } else { /* this happens if there is an "error" in the response data */ }` ... I think the code should go there.
Peter Ajtai
@Keen - I edited the answer a little to reflect that.
Peter Ajtai
@Peter thanks for that but I did already try it and that didn't remove the subscribe box. I tried again just to be sure and still no change.
KeenLearner
@Keen - Maybe you should include the relevant HTML. If your loader really has an ID of `subscribe_loading`, then it should be disappearing. You sure about your HTML and the the functions are actually running? Are you using Firebug or debugging in some other way?
Peter Ajtai
@Peter - I am using firebug. I can definitely assure you that there is a div with id #subscribe_loading. I could be wrong but I think there is more to it than I understand... ie the sucess is returning some other JS functions which then create the error output, but I can't see what those functions are... I have put the hide() function in many different places in the script above (ie in all the various if/else statements) and just can't get the desired outcome :| So frustrating because this is a pretty simple task and you would imagine this sort of functionality ie loading would be common.
KeenLearner
Inside the function mc_success_db() I put an alert(resp.result); and alert(resp) and nothing happens. No 'success' even alerted.
KeenLearner
@Keen - Well, it looks like your document ready isn't closed, also why are you including an argument (that's usually for other situations, like making plugins)? It should just be `$(document).ready( function() { ... });` Looks like you're missing a `)` and make sure to count your `}` s......
Peter Ajtai
@Keen - Additionally, the `success` callback is passed a series of arguments, so you can't just use a reference to invoke `mce_success_cb`, you have to get those arguments (one of which is the result). --- Take a look at the [ **AJAXForm documentation** ](http://jquery.malsup.com/form/#options-object)
Peter Ajtai
@Keen - I edited the answer to include some of this stuff..... I'd suggest playing around with the plugin and creating a very simple functioning page, and building up complexity as you begin to understand how it works.
Peter Ajtai
A: 

I didn't read any of your code, but have you tried the complete() method for the jQuery.ajax function? It calls the function once the data has been loaded, regardless of the error code sent by the server.

complete(XMLHttpRequest, textStatus)

A function to be called when the request finishes (after success and error callbacks are executed). The function gets passed two arguments: The XMLHttpRequest object and a string categorizing the status of the request ("success", "notmodified", "error", "timeout", or "parsererror"). This is an Ajax Event.

(From http://api.jquery.com/jQuery.ajax/)

Andrew Dunn