Я создал специальную форму узла, к которой прикреплено только два поля. Каждое поле имеет собственную кнопку «Сохранить» AJAX. При нажатии кнопки «Сохранить» все происходит так, как если бы это была отправка формы узла по умолчанию. Вот полный код:
/**
* Form;
*/
function mymodule_custom_form($form, &$form_state) {
$node = node_load(123);
$node->langcode = entity_language('node', $node);
// Store node object in form state
if (!isset($form_state['node'])) {
if (!isset($node->title)) {
$node->title = NULL;
}
node_object_prepare($node);
$form_state['node'] = $node;
}
else {
$node = $form_state['node'];
}
// Basic node information.
// These elements are just values so they are not even sent to the client.
$properties = array('nid', 'vid', 'uid', 'created', 'type', 'language');
foreach ($properties as $key) {
$form[$key] = array(
'#type' => 'value',
'#value' => isset($node->$key) ? $node->$key : NULL,
);
}
// Changed must be sent to the client, for later overwrite error checking.
$form['changed'] = array(
'#type' => 'hidden',
'#default_value' => isset($node->changed) ? $node->changed : NULL,
);
// TEST 1 field
field_attach_form('node', $node, $form, $form_state, $node->langcode, array(
'field_name' => 'field_test_1'
));
// Set the form prefix and suffix to support AJAX
$form['field_test_1']['#prefix'] = '';
$form['field_test_1']['#suffix'] = '';
// the submit button
$form['field_test_1']['save'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#name' => 'button-field-test-1',
'#ajax' => array(
'callback' => 'mymodule_custom_form_ajax_submit',
'wrapper' => 'wrapper-field-test-1',
'method' => 'replace',
'effect' => 'fade',
)
);
// TEST 2 field
field_attach_form('node', $node, $form, $form_state, $node->langcode, array(
'field_name' => 'field_test_2'
));
// Set the form prefix and suffix to support AJAX
$form['field_test_2']['#prefix'] = '';
$form['field_test_2']['#suffix'] = '';
// the submit button
$form['field_test_2']['save'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#name' => 'button-field-test-2',
'#ajax' => array(
'callback' => 'mymodule_custom_form_ajax_submit',
'wrapper' => 'wrapper-field-test-2',
'method' => 'replace',
'effect' => 'fade',
)
);
return $form;
}
/**
* Form validate;
*/
function mymodule_custom_form_validate($form, &$form_state) {
$field_name = reset($form_state['triggering_element']['#parents']);
// Validate only the stuff we need
$fields = array(
'field_test_1',
'field_test_2'
);
foreach ($fields as $field => $bundle) {
if ($field_name != $field) {
unset($form_state['values'][$field], $form_state['input'][$field]);
}
}
// $form_state['node'] contains the actual entity being edited, but we must
// not update it with form values that have not yet been validated, so we
// create a pseudo-entity to use during validation.
$node = (object) $form_state['values'];
node_validate($node, $form, $form_state);
entity_form_field_validate('node', $form, $form_state);
}
/**
* Form submit;
*/
function mymodule_custom_form_submit($form, &$form_state) {
// Execute all submit functions
$node = $form_state['node'];
entity_form_submit_build_entity('node', $node, $form, $form_state);
node_submit($node);
foreach (module_implements('node_submit') as $module) {
$function = $module . '_node_submit';
$function($node, $form, $form_state);
}
// Save the node
node_save($node);
$form_state['values']['nid'] = $node->nid;
$form_state['nid'] = $node->nid;
}
/**
* Form ajax submit;
*/
function mymodule_custom_form_ajax_submit($form, &$form_state) {
$field_name = reset($form_state['triggering_element']['#parents']);
// validate the form
drupal_validate_form('mymodule_custom_form', $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[$field_name];
}
// process the form
mymodule_custom_form_submit($form, $form_state);
// Show the processing box
$form[$field_name] = array('#markup' => 'Thanks!');
$form[$field_name]['#prefix'] = '';
$form[$field_name]['#suffix'] = '';
// return the confirmation message
return $form[$field_name];
}
Код работает отлично, за исключением того, что node_save($node) вызывает сообщение Содержимое на этой странице либо было изменено другим пользователем, либо вы уже отправили изменения, используя эту форму. В результате ваши изменения не могут быть сохранены. ошибка.
Нет ошибок, если я удалю их. Но мне нужно сохранить узел и активировать все перехватчики.
Я создал специальную форму узла, к которой прикреплено только два поля. Каждое поле имеет собственную кнопку «Сохранить» AJAX. При нажатии кнопки «Сохранить» все происходит так, как если бы это была отправка формы узла по умолчанию. Вот полный код:
// Store node object in form state if (!isset($form_state['node'])) { if (!isset($node->title)) { $node->title = NULL; } node_object_prepare($node); $form_state['node'] = $node; } else { $node = $form_state['node']; }
// Basic node information. // These elements are just values so they are not even sent to the client. $properties = array('nid', 'vid', 'uid', 'created', 'type', 'language'); foreach ($properties as $key) { $form[$key] = array( '#type' => 'value', '#value' => isset($node->$key) ? $node->$key : NULL, ); }
// Changed must be sent to the client, for later overwrite error checking. $form['changed'] = array( '#type' => 'hidden', '#default_value' => isset($node->changed) ? $node->changed : NULL, );
// TEST 1 field field_attach_form('node', $node, $form, $form_state, $node->langcode, array( 'field_name' => 'field_test_1' ));
// Set the form prefix and suffix to support AJAX $form['field_test_1']['#prefix'] = ''; $form['field_test_1']['#suffix'] = '';
/** * Form validate; */ function mymodule_custom_form_validate($form, &$form_state) { $field_name = reset($form_state['triggering_element']['#parents']);
// Validate only the stuff we need $fields = array( 'field_test_1', 'field_test_2' ); foreach ($fields as $field => $bundle) { if ($field_name != $field) { unset($form_state['values'][$field], $form_state['input'][$field]); } }
// $form_state['node'] contains the actual entity being edited, but we must // not update it with form values that have not yet been validated, so we // create a pseudo-entity to use during validation. $node = (object) $form_state['values']; node_validate($node, $form, $form_state); entity_form_field_validate('node', $form, $form_state); }
/** * Form submit; */ function mymodule_custom_form_submit($form, &$form_state) { // Execute all submit functions $node = $form_state['node']; entity_form_submit_build_entity('node', $node, $form, $form_state);
/** * Form ajax submit; */ function mymodule_custom_form_ajax_submit($form, &$form_state) { $field_name = reset($form_state['triggering_element']['#parents']);
// validate the form drupal_validate_form('mymodule_custom_form', $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[$field_name]; } // process the form mymodule_custom_form_submit($form, $form_state);
// Show the processing box $form[$field_name] = array('#markup' => 'Thanks!'); $form[$field_name]['#prefix'] = ''; $form[$field_name]['#suffix'] = '';
// return the confirmation message return $form[$field_name]; } [/code]
Код работает отлично, за исключением того, что node_save($node) вызывает сообщение Содержимое на этой странице либо было изменено другим пользователем, либо вы уже отправили изменения, используя эту форму. В результате ваши изменения не могут быть сохранены. ошибка.
Нет ошибок, если я удалю их. Но мне нужно сохранить узел и активировать все перехватчики.