Добавление разрыва страницы в многоступенчатую форму
У меня возникла некоторая проблема, я пытаюсь использовать команды ajax, чтобы перейти к следующему обращению в моей форме. Я действительно не понимаю, как это сделать, и я пробовал множество способов без какого-либо успеха. В основном то, что я пытаюсь сделать в своем обратном вызове ajax, загружает мою функцию предварительного загрузчика в div #neato_form с 10-секундной задержкой, а затем переводит ее в вариант 2, который является шагом 2 в моей форме.
Я включил свой обратный вызов ajax, так как это основная проблема. Вместе с моя форма и функция отправки на случай, если я сделал там что-то не так.
Мы будем очень признательны за любые предложения.
Команды Ajax
function neato_form_ajax_callback($form, &$form_state)
{
$commands = array();
$commands[] = array(
'command' => 'mortgage_response',
'leadstatus' => 'success',
);
$commands[] = ajax_command_replace('#neato_form', preloader());
$commands[] = ajax_command_invoke(NULL, "preloader");
if($commands[0]['leadstatus'] == 'success'){
$commands[] = ajax_command_replace('#neato_form', $form_state['step2']);
}
return array('#type' => 'ajax', '#commands' => $commands);
}
Форма и функция отправки
function neato_form($form, &$form_state)
{
$form_state['step'] = isset($form_state['step']) ? $form_state['step'] : 1;
$form['#prefix'] = '<div id="neato_form">';
$form['#suffix'] = '</div>';
switch($form_state['step'])
{
// Step 1
case 1:
$default_value = '';
if(isset($form_state['values']['step_1']))
{
$default_value = $form_state['values']['step_1'];
}
elseif(isset($form_state['storage']['step_1']))
{
$default_value = $form_state['storage']['step_1'];
}
$form['step_1'] = array
(
'#type' => 'textfield',
'#title' => t('Step 1'),
'#required' => TRUE,
'#default_value' => $default_value,
);
break;
// Step 2
case 2:
$default_value = '';
if(isset($form_state['values']['step_2']))
{
$default_value = $form_state['values']['step_2'];
}
elseif(isset($form_state['storage']['step_2']))
{
$default_value = $form_state['storage']['step_2'];
}
$form['step_2'] = array
(
'#type' => 'textfield',
'#title' => t('Step 2'),
'#required' => TRUE,
'#default_value' => $default_value,
);
break;
// Step 3
case 3:
$default_value = '';
if(isset($form_state['values']['step_3']))
{
$default_value = $form_state['values']['step_3'];
}
elseif(isset($form_state['storage']['step_3']))
{
$default_value = $form_state['storage']['step_3'];
}
$form['step_3'] = array
(
'#type' => 'textfield',
'#title' => t('Step 3'),
'#required' => TRUE,
'#default_value' => $default_value,
);
break;
}
$form['buttons'] = array
(
'#type' => 'container',
);
$form['buttons']['submit'] = array
(
'#type' => 'submit',
'#value' => t('Submit'),
'#ajax' => array
(
'wrapper' => 'neato_form',
'callback' => 'neato_form_ajax_callback',
),
);
return $form;
}
function neato_form_back_submit($form, &$form_state)
{
$form_state['step']--;
$form_state['rebuild'] = TRUE;
}
function neato_form_submit($form, &$form_state)
{
$step = $form_state['step'];
$form_state['storage']['step_' . $step] = $form_state['values']['step_' . $step];
if(isset($form_state['values']['forward']) && $form_state['values']['op'] == $form_state['values']['forward'])
{
$form_state['step']++;
}
elseif(isset($form_state['values']['submit']) && $form_state['values']['op'] == $form_state['values']['submit'])
{
$items = array($form_state['storage']['step_1'], $form_state['storage']['step_2'], $form_state['storage']['step_3']);
drupal_set_message(t('My !values', array('!values' => theme('item_list', array('items' => $items)))));
$form_state['step'] = 1;
$form_state['storage'] = array();
}
$form_state['rebuild'] = TRUE;
}
1 answers
Я думаю, вам следует прикрепить свою пользовательскую функцию предварительного загрузчика ajax к форме следующим образом:
$form['#attached']['js'] = array(
array(
'type' => 'file',
'data' => drupal_get_path('module', 'MY_MODULE') . '/js/ajax_preloader.js',
),
);
Ajax_preloader.js
(function($) {
Drupal.behaviors.events = {
attach: function(context, settings) {
$('#steps-form', context).ajaxStart(function() {
// ...
});
$('#steps-form', context).ajaxSuccess(function() {
// ...
});
}
};
})(jQuery);
В качестве альтернативы вы можете создать свою собственную команду (пример Mypreloaderexample)
(function($, Drupal) {
Drupal.ajax.prototype.commands.myPreloaderExample = function(ajax, response, status) {
$('#steps-form').ajaxStart(function() {
//...
});
$('#steps-form').ajaxSuccess(function() {
// ...
});
};
}(jQuery, Drupal));
Я не уверен, какова ваша цель, но если вы собираетесь создать многоступенчатую форму ajax со следующими функциями:
- Показывать только текущий элемент формы
- Сохранить все ранее предоставленные значения (разрешить предварительный просмотр всех значений не теряя их)
Вы можете создать такую форму следующим образом:
/**
* An example of steps form.
*/
function steps_form($form, &$form_state) {
// Because we have many fields with the same values, we have to set
// #tree to be able to access them.
$form['#tree'] = TRUE;
$form['steps_fieldset'] = array(
'#type' => 'fieldset',
'#title' => t('Steps form'),
// Set up the wrapper so that AJAX will be able to replace the fieldset.
'#prefix' => '<div id="steps-fieldset-wrapper">',
'#suffix' => '</div>',
);
$form['steps_fieldset']['actions'] = array(
'#type' => 'actions'
);
// Build the fieldset with the proper number of steps.
// Use $form_state['step'] to determine the number of textfields to build.
if (empty($form_state['step'])) {
$form_state['step'] = 1;
}
// An array with form values.
if (empty($form_state['storage'])) {
$form_state['storage'] = array();
}
// Define the number of steps.
$form_state['steps_number'] = 3;
// build all textfields with steps
for ($i = 0; $i < $form_state['step']; $i++) {
// set the type of each previous form item as a hidden. Only last step will be shown.
$type = ($i == ($form_state['step']-1)) ? 'textfield' : 'hidden';
// get the default value of step.
$default_value = isset($form_state['storage'][$i]) ? $form_state['storage'][$i] : '';
$form['steps_fieldset']['step'][$i] = array(
'#type' => $type,
'#title' => t('Step') . ' ' . ($i+1),
'#required' => FALSE,
'#default_value' => $default_value,
);
}
// The next step button.
if ($form_state['step'] != $form_state['steps_number']) {
$form['steps_fieldset']['actions']['add_step'] = array(
'#type' => 'submit',
'#weight' => '1',
'#value' => t('Next step'),
'#submit' => array('steps_form_add_one'),
'#ajax' => array(
'callback' => 'steps_form_callback',
'wrapper' => 'steps-fieldset-wrapper',
),
);
}
// The previous step button.
if ($form_state['step'] > 1) {
$form['steps_fieldset']['actions']['remove_step'] = array(
'#type' => 'submit',
'#weight' => '0',
'#value' => t('Previous step'),
'#submit' => array('steps_form_remove_one'),
'#ajax' => array(
'callback' => 'steps_form_callback',
'wrapper' => 'steps-fieldset-wrapper',
),
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
$form['#attached']['js'] = array(
array(
'type' => 'file',
'data' => drupal_get_path('module', 'MY_MODULE') . '/js/ajax_preloader.js',
),
);
return $form;
}
/**
* Callback for both ajax-enabled buttons.
*
* Selects and returns the fieldset with all values in it.
*/
function steps_form_callback($form, $form_state) {
$commands = array();
// return the form
$commands[] = ajax_command_html('#steps-fieldset-wrapper', render($form['steps_fieldset']));
// add your custom ajax command
$commands[] = array(
'command' => 'myPreloaderExample',
// define some custom variables if you need to
'someValue' => 'some value',
);
return array('#type' => 'ajax', '#commands' => $commands);
}
/**
* Submit handler for the "add-one-more" button.
*
* - save the form value, so the user will be able to preview all previously provided values without loosing them.
* - increments the step counter.
* - rebuild the form.
*/
function steps_form_add_one($form, &$form_state) {
$form_state['storage'][$form_state['step']-1] = $form_state['input']['steps_fieldset']['step'][$form_state['step']-1];
if ($form_state['step'] < $form_state['steps_number']) {
$form_state['step']++;
}
$form_state['rebuild'] = TRUE;
}
/**
* Submit handler for the "remove one" button.
*
* Decrements the step counter and causes a form rebuild.
*/
function steps_form_remove_one($form, &$form_state) {
if ($form_state['step'] > 1) {
$form_state['step']--;
}
$form_state['rebuild'] = TRUE;
}
/**
* Final submit handler.
*
* Reports what values were finally set.
*/
function steps_form_submit($form, &$form_state) {
$output = t('All my values: @steps',
array('@steps' => implode(', ', $form_state['values']['steps_fieldset']['step'])) );
drupal_set_message($output);
}
Результаты