¿Cómo validar y enviar un formulario usando AJAX?

12

He creado un formulario web utilizando la API de formulario. Estoy usando la #AJAXopción de campo para agregar la validación AJAX a cada campo.

¿Es posible validar y enviar el formulario usando AJAX sin volver a cargar la página? Si la validación falla, quiero mostrar un mensaje de error y si la validación es exitosa, entonces quiero mostrar un mensaje (idealmente en una caja de luz) y restablecer los campos del formulario.

Mi código hasta ahora:

$form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
    '#default_value' => '',
    '#maxlength' => '128',
    '#required' => TRUE,
    '#ajax' => array(
        'callback' => '_validate_name',
        'wrapper' => 'name-error-icon-container',
        'method' => 'html',
        'effect' => 'none',
        'progress' => array(
            'message' => NULL,
        ),
    ),
);

$form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Submit',
    '#ajax' => array(
        'callback' => '_handle_form_submit',
        'effect' => 'fade',
    ),
);

las funciones de devolución de llamada se ven así:

function _validate_name($form, $form_state) {

    if ($form_state['values']['name'] != '') {
    $output = 'OK';
    }
    else {
      $output = 'Enter a value';
    }

   return $output;

}

function _handle_form_submit($form, $form_state) {
}

Pero no estoy seguro de qué debe ir en la _handle_form_submitfunción para validar y luego devolver un mensaje o enviar un formulario y restablecer los campos.

Camsoft
fuente

Respuestas:

-2

El módulo de ejemplos tiene un formulario ajax al que puede hacer referencia, así como muchos otros. Aquí hay un enlace al ejemplo de formulario ajax en el repositorio de código, pero sugiero descargarlo para ver la implementación usted mismo de todos modos.

rocketeerbkw
fuente
1
lo siento - No puedo encontrar ningún ejemplo de validación ajaxy en el módulo de ejemplo
ErichBSchulz
Sí, esa es una respuesta hinchada allí mismo. De hecho, tampoco veo ninguna validación allí. Cada devolución de llamada simplemente devuelve el formulario.
AlxVallejo
2
¿Cómo es esta la respuesta aceptada? Ni siquiera dice dónde buscar en el enlace proporcionado (y el enlace no tiene un ejemplo de validación de todos modos).
robinmitra
Nuevo enlace para el ejemplo de formulario ajax: cgit.drupalcode.org/examples/tree/ajax_example/…
Brentg
Hice mi respuesta una wiki, ya que es aceptada pero de mala calidad
rocketeerbkw
11

Sé que esta pregunta ha estado rondando por un par de años por ahora, pero no creo que ninguna de las otras respuestas realmente entienda el envío del formulario Drupal 7 ajax, así que intentaré explicarlo.

Sinve su formulario debería funcionar tan bien sin el ajax como por buena práctica, su controlador de envío ajax no debería hacer nada más que devolver el formulario. Todo lo demás debe estar en su validación y enviar funciones.

function ex_form($form, $form_state) {
  $form['name'] = array(
    '#type' => 'textfield',
     '#title' => t('Name'),
     '#default_value' => '',
     '#maxlength' => '128',
     '#required' => TRUE,
  );

  $form['submit'] = array(
   '#type' => 'submit',
   '#value' => 'Submit',
   '#ajax' => array(
     'callback' => 'ex_form_ajax_handler',
     'effect' => 'fade',
   ),
  );
}

function ex_form_submit(&$form, &$form_state) {
  // Submit logic - runs when validation is ok
  // You can alter the form here to be just a markup field if you want.
}

function ex_form_validate(&$form, &$form_state) {
  // Validation logic - invalidate using form_set_error() or form_error()
}

function ex_form_ajax_handler(&$form, &$form_state) {
  return $form;
}
OWast
fuente
probablemente la mejor respuesta
Andrew Kozoriz
¿Está diciendo que los métodos de validación y envío serán llamados automáticamente para una devolución de llamada AJAX en un botón de envío? ¿En qué orden se llaman los métodos?
Jeff
3

Creo que la publicación de maxtorete el 17 de octubre de 2011 parece dar un ejemplo más completo usando ambos form_validate()yform_submit()

(No lo he probado todavía).

También la respuesta de Joshua Stewardson en el desbordamiento de pila tiene un buen ejemplo de trabajo:

function dr_search_test_form($form, &$fstate) {

  $form['wrapper'] = [
    '#markup' => '<div id="test-ajax"></div>',
  ];

  $form['name'] = [
    '#type'     => 'textfield',
    '#required' => TRUE,
    '#title'    => 'Name',
  ];

  $form['submit'] = [
    '#type'  => 'submit',
    '#value' => 'Send',
    '#ajax'  => [
      '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.');
}

Joshua señala que los mensajes de error de validación reemplazan el #ajax['wrapper']elemento por completo, por lo que su devolución de llamada debe reabastecer este elemento nuevamente mientras lo reemplaza.

ErichBSchulz
fuente
cuando ese enlace invalida es una señal, ¡la pregunta ya no es relevante!
ErichBSchulz
2
el voto negativo es un poco duro, incluso si fue solo un enlace, fue un enlace a la respuesta, no solo un enlace a un módulo que no tiene la respuesta, ¡a diferencia de la respuesta aceptada! de todos modos proporcioné un código de trabajo mientras estaba siendo rechazado.
ErichBSchulz
gracias @ mbomb007 - arreglado ahora
ErichBSchulz
2

En general, la validación y el manejo de envío de formularios deben realizarse en las devoluciones de llamada habituales _validate () y _submit (). La idea es que los formularios aún deberían funcionar sin ajax.

Prácticamente lo único que deben hacer las devoluciones de llamada #ajax es devolver la parte del formulario que debe reemplazarse, de acuerdo con el contenedor definido.

Berdir
fuente
2
Ten cuidado con tu redacción. La devolución de llamada debe devolver TODO EL FORMULARIO, reconstruido desde form_state. Devolver PARTE del formulario es el error más grande de Drupal / AHAH. Ver katbailey.net/blog/ahah-drupal-may-it-one-day-live-its-acronym .
77
Esta pregunta es sobre Drupal 7 ... AHAH ya no existe en Drupal. En una #ajaxfunción de devolución de llamada en Drupal 7, solo devuelve la parte del formulario que desea reemplazar.
Clive
1
@ChrisD. Como mencionó Clive, este es Drupal 7 y ahora tenemos un buen marco ajax que permite hacer todo tipo de cosas sofisticadas, como devolver múltiples partes de formularios separados, etc.
Berdir
@Clive Me encontré con otro problema relacionado con ajax drupal.stackexchange.com/a/142316/19205 donde el autor mencionó que "el formulario debe construirse nuevamente después de que se haya cambiado items_count", que también es para d7. Me confunden con qué afirmación es correcta (sin discutir quién tiene la razón :-)). ¿Podría por favor compartir alguna información sobre esto?
kiranking
0

Hay dos maneras

1)

function abc_form_validate(&$form, &$form_state) {
  // Validation logic - invalidate using form_set_error() or form_error()
}

function abc_form_ajax_handler(&$form, &$form_state) {
  return $form;
}

2) Módulo de ejemplo http://cgit.drupalcode.org/examples/tree/ajax_example/ajax_example.module?id=refs/heads;id2=7.x-1.x#l402

Drock
fuente
Ahora no sé qué tan precisa es su respuesta, pero su formato definitivamente necesita mejoras (si no desea que los moderadores la eliminen). Consulte la página de ayuda si es necesario, o simplemente use algunos de los botones del editor wysiwyg para al menos marcar su código como ... código.
Pierre.Vriens
El código no formateado correctamente no es una razón para eliminar una respuesta. Solo requiere un usuario con privilegio de edición para solucionarlo.
kiamlaluno
Aquí vengo, desesperado, buscando una solución, solo 2 años después de esta respuesta, hice clic en un enlace que me lleva a un árbol / rama no existente. No utilice enlaces en las respuestas, o si pega el contenido al momento de escribir.
MacK
0

En mi caso, el uso de un submittipo causó el formulario para enviar siempre, así que lo cambié a una buttoncon #ajaxespecificada. Luego, tuve que hacer mi validación en la devolución de llamada ajax.

Estaba haciendo un panel de ctools; No sé si eso juega con eso.

function mymodule_form($form, &$form_state) {
  ...
  $form['button'] = array(
    '#type' => 'button',
    '#value' => t('Subscribe'),
    '#ajax' => array(
      'callback' => '_mymodule_ajax',
    ),
  );
  return $form;
}

function _mymodule_ajax($form, &$form_state) {
  if ( ! valid_email_address($form_state['values']['email']) ) {
    form_set_error($form, t('Please enter a valid email address.'));
  } else {
    $form = array(
      '#markup' => t('You have subscribed.'),
    );
  }
  return $form;
}
usuario1359
fuente