Drupal 7 node_save() 导致 AJAX 失败

问题描述 投票:0回答:3

我创建了仅附加两个字段的自定义节点表单。每个字段都有自己的“保存”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'] = '<div id="wrapper-field-test-1">';
  $form['field_test_1']['#suffix'] = '</div>';

  // 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'] = '<div id="wrapper-field-test-2">';
  $form['field_test_2']['#suffix'] = '</div>';

  // 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'] = '<div id="wrapper-' . str_replace('_', '-', $field_name) . '">';
  $form[$field_name]['#suffix'] = '</div>';

  // return the confirmation message
  return $form[$field_name];
}

代码运行完美,只是

node_save($node)
导致
The content on this page has either been modified by another user, or you have already submitted modifications using this form. As a result, your changes cannot be saved.
错误。

如果我删除它,就没有错误。但我需要保存节点并触发所有钩子。

php ajax drupal drupal-7
3个回答
0
投票

我认为此行引起的问题:

 // process the form
 mymodule_custom_form_submit($form, $form_state);

在你的ajax函数中,尝试在你的ajax函数中使用node_save。 mymodule_custom_form_submit 是通常使用的常规钩子。似乎是同时进行多个保存过程。


0
投票

不知道你解决了没,我也遇到过类似的情况。

我避免了错误:此页面上的内容已被修改...,修改$form_state中的

changed
值。在您的提交功能中:
mymodule_custom_form_submit
node_save($node)
之后,添加此行:

$form_state['input']['changed'] = $node->changed;

-1
投票

Drupal 7 完整的 Save & Stay 回调函数,请添加表单包装:

function <MODULE_NAME>_node_ajax_save_callback($form, &$form_state){

  // If error, return form.
  if (form_get_errors()) {
    return $form;
  }

  node_form_submit($form, $form_state);
  $form['changed']['#value'] = $form_state['node']->changed;

  return $form;
}
© www.soinside.com 2019 - 2024. All rights reserved.