Автозаповнення полів на основі іншого поля


10

У мене дуже складна ситуація, коли мені потрібна порада. У мене є тип вмісту my_content, до якого приєднано поле для збору полів field_mycollection, у якому є поле посилання сутності, що посилається на користувача field_my_userreference, телефонне поле field_my_phone, текстове поле field_my_textта інше текстове поле field_my_anothertext.

My Content
|_ field_mycollection
   |_ field_my_userreference
   |_ field_my_phone
   |_ field_my_text
   |_ field_my_anothertext

У сутності користувача також є поля field_my_phone, field_my_textа field_my_yetanothertextостанній має іншу назву машини.

Що я хочу зробити, якщо у my_contentформі редагування / додавання у field_my_userreferenceвибраному користувачеві інші поля повинні бути автоматично заповнені з даних вибраного користувача. Автоматично заповнені поля все ще мають редагуватися.

Як я міг досягти цієї мети? Я хотів би зробити це, якщо можливо, з деяким кодуванням, використовуючи hook_form_FORM_ID_alter().


Потрібно, щоб це сталося в прямому ефірі чи на збереженні?
Молот

Жити на формі. Я вже реалізував це, окрім збереження, що дані будуть взяті від сутності користувача, якщо їх залишити порожніми. Але насправді те, що мені потрібно на формі :(
Елін Й.

Гаразд, поставив мою відповідь.
Молот

Відповіді:


11

Якщо ви хочете, щоб це сталося в прямому ефірі, і всі поля вже є у формі, найбезпечнішим способом було б скористатися, hook_form_FORM_ID_alter()щоб додати наступне до форми:

$form['#attached']['js'] = array(
  drupal_get_path('module', 'module_name') . '/js/copy_field_value.js',
);

Потім у copy_field_value.jsстворенні поведінки:

(function($) {
  Drupal.behaviors.moduleNameCopyFieldValue = {
    attach: function (context, settings) {

      // Repeat this for all fields as needed
      $('#source', context).on('blur', function () { 
        // above you can use change instead of blur if element is not changed by another js
        if (!$('#destination').val() || 0 === $('#destination').val().length) {
          $('#destination').val($(this).val());
          // wrap line above in "if no value" like I did, or other condition you like
        }
      });
      // end of "repeat this"
    }
  };
})(jQuery);

Ви також hook_form_FORM_ID_alter()можете додати #ajaxпараметр до вихідного поля, але це зробить вашу форму для виклику сервера на кожній копії поля. Якщо вам потрібно насправді запитувати базу даних, це шлях. Було б досить широко описати це заново тут. Вам потрібно змінити $form_state["input"]масив, щоб оновити реальні значення, які бачив користувач. Виконайте це у формі створення форми, загорнувши їїisset щоб уникнути повідомлень.

Якщо ваш елемент форми $form["something"]["something"]["element"], його значення буде $form_state["input"]["something"]["something"]["element"]- і ви можете встановити його в hook_form_alterпорядку, просто не забудьте взяти і те, $formі $form_stateпосилання.

Примітка : .on()метод був доданий у jQuery 1.7, тому вам буде потрібно оновлення jQuery, щоб використовувати цю відповідь безпосередньо, або перекласти мій код на використання .change()чи .blur()метод.


Велике спасибі за інструкції! Я не дуже добре використовую JS API Drupal. Чи пояснюєте ви, як я отримую значення поля від сутності користувача? Наприклад, якщо вибрано користувача, як я можу заповнити наступні поля інформацією цього користувача?
Елін Й.

1
@ ЕлінЙ. хитрість тут - не турбота про фон PHP. Просто визначте параметри ідентифікаторів <input>тегів, використовуючи Firebug або подібний інструмент для улюбленого браузера. Або скористайтеся будь-яким іншим селектором jQuery. Це відбудеться лише в браузері, тому у вас є на екрані те, що у вас є. З іншого боку, якщо вам потрібно насправді запитувати базу даних (здається, я це пропустив), #ajaxце шлях. Але це було б досить широко. Вам потрібно змінити $form_state["values"]масив, щоб оновити реальні значення, які бачив користувач. Виконайте це у формі створення форми, загортаючи її, issetщоб уникнути повідомлень.
Молот

Ще раз дякую @ Mołot, я спробую реалізувати це завтра, а може, сьогодні ввечері. Здається, мені знадобиться кілька годин, щоб він справді працював, якщо не більше.
Елін Й.

@ ЕлінЙ. удачі, не соромтеся повернутися з додатковими питаннями та зв’язати їх тут у коментарях, якщо вони пов’язані. Трохи оновлена ​​відповідь, btw.
Молот

1
Гаразд, я трохи експериментую і напишу свої враження.
Елін Й.

4

Ви можете зробити це за допомогою обчислюваного модуля поля

Computed Field - це дуже потужний модуль поля CCK, який дозволяє додавати власні "обчислювані поля" до типів вмісту. Ці обчислені поля заповнені значеннями, які ви визначаєте за допомогою PHP-коду. Ви можете звертатися до всього, що доступне для Drupal, включаючи інші поля, поточного користувача, таблиці баз даних, ви їх називаєте. (Поки відчуваєте потужність? :)) Ви також можете вибрати, чи потрібно зберігати обчислювані значення поля в базі даних разом з іншими полями вмісту або їх "обчислювати" під час руху під час перегляду вузлів. (Хоча вам слід зазначити, що для використання Views потрібні значення, що зберігаються в базі даних.) Це поле буквально ножем швейцарської армії полів CCK. Тож починайте готувати свої значення на основі PHP!


