Success message not displaying using jQuery ajax

会有一股神秘感。 提交于 2019-12-11 05:04:02

问题


So I have verified that my contact.php (phpmailer file) is working. However at the end, given a successful response, the contact.php says echo: 'done'

if(!$mail1->send()) {
    echo 'error';
    //echo 'Mailer Error: ' . $mail->ErrorInfo;
    return false;
} else {
    echo 'done';
    return true;
}

At that point (I'm guessing since I paid a developer to create the form for me, but haven't tried to test with my own host til recently. This is the code he supplied.

/************
 AJAX Method
*************/
function submitForm()
    {
        //1. user clicked on submit/send button after filling form
        $('#contactform').on('submit',function(e){
            //2. this line will prevent the window's reload!
            e.preventDefault();
        });//end form submit

        //3. handilg the success div
        $('#success_message').show();
        $('#success_message h2').text('Processing, wait please...');
        $('#submit_cf').attr('disabled','disabled');

        //4. the actual ajx process starting from here
        $formData = $('#contactform').serialize();

        $.ajax({
            url : "contact.php",
            type: "POST",
            data : $formData,
            success: function(data) {
                //data - response from server
                //console.log(data);
                if(data == 'done'){
                    $('#success_message h2').text('Mail Sent Successfully!');
                }else{
                    $('#success_message h2').text('There is an error, try again later!');
                    // $('#submit_cf').attr('disabled','disabled');
                }
            }//end success
        });//end ajax
    }//end submitForm() function
})(jQuery, window, document);
</script>

I'm assuming that echo: 'data', return: true shoud send the word data back to the ajax form where the:

