2011-10-26 26 views
13

Stworzyłem formularz w Drupal 7 i chcę użyć AJAX. Dodałem to do tablicy przycisku przesyłania:Formularz AJAX zatwierdzić i przesłać

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

Działa to, ale cała funkcja sprawdzania poprawności jest ignorowana. Jak mogę sprawdzić poprawność formularza przed wywołaniem my_callback()? A jak wyświetlić komunikaty o stanie lub błędach w formularzu AJAX?

+1

Czy pozytywna walidacja jest ignorowana? Robiłem to dziesiątki razy, a walidacja nigdy, nigdy nie została zignorowana (chyba, że ​​specjalnie powiedziałem Drupalowi, aby zignorował je za pomocą '# limit_validation_errors'). Również komunikaty o błędach są automatycznie ładowane do elementu 'wrapper', więc po pierwszym rozwiązaniu powinien on po prostu spaść na miejsce. Czy mógłbyś opublikować trochę swojego kodu? – Clive

+0

@ Clive Właśnie zrobiłem kolejną próbną wersję, te same wyniki. Poniżej forma: funkcja dr_search_test_form (postać $, & $ fstate) { $ forma [ "owinięcie"] = tablica ( "#markup" => "

" ); $ form ["name"] = array ( "#type" => "textfield", "#required" => true, "#title" => "Name" ); $ form [ "submit"] = array ( "#type" => "submit", "#VALUE" => "Wyślij", "#ajax" => array ( "callback" => „dr_search_test_form_callback ", " opakowanie "=>" test-ajax ", " efekt "=>" zanikanie " ) ); return $ form; } –

+0

funkcja dr_search_test_form_callback ($ form, & $ fstate) { return "sadsadas"; } } funkcja dr_search_test_form_validate ($ form, & $ fstate) { form_set_error ("name", "Niektóre błędy do wyświetlenia."); } –

Odpowiedz

7

OK, rozumiem. Widocznie trzeba zwracać tablicę na ajax funkcji zwrotnej, a nie tylko wiadomości tekstowych ...

coś takiego:

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

to pytanie i odpowiedź pomógł poprowadzić mnie do właściwego rozwiązania, ale to isn nie jest dokładnie kryształowo czysty. Zróbmy tak.

warte być bardzo świadomi:

  1. komunikaty o błędach walidacji zostaną umieszczone wewnątrz, co jest określone jako #ajax['wrapper']
  2. zwrócić szczególną uwagę na którym Drupal Forms API documentation of the ajax wrapper mówi, że”cały element z tego ID zostaje zastąpiony, a nie tylko zawartością elementu. "
  3. Ponieważ ten element został wymieniony, lepiej go podać ponownie. To powoduje, że odpowiedź Mariusza Ilie działa - nie z powodu tablicy i #markup, ale raczej dlatego, że zawiera element div z ustawionym identyfikatorem opakowania.

Oto kod, który pracował dla mnie opiera się czym Marius umieścić w komentarzu powyżej:

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 za podzielenie się doświadczeniem po zamknięciu pytania; to jest prawdziwe pytanie i odpowiedzi społeczności. – msanford

8

Nic z tego nie działa na mnie. Funkcja ajax ajaxa formularza wciąż wywołuje bezpośrednio funkcję zwrotną, pomijając sprawdzanie poprawności, przesyłając, a także uniemożliwiając wielokrotne kliknięcie przycisku. Komunikaty sprawdzania poprawności NIE są wyświetlane. Dosłownie skopiowałem i wkleiłem kod Joshua Stewardsona i nie zadziałało.

Fakt, że ten przypadek użycia jest tak trudny i nieudokumentowany, jest bardzo denerwujący. Dla mnie wydaje się to najbardziej podstawowym żądaniem dla interfejsu API formularza AJAX. Okay, rozwiązałem moją frustrację, na rozwiązanie.

Oto, co zrobiłem, aby to zadziałało. Czuje się zjadliwy i opóźniony. Zerwie się również, jeśli na jednej stronie znajduje się wiele wystąpień formularza, ale było to najlepsze, co mogłem zrobić. Jeśli ktokolwiek może rzucić światło na to PROSZĘ, proszę!

Zasadniczo, musisz zamienić cały formularz na siebie wewnątrz swojego wywołania zwrotnego i ręcznie przedłożyć wszystkie ustawione komunikaty do obiektu formularza. Zrób to, deklarując, że opakowanie jest identyfikatorem twojego formularza (zostanie ono przerwane, jeśli na jednej stronie znajduje się wiele wystąpień formularza, ponieważ identyfikator zostanie zaktualizowany).

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

Występuje przeciwnie, wywołanie zwrotne Ajax jest wyzwalane, a następnie wywoływana jest funkcja formularza, a komunikat w module obsługi przesyłania powraca z odpowiedzią Ajax, mówiąc, że został zapisany. Co nie jest tym, czym chcę się stać. Ponieważ to wyzwala operację wsadową. To jest Drupal 7, jeśli to ma znaczenie. –

-1

// można używać walidacji formularza 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

Wykroczenie poza Drupal do sprawdzania poprawności może być problematyczne, gdy chcesz sprawdzić więcej niż długość ciągu znaków. – Kevin

9

znalazłem doskonałe rozwiązanie tego problemu.

zasługa blogu tego gościa:

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

rozwiązanie proponuje on jest następujący:

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

$ formularz ['# prefix'] i $ formularz ['# sufiks'] nie działają w moim haku _form_alter. – AlxVallejo

+0

@AlxVallejo Powinno dotyczyć dowolnego elementu formularza, w tym samego formularza. Pobranie informacji na temat [Form API Reference] (https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#prefix) – bmunslow

0

Szukałem wiele godzin sposobu, aby to zrobić prawidłowo. Niestety, większość z tych rozwiązań nadal opiera się na walidacji po stronie serwera Drupala, aby ustalić, czy wyniki ajax lub komunikaty o błędach po stronie klienta powinny być umieszczone w opakowaniu. Opieranie się na wynikach serwera jest wolniejsze niż sprawdzanie poprawności strony klienta, które powinno być praktycznie natychmiastowe. Zastąpienie formularza ... formularzem ... komunikatami o błędach jest nieco zbyt niechlujny w stosunku do moich preferencji.

metod użyć jQuery Validation, aby wywołać ajax zdarzenia z javascript wyzwalania:

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

Reference spust javascript jako ajax zdarzenia, który jest nasłuchiwał:

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

Teraz walidacji uruchamiany zaraz po kliknięciu przycisku przesyłania, a walidacja po stronie serwera ma miejsce tylko wtedy, gdy jest ważna!

Powiązane problemy