Чи можливо відображення робочої форми віджетів поля самостійно?


21

Мені цікаво вставити форму віджету поля з боку контексту всієї форми редагування вузла.

Я раніше відображав повні форми, використовуючи drupal_get_form, але це, схоже, не застосовується для одиночних польових форм.

Чи можливо відображення робочої форми віджету поля? Який був би найкращий спосіб зробити це?

Як польові віджети, так і "нормальні" форми здаються дуже схожими, тому, якщо це неможливо, що потрібно для "зміни" форми віджетів на нормальну форму?

Це питання, схоже, запитує щось подібне, але я не розумію відповіді. Ця відповідь вказує за допомогою гачка_field_widget_form_alter ; що я не розумію, це як відобразити форму поля, а не як зачепити її після її створення.

Відповіді:


18

VBO робить щось подібне в modify.action.inc:

$form_key = 'bundle_' . $bundle_name;
$form[$form_key] = array(
  '#type' => 'fieldset',
  '#title' => $label,
  '#parents' => array($form_key),
);  
field_attach_form($context['entity_type'], $entity, $form[$form_key], $form_state, LANGUAGE_NONE);  

Отже, вам потрібен тип сутності, сутність (яка може бути пустим об'єктом із лише встановленим ключем пакета, саме для цього використовується), форма додавання віджетів та мова. Якщо ви хочете вставити віджети глибше у форму (не в $ формі, а в $ form [$ form_key], як я, або навіть глибше), то для цього масиву форм потрібно встановити #parents.

Звичайно, зауважте, що це вбудовує віджети всіх полів, що належать до цього типу сукупності та пакету. Ось так було написано функції прикріплення. Якщо обійти, що вимагатиме від вас винаходити досить багато коду; дивіться фактичний код, який робить важкий підйом. Що я роблю, це пройти через екземпляри поля, отримати кожен $ field_name, і якщо цей тип поля мене не цікавить, я встановив, $form[$form_key][$field_name]['#access'] = FALSE; який ховає ці віджети від погляду.

EDIT: Гаразд, у ctools є ctools_field_invoke_field (), який теоретично міг би дозволяти вам працювати на основі поля. Я ніколи цього не використовував. Текст вище - це мій безпосередній досвід.


Дивовижна відповідь. Більшу частину дня я провів, працюючи з цим, і це працювало так, як я хотів. Баунті нагороджений, і я рекомендую ОП прийняти це як правильну відповідь. Я в кінцевому підсумку створив фіктивний тип вмісту, щоб я міг керувати своїми полями, як і будь-який інший тип вмісту, замість того, щоб налаштування, #access = FALSEздавалося, хитке в цьому контексті.
Летаріон

Дякуємо, що підтвердили те, чого я побоювався: що віджет одного поля практично не може бути використаний самостійно.
SMTF

7

Я активно використовував функцію, запропоновану ttk, але думаю, що нещодавнє оновлення зіпсувало речі ...

Ось нова версія попереднього рішення, яка добре працює з Drupal 7.22 та ctools 7.x-1.3.

Отже, як і в попередньому дописі, ви називаєте свою власну функцію так:

my_field_attach_form('field_body', 'node', 'blog',  $node, $form, $form_state, LANGUAGE_NONE);

Зауважте, що тепер сукупність сутності є параметром. Я зробив це, тому що я також використовував цю функцію для редагування користувачів. Таким чином, він також може бути використаний для терміна таксономії або будь-якого іншого суб'єкта.

І my_field_attach_formвизначається як:

function my_field_attach_form($field_name, $entity_type, $bundle, $entity, &$form, &$form_state, $langcode = NULL) {

  // Set #parents to 'top-level' if it doesn't exist.
  $form += array('#parents' => array());

  // If no language is provided use the default site language.
  $options = array(
    'language' => field_valid_language($langcode),
    'default' => TRUE,
  );

  // Append to the form
  ctools_include('fields');
  $field_instance = field_info_instance($entity_type, $field_name, $bundle);
  $form += (array) ctools_field_invoke_field($field_instance, 'form', $entity_type, $entity, $form, $form_state, $options);
}

Ця функція заощадила мені багато часу, сподіваюся, що буде і для вас!


5

Ось рішення за допомогою ctools_field_invoke_field()методу. У своїй спеціальній функції форми додайте:

$form = array();
$node = new stdClass();
$node->type = 'blog';
my_field_attach_form('field_body', 'node', $node, $form, $form_state, LANGUAGE_NONE);

де my_field_attach_formфункція визначена як

function my_field_attach_form($field_name, $entity_type, $entity, &$form, &$form_state, $langcode = NULL) {
  // Set #parents to 'top-level' if it doesn't exist.
  $form += array('#parents' => array());

  // If no language is provided use the default site language.
  $options = array(
    'language' => field_valid_language($langcode),
    'default' => TRUE,
  );
  module_load_include("inc","ctools","includes/fields");
  $form += (array) ctools_field_invoke_field($field_name, 'form', $entity_type, $entity, $form, $form_state, $options);
}

Зауважте, що для вашого сайту потрібно включити ctools. Дуже погано, що Drupal за замовчуванням не включає в себе функцію помічника.


2

Мені не вдалося змусити метод ctools працювати, і я вирішив зробити це так.

Цей код знаходитиметься всередині функції форми, тому $ form та $ form_state будуть передані вже.

function form_function($form, &$form_state) {

Спочатку створіть порожній вузол типу, у якому є поле, яке ви хочете відобразити.

    $entity = new stdClass();
    $entity->title = "Temp Object";
    $entity->type = "node_type";
    node_object_prepare($entity);

Я скопіював змінні форми, щоб я не зациклювався на оригіналі.

    $temp_form       = $form;
    $temp_form_state = $form_state;
    field_attach_form("node", $entity, $temp_form, $temp_form_state);

Вийміть шукане поле та додайте його до форми.

    $form["field"] = $temp_form["existing_field"];
}

Я використовував цей метод, щоб відобразити віджет вибору таксономії, віджет прапорців таксономії та віджет Hierarchical Select у спеціальній формі. (Віджет таксономії автоматично заповнює, але видає помилку при надсиланні)

Нарешті візуалізуйте та надрукуйте

drupal_render(drupal_get_form("form_function"))

Здається, це простий спосіб використовувати польовий віджет у спеціальній формі. Однак це залежить від наявного пакету. У моєму випадку я використовую фіктивний тип вмісту, де я створюю та конфігурую поля за потребою. Це трохи гакітно, але необхідно і для інших методів. Зауважимо: ctools_field_invoke_field()описаний вище метод також працює.
Бернхард Фюрст

0

Я створив форми з індівідуальних полів, використовуючи

field_default_form('entity_type', $entity, $field,$field_instance,LANGUAGE_NONE,$default_value, $form, $form_state);

це має повернути необхідну форму віджетів, яку можна використовувати в будь-якій формі

 $custom_form['form_element_to_display'] = field_default_form('entity_type', $entity, $field,$field_instance,LANGUAGE_NONE,$default_value, $custom_form, $custom_form_state);

Щоб отримати значення для вищевказаного параметра 2, використовуйте:

$field = field_info_field($field_name);
$field_instance = field_info_instance('node', $field_name, $node_type);

Для інших параметрів ви можете перевірити посилання api тут

Це повертає форму віджетів за замовчуванням, визначену в полі типів вмісту.

Сподіваюся, це комусь допоможе :)

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