if(data == 'done'){
    $('#success_message h2').text('Mail Sent Successfully!');

would take over and populate the div#success_message h2 html with Mail Sent Successfully.

Only instead, the ajax doesn't work at all. Instead a new page loads with just the word "done" on it (which is what I expect happens when you use echo:'done').

I don't know how to make ajax take in 'done' and then populate the same page with the success message.

I loaded jquery into the header, as it is used for several other scripts. The ajax script is in the html rather than an external script.

Please tell there is a simple fix, or do I need to start over with Swift?


回答1:


After looking at the script, it's set up kind of strange. I will notate what I think you need to change but first answer your questions:

I'm assuming that echo: 'data', return: true should send the word data back to the ajax form...

No, data is what is being returned from the ajax page, in my answer I have changed it to say response so it is clearer what it does. It will contain the success/error message

Instead a new page loads with just the word "done" on it...

This usually indicates that there is an issue, either jQuery is not loaded first or there is an error that stops the jquery running properly, so the line that is supposed to stop the form from submitting normally (e.preventDefault()) is interrupted.

I loaded jquery into the header, as it is used for several other scripts. The ajax script is in the html rather than an external script.

This shouldn't be too hard to remedy, you can have this script on it's own instead of the html. It has to be between the event listener instead of the way your's has it and make sure it is placed after the jQuery library loads:

<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript" src="/js/myScript.js"></script>

Please tell there is a simple fix, or do I need to start over with Swift?

You should not have to start over in Swift

/js/myScript.js

$(document).ready(function(){
    // Make a function on this would make more sense, but you only need it if you
    // want to re-use this feature, otherwise you can incorporate it back
    // I made it as a function so it cleans up the submit a bit
    function doSuccess(acton,message,disable)
        {
            $(acton).show();
            $(acton+' h2').text(message);
            $(disable).attr('disabled','disabled');
        }

    // It's strange to have the on('submit') inside the function since it's
    // a listener, you shouldn't need to wrap this in a function, but wrap 
    // everything inside the listener instead
    $('#contactform').on('submit',function(e){
        // This is fine, it does prevent the form from submitting
        e.preventDefault();
        // Assign to variable this form
        var thisForm = $(this);
        // Run messaging
        doSuccess('#success_message','Processing, please wait...','#submit_cf');
        // Run ajax
        $.ajax({
            url : "contact.php",
            type: "POST",
            // You can serialize the form here
            data : thisForm.serialize(),
            success: function(response) {
                // Just do the text here from php
                $('#success_message h2').text(response);
            }
        });
    });
});

On the PHP side, just echo the message. Make it easier since you don't have any complex return:

# You can use a ternary since there are only two options
echo ($mail1->send())? 'Your message sent successfully' : 'There is an error, try again later!';
# Unless there is a reason to return true or false (unless this is part of a
# function or method), you don't need it. It's not doing anything

One last note, where ever you are using the submitForm() (likely it's on your submit button or something as an inline javascript), you should be able to just remove that since the function won't exist anymore.



EDIT/JUST AS A SIDE: I am just going to demonstrate how I do this (in as simple example as I can) in order to get consistent results over and over. It may be too complex for you at this stage but, if you are interested and read the notations it's pretty straight forward. If you copy everything and put them in the correct folders as I labelled below, you can see it work first before you decide to implement it.

It involves a dispatcher page, an xml page, and a javascript ajax object. The idea is that you can build it out and do automated workflows using xml as the automation instructions:

/dispatcher.php

This is the page that will receive your ajax calls. It would receive ALL ajax calls and dispatch the correct instructions. You would want to build some checks (like form token matches) into it because this kind of automation can be dangerous. These are the basics of it:

// Check specifically for actions
if(!empty($_POST['action'])) {
    // This will fetch an xml file and parse it (see next section)
    $config =   simplexml_load_file(__DIR__."/xml/settings.xml");
    // Assign the action
    $action =   $_POST['action'];
    // Check the parsed file for the proper ajax action
    if(!empty($config->ajax->action->{$action})) {
        // Loop through the action
        foreach($config->ajax->action->{$action} as $do) {
            // If there is an include action
            if(isset($do->{"include"})) {
                // Loop through the includes
                foreach($do->{"include"} as $include) {
                    // If the file exists, include it
                    if(is_file($inc = __DIR__.$include))
                        include($inc);
                }
            }
        }
    }
    // Stop processing
    exit;
}

/xml/settings.xml

This is just a basic xml file to help automate your calls. It's pretty straight forward. One thing to note, you will want to put the xml folder outside the root OR use a .htaccess (or web.config for Windows) to secure this folder from access except php. There are examples on the web of this. You can expand this xml out to include multiple pages with the <include> tag and the dispatcher will run one after the other.

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <ajax>
        <action>
            <!-- This would correlate to a hidden field in your form. See html form example -->
            <email_user>
                <include>/contact.php</include>
                <!-- To run more actions on this call, just add another tag here -->
                <!-- <include>/another/page/here.php</include> -->
            </email_user>
        </action>
    </ajax>
</config>

/js/myScript.js

This is slightly different that the above version. I would use an Ajax object so it can be re-used.

// @param $ [object] This accepts jQuery object
var AjaxEngine  =   function($)
    {
        // Used to overwrite default url
        var useUrl;
        // Default url for call
        var url     =   '/dispatcher.php';
        // This is the do before function
        var beforeFunc;
        // This is the default do before
        var useBefore = false;
        // This is what overwrites the url (not needed in this instance)
        this.useUrl =   function(useUrl)
            {
                url =   useUrl;
                return this;
            }
        // This assigns the beforeSend action in ajax
        this.doBefore   =   function(beforeFunc)
            {
                useBefore   =   beforeFunc;
                return this;
            }
        // This is the actual send function
        // @param data [object] This is what data to send to the dispatcher
        // @param fun [object]  This is the anonymous function that will run
        //                      on success of the form 
        this.send   =   function(data,func)
            {
                $.ajax({
                    // Runs before the sending (this is where you add waiting messages)
                    beforeSend: useBefore,
                    url: url,
                    data: data,
                    type: 'post',
                    // This will take the response and drop it into the
                    // anonymous function
                    success: function(response){
                        func(response);
                    }
                });

                return this;
            };
    }
// Wait for document to be ready
$(document).ready(function(){
    // If you use a class, you can act on any form that has the "ajax_form" class
    // This is very powerful. It means you can have many different forms on
    // the same page and use the same script/dispatcher to run/process each
    $('.ajax_form').on('submit',function(e){
        e.preventDefault();
        var thisForm = $(this);
        // Create new ajax engine, you have to pass jQuery for ajax to work
        var Ajax    =   new AjaxEngine($);
        // Set do before action, in your case you have 3 things that must
        // happen before ajax sends. In this example, this function is fixed
        // (not ideal), but you can add automation so you send the correct 
        // doBefore function on a per-form basis
        Ajax.doBefore(function() {      
                $('#success_message').show();
                $('#success_message h2').text('Processing, please wait...');
                $('#submit_cf').attr('disabled','disabled');
            })
            // Send the form data and response function to "/dispatcher.php"
            .send(thisForm.serialize(),function(response) {
                // Do a "try/catch" here, that way you can catch errors
                // Most common in this scenario would be an empty response, or
                // mal-formed json (like a fatal error in php or whatever)
                try {
                    // Parse the response
                    var parseResp   =   JSON.parse(response);
                    // See if there are instructions
                    var instr       =   (parseResp.instructions !== "undefined")? parseResp.instructions : 'text';
                    // Apply instructions, these are just some examples.
                    switch(instr) {
                        case('html'):
                            // Take from php apply html
                            $(parseResp.sendto).html(parseResp.data);
                            break;
                        default:
                            // Take from php apply text
                            $(parseResp.sendto).text(parseResp.data);
                    }
                }
                catch(Exception) {
                    // This will show you in the console what is wrong
                    console.log(Exception.message);
                    // This will show you what was received back so you can address issue
                    console.log(response);
                }
            });
    });
});

/index.php

Example form in the root of the site:

<form action="/tester.php" id="contactform" class="ajax_form">
    <div id="success_message">
        <h2>Hey</h2>
    </div>
    <input type="text" name="test" value="1050724273" />
    <!-- Send this to the dispatcher and match the value in the xml file -->
    <input type="hidden" name="action" value="email_user" />
    <input type="submit" value="Save" />
</form>

/contact.php

Finally, this is the page that will be run in our automation based on the tag in the xml file. Key to this is to return json:

<?php
// Do all your code first, then output json at the very bottom
// For complex html output, do a buffer so you can capture it easily
ob_start();
?>
<h1>Hello people</h1>
<?php
// Get the above text/html from the buffer
$data   =   ob_get_contents();
// Clear out the buffer
ob_end_clean();
// This is what will be sent back as the "response" in the ajax
$response   =   array(
                    // This will tell the ajax where to drop the response
                    'sendto'=>'#contactform',//'#success_message h2',
                    // This is the content from above (<h1>Hello people</h1>)
                    'data'=>$data,
                    // This is just incase you want to expand out the ajax
                    // to include checks for success and failure
                    'success'=>true,
                    // This tells your ajax how to output using the switch
                    'instructions'=>'html'//'text'
                );
// If you have extra includes that you want to run in the ajax call,
// don't die here, but in this instance, since there is only one include (contact.php),
// just die and output the response
die(json_encode($response));


来源:https://stackoverflow.com/questions/39060278/success-message-not-displaying-using-jquery-ajax

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!