Сообщение об успехе не отображается с использованием jQuery ajax

Итак, я убедился, что мой contact.php (файл phpmailer) работает. Однако в конце, при успешном ответе, contact.php говорит echo: 'done'

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

В тот момент (я предполагаю, что я заплатил разработчику за создание формы для меня, но до недавнего времени не пробовал тестировать на своем собственном хосте. Это код, который он предоставил.

/************
 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>

Я предполагаю, что echo: 'data', return: true должны отправить слово data обратно в форму ajax, где:

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

взял бы на себя и заполнил бы div#success_message h2 html Mail Sent Successfully.

Только вместо этого ajax вообще не работает. Вместо этого загружается новая страница со словом «готово» (что, как я ожидаю, происходит, когда вы используете echo: «готово»).

Я не знаю, как заставить ajax принять «готово», а затем заполнить ту же страницу сообщением об успехе.

Загрузил jquery в шапку, так как он используется для нескольких других скриптов. Скрипт ajax находится в html, а не во внешнем скрипте.

Скажите, пожалуйста, есть простое решение, или мне нужно начать заново со Swift?


person Paeon    schedule 21.08.2016    source источник
comment
Можешь форму показать?   -  person Rasclatt    schedule 21.08.2016


Ответы (1)


После просмотра сценария он настроен как-то странно. Я отмечу, что, по моему мнению, вам нужно изменить, но сначала отвечу на ваши вопросы:

Я предполагаю, что echo: 'data', return: true должен отправить данные слова обратно в форму ajax...

Нет, data - это то, что возвращается со страницы ajax, в моем ответе я изменил его, чтобы сказать response, чтобы было понятнее, что он делает. Он будет содержать сообщение об успехе/ошибке

Вместо этого загружается новая страница со словом «готово» на ней...

Это обычно указывает на наличие проблемы: либо jQuery не загружается первым, либо есть ошибка, которая останавливает работу jquery, поэтому строка, которая должна мешать нормальной отправке формы (e.preventDefault()) прерывается.

Загрузил jquery в шапку, так как он используется для нескольких других скриптов. Скрипт ajax находится в html, а не во внешнем скрипте.

Это не должно быть слишком сложно исправить, вы можете использовать этот скрипт самостоятельно вместо html. Он должен быть между прослушивателем событий, а не так, как у вас, и убедитесь, что он размещен после загрузки библиотеки jQuery:

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

Скажите, пожалуйста, есть простое решение, или мне нужно начать заново со Swift?

Вам не нужно начинать все сначала в 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);
            }
        });
    });
});

На стороне PHP просто повторите сообщение. Сделайте это проще, так как у вас нет сложного возврата:

# 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

И последнее замечание: где бы вы ни использовали submitForm() (скорее всего, это кнопка отправки или что-то вроде встроенного javascript), вы должны просто удалить это, поскольку функция больше не будет существовать.



РЕДАКТИРОВАНИЕ/ПРОСТО КАК СТОРОНА: я просто продемонстрирую, как я это делаю (на как можно более простом примере), чтобы снова и снова получать стабильные результаты. На данном этапе это может показаться вам слишком сложным, но если вы заинтересованы и читаете обозначения, все довольно просто. Если вы скопируете все и поместите их в правильные папки, как я отметил ниже, вы сначала увидите, как это работает, прежде чем решите реализовать это.

Он включает в себя страницу диспетчера, страницу xml и объект ajax javascript. Идея состоит в том, что вы можете создать его и выполнять автоматизированные рабочие процессы, используя xml в качестве инструкций по автоматизации:

/dispatcher.php

Это страница, на которую будут поступать ваши вызовы ajax. Он будет получать ВСЕ вызовы ajax и отправлять правильные инструкции. Вы хотели бы встроить в него некоторые проверки (например, совпадения токенов формы), потому что такая автоматизация может быть опасной. Вот его основы:

// 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

Это простой XML-файл, который поможет автоматизировать звонки. Это довольно прямолинейно. Следует отметить одну вещь: вы захотите поместить папку xml вне корня ИЛИ использовать .htaccess (или web.config для Windows), чтобы защитить эту папку от доступа, кроме php. Примеры этому есть в сети. Вы можете расширить этот xml, включив в него несколько страниц с тегом <include>, и диспетчер будет запускаться одна за другой.

<?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

Это немного отличается от приведенной выше версии. Я бы использовал объект Ajax, чтобы его можно было использовать повторно.

// @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

Пример формы в корне сайта:

<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

Наконец, это страница, которая будет запускаться в нашей системе автоматизации на основе тега в XML-файле. Ключом к этому является возврат 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));
person Rasclatt    schedule 21.08.2016
comment
Спасибо за такой подробный ответ. Я не смогу работать с этим до вечера, но я хочу поблагодарить вас за этот ответ. - person Paeon; 21.08.2016
comment
Нет проблем, я пытался сделать это действительно ясным, но если у вас возникнут какие-либо проблемы, дайте мне знать. Я буду рядом. - person Rasclatt; 21.08.2016