2011-10-26 16 views
13

Creé un formulario en Drupal 7 y quiero usar AJAX. He añadido esto a la matriz botón de envío:formulario AJAX validar y enviar

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

Esto funciona, pero toda la función de validación se ignora. ¿Cómo puedo validar el formulario antes de llamar al my_callback()? ¿Y cómo puedo mostrar el estado o los mensajes de error en un formulario AJAX?

+1

¿Está seguro de que la validación está siendo ignorada? Lo he hecho docenas de veces y la validación nunca ha sido ignorada (a menos que le haya dicho específicamente a Drupal que las ignore usando '# limit_validation_errors'). Además, los mensajes de error se cargan automáticamente en el elemento 'wrapper' de manera predeterminada, por lo que una vez que hayas arreglado el primer bit, debería encajar en su lugar. ¿Podrías publicar algo más de tu código? – Clive

+0

@Clive Acabo de hacer otra forma de prueba, los mismos resultados. Aquí está la forma: función dr_search_test_form (forma $, Y $ FSTATE) {$ forma [ "envoltorio"] = array ( "#markup" => "

" ); $ form ["name"] = array ( "#type" => "textfield", "#required" => true, "#title" => "Nombre" ); $ formulario [ "enviar"] = array ( "#TYPE" => "enviar", "#value" => "Enviar", "#ajax" => array ( "callback" => "dr_search_test_form_callback ", " envoltura "=>" prueba-ajax ", " efecto "=>" fundido " ) ); return $ form; } –

+0

function dr_search_test_form_callback ($ form, & $ fstate) { return "sadsadas"; } función dr_search_test_form_validate ($ form, & $ fstate) { form_set_error ("nombre", "Algún error para visualizar"); } –

Respuesta

7

Ok, lo entiendo. Al parecer, usted debe devolver una matriz en su función de devolución de ajax, no sólo un mensaje de texto ...

Algo como esto:

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

Esta pregunta y la respuesta me ayudó a guiar a la solución correcta, pero ISN No es exactamente claro como el cristal. Hagámoslo así.

Cosas que tener muy en cuenta:

  1. mensajes de error de validación se colocan dentro de lo que sea se especifica como el #ajax['wrapper']
  2. Ponga mucha atención a donde el Drupal Forms API documentation of the ajax wrapper dice que "el elemento completo con este La identificación se reemplaza, no solo el contenido del elemento ".
  3. Como ese elemento se reemplaza, es mejor que lo proporcione de nuevo. Esa es la razón por la cual la respuesta de Marius Ilie funciona, no por la matriz y #markup, sino porque incluye el div con el conjunto de id del wrapper.

Aquí es código que estaba trabajando para mí basa fuera lo Marius puso en el comentario anterior:

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 para compartir su experiencia después de cerrada la pregunta; esta es la verdadera Q & A de la comunidad. – msanford

8

Nada de esto funciona para mí. La función ajax del envío de formulario aún llama directamente a la función de devolución de llamada, al omitir la validación, enviar y también hacer que el botón no pueda hacerse clic varias veces. Los mensajes de validación NO se muestran. Literalmente copié y pegué el código de Joshua Stewardson y no funcionó.

El hecho de que este caso de uso sea tan difícil e indocumentado es muy perturbador. Para mí, esta parece ser la más básica de las solicitudes para una API de formulario AJAX. De acuerdo, aliviando mi frustración, en la solución.

Esto es lo que terminé haciendo para que esto funcione. Se siente hacky y retrasado. También se romperá si hay múltiples instancias del formulario en una sola página, pero fue lo mejor que pude hacer. Si alguien puede arrojar luz sobre esto, POR FAVOR, hazlo!

Básicamente, debe reemplazar todo el formulario consigo mismo dentro de su devolución de llamada, y anteponer manualmente cualquier mensaje configurado al objeto de formulario. Para ello, declare que el contenedor es la identificación de su formulario (se romperá si hay varias instancias de su formulario en una sola página, porque la ID se actualizará).

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

Experimento lo contrario, se activa la devolución de llamada de Ajax y luego se llama a la función de envío de formulario y el mensaje en el controlador de envío regresa con la respuesta de Ajax que dice que se guardó. Que no es lo que quiero que pase. Dado que este dispara una operación por lotes. Este es Drupal 7 si es importante. –

-1

// Puede utilizar la validación de formularios 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

Salir de Drupal para la validación puede ser problemático cuando se desea verificar más que la longitud de la cadena. – Kevin

9

He encontrado una excelente solución a este problema.

crédito va al blog de este tipo:

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

La solución que propone es el siguiente:

// 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 ['# prefijo'] y $ formulario ['# sufijo'] no funcionan en mi gancho _form_alter. – AlxVallejo

+0

@AlxVallejo Debe aplicarse a cualquier elemento de un formulario, incluido el formulario en sí. Consulte la [Referencia de la API de formulario] (https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#prefix) – bmunslow

0

Busqué muchas horas una manera de hacer esto correctamente. Desafortunadamente, la mayoría de estas soluciones todavía se basan en la validación del lado del servidor de Drupal para determinar si los resultados de AJAX o los mensajes de error del lado del cliente deben colocarse en el contenedor. Confiar en el resultado del servidor es más lento que la validación del lado del cliente, que debe ser prácticamente instantánea. Además, reemplazar el formulario ... con un formulario ... con los mensajes de error es un poco demasiado complicado para mi preferencia.

métodos de uso de validación jQuery para activar un evento ajax con un gatillo javascript:

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

referencia el gatillo javascript como su evento ajax que se escucha para:

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

Ahora, la validación es se activa tan pronto como se hace clic en el botón Enviar, y la validación del lado del servidor solo ocurre una vez que es válida.

Cuestiones relacionadas