2011-10-26 128 views
13

我在Drupal 7中創建了一個表單,並且想要使用AJAX。我將其添加到提交按鈕數組中:AJAX表單驗證並提交

"#ajax" => array(
    "callback" => "my_callback", 
    "wrapper" => "details-container", 
    "effect" => "fade" 
) 

這可行,但整個驗證功能被忽略。如何在my_callback()被調用之前驗證表單?我怎樣才能在AJAX表單上顯示狀態或錯誤信息?

+1

您是否正面驗證被忽略?我做了幾十次,驗證從未被忽略過(除非我明確告訴Drupal使用'#limit_validation_errors'忽略它們)。此外,默認情況下,錯誤消息會自動加載到'wrapper'元素中,所以一旦您修復了第一個元素,它應該就位。你可以發佈一些更多的代碼嗎? – Clive

+0

@Clive 我剛做了另一個測試表單,結果相同。這裏的形式: 功能dr_search_test_form($形式,&$ fstate){$ 形式[ 「包裝」] =陣列( 「#markup」=> 「

」 ); $ form [「name」] = array( 「#type」=>「textfield」, 「#required」=> true, 「#title」=>「Name」 ); $ form [「submit」] = array( 「#type」=>「submit」, 「#value」=>「Send」, 「#ajax」=> array( 「callback」=>「dr_search_test_form_callback 「, 」wrapper「=>」test-ajax「, 」effect「=>」fade「 ) ); return $ form; } –

+0

函數dr_search_test_form_callback($ form,&$ fstate){ return「sadsadas」; ($ form,&$ fstate){ } form_set_error } –

回答

7

好的,我知道了。顯然,你應該在你的Ajax回調函數,而不是隻是一個文本消息返回數組...

事情是這樣的:

return array("#markup" => "<div id='wrapper'></div>"); 
17

這個問題和答案幫助引導我正確的解決方案,但它不是完全清澈透明。讓我們這樣做吧。

事情要非常意識到:

  1. 驗證錯誤信息將被放在裏面的任何被指定爲#ajax['wrapper']
  2. 狠抓其中Drupal Forms API documentation of the ajax wrapper說:「這個整個元素ID被替換,而不僅僅是元素的內容。「
  3. 由於該元素被替換,所以最好再提供一次。 這就是爲什麼Marius Ilie的答案有效 - 不是因爲數組和#markup,而是因爲他包含了包裝器ID設置的div。

下面是對我關閉基於什麼馬呂斯放在上面的註釋工作代碼:

function dr_search_test_form($form, &$fstate) { 
    $form["wrapper"] = array("#markup" => "<div id='test-ajax'></div>"); 

    $form["name"] = array(
    "#type" => "textfield", 
    "#required" => true, 
    "#title" => "Name" 
); 

    $form["submit"] = array(
    "#type" => "submit", 
    "#value" => t("Send"), 
    "#ajax" => array(
     "callback" => "dr_search_test_form_callback", 
     "wrapper" => "test-ajax", 
     "effect" => "fade", 
    ), 
); 
    return $form; 
} 

function dr_search_test_form_callback($form, &$fstate) { 
    return "<div id='test-ajax'>Wrapper Div</div>"; 
} 

function dr_search_test_form_validate($form, &$fstate) { 
    form_set_error("name", "Some error to display."); 
} 
+4

+1在問題關閉後分享您的經驗方式;這是真正的社區問答。 – msanford

8

的這一切對我的作品。表單提交的ajax函數仍然只是直接調用回調函數,繞過驗證,提交,也使得它不能點擊多次。驗證消息不會顯示。我從字面上複製並粘貼了Joshua Stewardson代碼,但它沒有奏效。

事實上,這個用例非常難以記錄,非常令人不安。對我而言,這似乎是AJAX表單API最基本的要求。好吧,完成發泄我的挫折,到解決方案。

下面是我最終做的工作。它感覺哈克和遲鈍。如果單個頁面上有多個表單的實例,它也會中斷,但這是我能做的最好的事情。如果任何人都可以闡明這一點,請做!

基本上,您必須在回調中用自己替換整個表單,並手動將所有設置的消息前置到表單對象。通過將包裝器聲明爲表單的ID(如果單個頁面上存在多個表單實例(因爲ID將被更新)而中斷),可以做到這一點。

function productsearchbar_savesearch_form($form, &$form_state) { 

    $form["wrapper"] = array("#markup" => "<div class='inline-messages'></div>"); 

    $form["name"] = array(
    "#type" => "textfield", 
    "#required" => true, 
    "#title" => "Name" 
); 

    $form["submit"] = array(
    "#type" => "submit", 
    "#value" => "Send", 
    "#ajax" => array(
     "callback" => "productsearchbar_savesearch_form_callback", 
     "wrapper" => "productsearchbar-savesearch-form", 
     "effect" => "fade" 
    ) 
); 

    return $form; 
} 

function productsearchbar_savesearch_form_callback($form, &$form_state) { 
    $messages = theme('status_messages'); 

    if($messages){ 
    $form["wrapper"] = array("#markup" => "<div class='inline-messages'>$messages</div>"); 
    } 
    return $form; 
} 

function productsearchbar_savesearch_form_validate($form, &$form_state) { 
    if ($form_state['values']['name'] == '') { 
    form_set_error('', t('Name field is empty!')); 
    } 
} 

function productsearchbar_savesearch_form_submit($form, &$form_state) { 
    drupal_set_message(t('Your form has been saved.')); 
} 
+0

我遇到了相反的情況,Ajax回調被觸發,然後表單提交函數被調用,並且提交處理程序中的消息返回,並且Ajax響應表示它已被保存。這不是我想要發生的事情。由於這一個觸發批處理操作。這是Drupal 7,如果它很重要。 –

-1

//你可以使用jQuery表單驗證

jQuery('#button-id').mousedown(function() { 
    var textval = $("#get-text-val").val(); 
    if (textval == '') { 
    $("#apend-error-msg").append('<div id="add-text-error" class="add-text-error">error msg</div>'); 
    return false; 
    } 
    else { 
    return true; 
    } 
    return false; 
}); 
+0

如果您想檢查多個字符串長度,那麼在Drupal之外進行驗證可能會造成問題。 – Kevin

9

我找到了一個很好的解決這個問題。

幸得這傢伙的博客:

http://saw.tl/validate-form-ajax-submit-callback

他提出的解決方案是:

// when creating or altering the form.. 
{ 
    $form['#prefix'] = '<div id="formwrapper">'; 
    $form['#suffix'] = '</div>'; 
    // the submit button 
    $form['save']['#ajax'] = array(
    'callback' => 'mymodule_form_ajax_submit', 
    'wrapper' => 'formwrapper', 
    'method' => 'replace', 
    'effect' => 'fade', 
); 
// ... 
} 

function mymodule_from_ajax_submit($form, &$form_state) { 
    // validate the form 
    drupal_validate_form('mymodule_form_id', $form, $form_state); 
    // if there are errors, return the form to display the error messages 
    if (form_get_errors()) { 
    $form_state['rebuild'] = TRUE; 
    return $form; 
    } 
    // process the form 
    mymodule_form_id_submit($form, $form_state); 
    $output = array(
    '#markup' => 'Form submitted.' 
); 
    // return the confirmation message 
    return $output; 
} 
+0

$ form ['#prefix']和$ form ['#suffix']在我的_form_alter鉤子中不起作用。 – AlxVallejo

+0

@AlxVallejo它應該適用於表單的任何元素,包括表單本身。簽出[Form API Reference](https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#prefix) – bmunslow

0

我搜索好幾個小時的路才能正常做到這一點。不幸的是,這些解決方案中的大多數依然依賴於Drupal的服務器端驗證來確定ajax結果或客戶端錯誤消息是否應該放在包裝器中。依賴於服務器的結果比客戶端驗證要慢,這應該幾乎是瞬間的。另外,用表單...替換表單...的錯誤信息對我的偏好來說太麻煩了。

// Prevent form submission when there are client-side errors, trigger ajax event when it is valid 
(function ($) { 
    Drupal.behaviors.submitForm = { 
     attach: function (context) { 
      var $form = $("form#validated_form", context); 
      var $submitButton = $('input[type="submit"]', $form); 

      $form 
       .once('submitForm') 
       .off('submit') 
       .on('submit', function(e){ 

        // Prevent normal form submission 
        e.preventDefault(); 
        var $form = $(this); 

        // The trigger value should match what you have in your $form['submit'] array's ajax array 
        //if the form is valid, trigger the ajax event 
        if($form.valid()) { 
         $submitButton.trigger('submit_form'); 
        } 
      }); 

     } 
    }; 
})(jQuery); 

引用JavaScript觸發爲你的Ajax事件時聽了:

使用jQuery驗證的方法,通過一段JavaScript觸發器觸發AJAX事件

$form['submit'] = array(
    '#type' => 'submit', 
    '#value' => t('Submit'), 
    '#ajax' => array(
     'event' => 'submit_form', 
     'callback' => 'callback_function_for_when_form_is_valid', 
     'wrapper' => 'validated_form' 
    ) 
); 

現在,驗證點擊提交按鈕後立即觸發,並且只有在服務器端驗證有效後纔會進行驗證!