2012-02-17 74 views
2

我想在點擊提交按鈕時驗證WordPress帖子上的用戶條目,顯示錯誤消息是否存在問題,如果一切正常,請提交表單。我有一個PHP函數做檢查,如果form_data中的數據是OK的,返回true,否則有一些錯誤代碼。下面的JavaScript發出AJAX請求,應該繼續提交成功後,檢查的形式,但它並不:如何在AJAX調用後繼續表單提交?

 jQuery(document).ready(function() { 
      jQuery('#post').submit(function() { 

       var form_data = jQuery('#post').serializeArray(); 
       var data = { 
        action: 'ep_pre_submit_validation', 
        security: '<?php echo wp_create_nonce('pre_publish_validation'); ?>', 
        form_data: jQuery.param(form_data), 
       }; 
       var proceed = false; 
       jQuery.post(ajaxurl, data, function(response) { 
        if (response.indexOf('true') > -1 || response == true) { 
         proceed = true; 
        } else { 
         alert("Error: " + response); 
         proceed = false; 
        } 
       }); 
       jQuery('#ajax-loading').hide(); 
       jQuery('#publish').removeClass('button-primary-disabled'); 
       return proceed; //breakpoint here makes the code run 
      }); 
     }); 

的代碼是從WPSE question,這原本並沒有爲我工作,爲適應該表格沒有提交。我發現如果綁定到.submit()的jQuery函數返回true,表單應該被提交,所以這就是我試圖實現的。使用上面的代碼,它起初似乎沒有工作(表單在沒有錯誤時沒有提交),但如果在Firebug proceed的密切檢查下,如果在return proceed行處插入了斷點,似乎會得到正確的結果。它按照預期的方式工作,有效數據只有,如果我在等待斷點時等待它,然後繼續執行。如果出現錯誤,則發出警報沒有問題。

處理這個問題的最佳方法是什麼?

編輯基於@Linus

下面回答,下面的代碼可以使用兩種有效和無效的數據:

 jQuery(document).ready(function() { 
      jQuery('#post').submit(function() { 
       if(jQuery(this).data("valid")) { 
        return true; 
       } 

       var form_data = jQuery('#post').serializeArray(); 
       var data = { 
        action: 'ep_pre_submit_validation', 
        security: '<?php echo wp_create_nonce('pre_publish_validation'); ?>', 
        form_data: jQuery.param(form_data), 
       }; 
       jQuery.post(ajaxurl, data, function(response) { 
        if (response.indexOf('true') > -1 || response == true) { 
         jQuery("#post").data("valid", true).submit(); 
        } else { 
         alert("Error: " + response); 
         jQuery("#post").data("valid", false); 

        } 
        //hide loading icon, return Publish button to normal 
        jQuery('#ajax-loading').hide(); 
        jQuery('#publish').removeClass('button-primary-disabled'); 
       }); 
       return false; 
      }); 
     }); 

回答

6

簡答:你不能 - 不能這樣。

一些背景:您作爲參數提供的回調函數(例如$.post)是異步執行的。這意味着你將在之前return proceed你的成功回調已經執行,並且proceed將始終爲false。有了你的斷點,如果你等到成功回調執行完畢,proceed將是true,一切都會好的。

所以,如果你想在你的ajax請求完成後提交表單,你必須使用javascript提交它。這對於jQuery來說非常簡單,只需使用data: $("yourForm").serialize()url: yourForm.action即可執行jQuery $.post

這基本上是你已經在做的事情,你只需要重複那個你真正想要發佈數據的URL。

編輯:

另一種方法是在表單上設置屬性,說valid,並在您的submit處理程序檢查:

jQuery("#post").submit(function() { 
    if($(this).data("valid")) { 
     return true; 
    } 
    // Rest of your code 
}); 

而且在成功回調您的驗證ajax要求您設置/清除該屬性,然後提交:

$("#post").data("valid", true).submit(); 

編輯:

你也想要做你的「AJAX裝載」 /按鈕回調內部實現了$.post基於上述同樣的原因 - 你的Ajax調用返回之前,因爲它是,他們會立即發生。

+0

輝煌的解決方案!我起初掙扎了一下,但後來我意識到它不工作,因爲在WordPress中,jQuery必須被稱爲'jQuery'而不是'$'... – englebip 2012-02-17 16:29:25

+1

哇,你剛剛保存了我的客廳窗口,我的電腦和我最後一絲耐心。我無法理解(但仍然沒有)爲什麼ajax事件不能阻塞,然後發出完成信號並允許定期進行表單處理。這工作,但我不明白爲什麼這種情況不會出現時,測試權力,這是。 – eggmatters 2013-02-02 08:36:35

6

綁定您的按鈕來驗證功能,而不是提交。如果它通過驗證,請調用submit()。

+0

你的意思是使用JQuery驗證或類似的東西進行驗證?我可以使用它進行Ajax調用嗎? – englebip 2012-02-17 15:40:27

+0

取代提交按鈕,使用常規按鈕進行AJAX調用。當您想提交時,請在代碼中提交表單。 – 2012-02-17 15:46:58

+0

Gotcha。我最終也這樣做了,它實際上解決了保存草稿的處理問題,但卻不能發佈帖子。謝謝! – englebip 2012-02-17 17:39:53

1

真正的問題是 - 你爲什麼要做驗證服務器端?爲什麼不能在加載驗證標準之前 - 正在撰寫文章?然後您的驗證可以實時發生,而不是提交。

jquery.post是異步執行的,這意味着JS會在得到答覆之前繼續執行。你被Diodeus的答案卡住了 - 將按鈕綁定到驗證,然後提交表單(使其不會退化),或將$ .post更改爲ajax並關閉異步,這將迫使它在繼續之前等待響應...可能會鎖定您的頁面上的JS直到它超時。

$.ajax({ 
    type: 'POST', 
    url: ajaxurl, 
    async:false, 
    data: data, 
    timeout:3000, 
    success: function(){ 

    } 
}); 
+0

關於服務器端驗證的好處;我現在只是在想這個。我需要確保包含無效/不完整數據的帖子沒有發佈,這就是爲什麼我認爲服務器端是要走的路。也許在沒有滿足要求時禁用提交(發佈)按鈕?如果JavaScript被用戶禁用,怎麼辦?這會增加很多開銷嗎? – englebip 2012-02-17 16:01:58

+0

正面驗證在開銷方面非常輕。 if($('your field').val().length 2012-02-17 16:40:48

2

WordPress使用wp-admin/wp-ajax.php有自己的機制來處理Ajax請求。這允許您在Ajax邊界的任意一邊運行任意代碼,而無需編寫來回的狀態檢查代碼和所有這些代碼。設置你的回調,並去...