Дякуємо за швидку відповідь. Це звучить дуже перспективно. Хоча я не хочу встановлювати модуль для цього, а просто написати якийсь код, оскільки мені потрібна така функціональність лише в цій формі, а фактична система вже завелика, і багато модулів встановлено для різноманітних функцій.
Елін Й.

По-друге, чи можна за допомогою цього модуля користувачеві, який створює або редагує вузол, переосмислити автоматично заповнені поля вручну та зберегти? Таким чином, в об'єкті користувача та my_content різні значення зберігаються.
Елін Й.

Це залежало б від способу встановлення
4life

Спасибі @ 4life, я також спробую це зробити, якщо я не можу досягти цього з кодуванням, користуючись інструкціями Mołot.
Елін Й.

2

Я хочу опублікувати, як я цього досяг, завдяки чудовій допомозі @ Mołot.

  1. Реалізовано гачок_форма_FORM_ID_alter () .
  2. Додано обгортковий поділ навколо колекції поля.
  3. Оскільки колекція моїх полів є полем з великим значенням, перегляньте його і встановіть #ajaxвластивість для поля field_my_userreference.
  4. Створено функцію зворотного дзвінка, яка просто повертає елемент колекції поля назад.
  5. Поставлено прапорець у здійсненні гачки_form_FORM_ID_alter (), якщо для колекції полі встановлено $ form_state. Якщо так, отримайте значення від сутності користувача та заповніть поля введення форми цими значеннями.

Мій код виглядає так:

function MYMODULE_form_my_content_node_form_alter(&$form, &$form_state, $form_id) {
  $form['field_mycollection']['#prefix'] = '<div id="mycollection-wrapper">';
  $form['field_mycollection']['#suffix'] = '</div>';
  foreach ($form['field_mycollection']['und'] as $key => $fc_mycollection) {
    if (is_numeric($key)) {
      $form['field_mycollection']['und'][$key]['field_my_userreference']['und']['#ajax'] = array(
        'callback' => 'MYMODULE_mycollection_callback',
        'wrapper' => 'mycollection-wrapper',
      );
      if (isset($form_state['values']['field_mycollection']['und'][$key]['field_my_userreference']['und'][0]['target_id'])) {
        $user_wrapper = entity_metadata_wrapper('user', $form_state['values']['field_mycollection']['und'][$key]['field_my_userreference']['und'][0]['target_id']);
        $form_state['input']['field_mycollection']['und'][$key]['field_my_text']['und'][0]['value'] = $user_wrapper->field_my_text->value() ? $user_wrapper->field_my_text->value() : '';
        $form_state['input']['field_mycollection']['und'][$key]['field_my_anothertext']['und'][0]['value'] = $user_wrapper->field_my_text->value() ? $user_wrapper->field_my_yetanothertext->value() : '';
      }
    }
  }
}

function MYMODULE_mycollection_callback($form, &$form_state) {
  return $form['field_mycollection'];
}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.