Импорт данных из одной формы в другую с помощью AJAX

Drupal 7 и улучшенные Form API делает использование AJAX очень простым. Вы можете добавлять, заменять или удалять элементы форм с помощью AJAX, не запачкав свои руки в javascript коде.

Возьмем пример из жизни.
У нас на сайте есть тип содержимого "Резюме"(resume) и профиль "Профессиональная информация"(prof_info) в Profile2. В этом профиле содержится информация, к примеру, об опыте работы в поле 'field_work_experience'. В типе содержимого "Резюме" так же есть поле 'field_work_experience'. И мы не хотим, что бы пользователь ещё раз вводил уже введённую информацию. Для эго над полем 'field_work_experience' в типе содержимого "Резюме" мы поместим кнопку, при нажатии на который данные из профиля вставятся в нашу форму.

Ниже приведен код, реализующий данный функционал:

  1. /**
  2.  * Implements hook_form_FORM_ID_alter().
  3.  *
  4.  * Форма создания/редактирования типа материала "Резюме".
  5.  */
  6. function formsd7_form_resume_node_form_alter(&$form, &$form_state, $form_id) {
  7. // Загрузка профиля текущего пользователя.
  8. $uid = $form['uid']['#value'];
  9. $author = user_load($uid);
  10. $profile = profile2_load_by_user($author, 'prof_info');
  11.  
  12. // Кнопка позволяющая импортировать данные о опыте работы из профиля в форму.
  13. // Проверка сработает только для нод с нейтральным языком.
  14. if (array_key_exists('und', $profile->field_work_experience)) {
  15. // Оборачивание элемента в блок, что бы можно было работать с AJAX.
  16. $form['field_work_experience']['#prefix'] = '<div id="field-work-experience-wrapper">';
  17. $form['field_work_experience']['#suffix'] = '</div>';
  18.  
  19. $form['field_work_experience']['import_work_experience'] = array(
  20. '#type' => 'submit',
  21. '#value' => 'Импортировать опыт работы из профиля',
  22. '#description' => 'Предупреждение: все ранее введенные данные в поле Опыт работы будут удалены!',
  23. '#weight' => -20,
  24. '#attributes' => array('class' => array('field-add-more-submit')),
  25. // Не производить валидацию когда нажата кнопка!
  26. '#limit_validation_errors' => array(),
  27. '#ajax' => array(
  28. 'callback' => 'formsd7_js_import_work_experience',
  29. 'wrapper' => 'field-work-experience-wrapper',
  30. 'effect' => 'fade',
  31. 'method' => 'replace',
  32. ),
  33. );
  34. }
  35. }
  36.  
  37. /**
  38.  * Вызов при обработки AJAX запроса с формы составления резюме.
  39.  */
  40. function formsd7_js_import_work_experience($form, $form_state) {
  41. $field_collection = 'field_work_experience';
  42. // Загрузка поле через дополнительную функцию. Это позволит повторять этот процесс для других полей.
  43. $element = formsd7_js_import_field_collection($field_collection, $form, $form_state);
  44.  
  45. return $element;
  46. }
  47.  
  48. /**
  49.  * Получаем срендеренный элемент формы.
  50.  */
  51. function formsd7_js_import_field_collection($field_collection, $form, $form_state) {
  52. // Загрузка профиля текущего пользователя.
  53. $uid = $form['uid']['#value'];
  54. $author = user_load($uid);
  55.  
  56. // Нужно подключить объявление profile формы из profile2.
  57. module_load_include('inc', 'profile2_page', 'profile2_page');
  58. // Загрузить объект профиля
  59. $profile2 = profile2_by_uid_load($uid, 'prof_info');
  60. // Генерирует форму. Также можно использовать drupal_get_form для форм не использующих entity.
  61. $profile2_form = entity_ui_get_form('profile2', $profile2, 'edit');
  62.  
  63. if (isset($profile2_form)) {
  64. // Возвращаем срендеренный элемент формы из профиля.
  65. return $profile2_form['profile_prof_info'][$field_collection];
  66. }
  67. }

Другой пример где может понадобится данные действия, это перенос данных некоторых данных из уже созданного резюме в новое.

При написании статьи и кода использовались данные из Import form values from one form to another via AJAX

Версия Drupal: