AJAX дзвінки в плагіні типу вмісту CTools?


10

Я будую тип вмісту панелей CTools (тобто те, що ви вставляєте на панелі, додаючи вміст, а не тип вузла), і я намагаюся використовувати #ajaxатрибут елемента форми для встановлення деяких значень за замовчуванням. Дивіться код нижче.

Це my_module_content_type_edit_form($form, &$form_state), до речі, всередині виклику типу вмісту .

  $form['link_type'] = array(
    '#type' => 'radios',
    '#title' => t('Link Type'),
    '#ajax' => array(
      'callback' => 'my_module_set_target'
    ),
    '#default_value' => empty($conf['link_type']) ? '_blank' : $conf['link_type'],
    '#options' => array('none'=>t('No Link'), 'internal'=>t('Internal Link'), 'external'=>t('External Link'), 'document'=>t('Document Link')),
  );

Мій зворотній дзвінок такий.

function my_module_set_target($form, $form_state) {
  watchdog("Test", "Testing callback", array(), WATCHDOG_ALERT);
  $form['link_target']['#default_value'] = '_parent';

  return $form['link_target']['#default_value'];
}

Незалежно від того, чи справді повернення, яке я пропоную, справді спрацює, watchdog()навіть не працює.

Я знаю, що CTools робить якісь дивні речі з AJAX, але це не може бути таким дивним. Чи маєте ви якесь уявлення про те, як би я робив те, що хочу зробити?

Дякую!

Як варіант: Як встановити значення за замовчуванням на основі значення попереднього параметра форми?

Я придумав, як це зробити, але це трохи хакітно - ви створюєте нові поля форм для кожної вилки залежності. Потім ви можете об'єднати цілі разом hook_content_type_edit_form_submit(), використовуючи те, що відповідає значенню, вибраному для компонента, який спочатку розщедрив усе.

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

Оновлення. Здається, ви також не можете робити речі з #attached.

$form['link'][$i] = array(
  '#type' => 'fieldset',
  '#title' => t('Link #@num', array('@num' => $i)),
  '#collapsible' => TRUE,
  '#collapsed' => TRUE,
  '#attached' => array(
    'js' => array(
      'alert("Yay.");', 'inline'
    ),
  )
);

Будучи розробником Drupal типу "Панелі для всього", я думаю, що можу знайти користь для цього і в майбутньому, тому я додав щедрості, давайте подивимося, що відбувається.
Летаріон

Нічого собі, цей щедрість прийшов і пройшов навіть без коментаря (Спасибі BTW, Летаріон). Це те, що я прошу неможливо, чи щось таке?
aendrew

Слід зазначити, що мені вдалося успішно додати Javascript за допомогою ctools_add_js();або drupal_add_js();в кінці hook_content_type_edit_form();. Якщо ви просто робите прості речі, пов’язані з інтерфейсом користувача, здається, що це може бути найкращим дзвінком (принаймні, поки хтось належним чином не відповість на це запитання).
aendrew

Відповіді:


8

Коротка відповідь: ви повинні використовувати #ajax ['шлях'].

Довга відповідь:

Наявність зворотного виклику Ajax не допомагає, оскільки ctools створює його форми по-різному afaik. Зворотний виклик, виконаний системою / ajax, не може знайти повне визначення форми, тому не може знайти елемент для обробки запиту ajax. Використання #ajax [шлях] просто запускає пункт меню.

Ви можете перевірити себе, скинувши форму, використовуючи #ajax [зворотний виклик]

function ajax_form_callback() {
  list($form, $form_state) = ajax_get_form();
  drupal_process_form($form['#form_id'], $form, $form_state);

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

function simplecontext_content_type_edit_form($form, &$form_state) {
  $conf = $form_state['conf'];

  $form['owner_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Username'),
    '#default_value' => 'admin',
    '#autocomplete_path' => 'user/autocomplete',
    '#size' => '6',
    '#maxlength' => '60',
    '#description' => '$description',
  );

  $form['link_type'] = array(
    '#type' => 'radios',
    '#title' => t('Link Type'),
    '#ajax' => array(
      'path' => 'my_module_set_target'
    ),
    '#default_value' => empty($conf['link_type']) ? '_blank' : $conf['link_type'],
    '#options' => array('none' => t('No Link'), 'internal' => t('Internal Link'), 'external' => t('External Link'), 'document' => t('Document Link')),
  );
...

Оскільки ви зараз використовуєте шлях #ajax, вам потрібно додати пункт меню так, як я хотів

<?php

function my_module_menu() {
  $items = array(
    'my_module_set_target' => array(
      'title' => 'AJAX Example',
      'page callback' => 'my_module_set_target',
      'access callback' => TRUE,
      'expanded' => TRUE,
    )
  );
  return $items;
}

function my_module_set_target() {
  drupal_json_output( array('data' => "ABC"));
}

Нітчік про #attached [js]: вбудований js повинен бути key => значення типу:

'#attached' => array(
  'js' => array(
    'alert("Yay.");' => 'inline',
  ),
),

Я використовував Firebug для перевірки отриманого значення, а не результату. Тож сподіваюся, що це допоможе вирішити вашу проблему.


Ого. Я настільки приготований, що нарешті мав відповідь на це питання. Спробую це трохи. Дякую також за примітку про #attached біт, це насправді те, що я мав спочатку (Але змінив це, бо зрозумів, що це не може бути правильним)
aendrew

Отже, будь-який успіх? Було б цікаво дізнатися до того, як закінчиться щедрість :)
Летаріон

Я сподіваюся, що я отримаю свою нагороду: p
Клеменс Толбум

Вибачте за затримку з цим, що трохи часу працюю, коли я намагаюся повернути масив $ form, він повідомляє мені, що моя функція перевірки не визначена. Він є, і коли я намагаюся повторно оголосити його у своєму модулі (на відміну від файлу плагіну типу вмісту), він говорить мені, що я його повторно декларую. Я здогадуюсь, що це не те, що мені потрібно зробити, але я не можу зрозуміти, як структурувати drupal_json_output, щоб він вивів щось, що моя форма буде інтерпретувати як значущу відповідь. Будь-яка допомога? Кращий приклад зворотного дзвінка допоможе ЛОТ. Дякую!
aendrew

Я пропустив крихітну частину вашого запитання, що стосується поверненого значення: return $ form ['link_target'] ['# default_value']; яка намагається повернути друпальську форму в контекст html / javascript . Це не вийде. Ви бачили подібне, що ви хочете в інтерфейсі панелей? (Я сам відключаю JavaScript час від часу з інтерфейсом перегляду, щоб побачити робочий процес, який не є js) (редагував цей коментар в мільйон разів ... незручно)
Клеменс Толбом

2

У мене була подібна проблема, коли я хотів включити тип медіа-елемента в плагін типу вмісту CTools, який також використовує ajax для вибору зображення.

Він використовує власну настройку "шлях" ajax замість "зворотного дзвінка", але, вибираючи зображення, форма була відновлена ​​без медіа-елемента повністю.

Я простежив це до того, що drupal_rebuild_form не міг знайти ні функції обгортки форми CTools, ні функції фактичних налаштувань. Тому я виправив це, додавши ці рядки коду до форми налаштувань ctools:

function custom_module_my_content_plugin_content_type_edit_form($form, &$form_state) {

$background_image = isset($conf['background_image']) ? $conf['background_image'] : array();
  $form['background_image'] = array(
    '#title' => t('Background image'),
    '#default_value' => $background_image,
    '#type' => 'media',
    '#input' => TRUE,
    '#extended' => TRUE,
    '#tree' => TRUE,
    '#media_options' => array(),
  );

  // The two function calls below are necessary if we want to use a media
  // element type, because it causes ajax requests, which in turn call
  // drupal_form_rebuild(), and without the below includes, Drupal will
  // not be able to rebuild the form.

  // Include the CTools content type plugin file, because it provides
  // the ctools_content_configure_form_defaults() function, which is needed
  // when rebuilding the form, because of an ajax action, like selecting
  // a media element.
  ctools_form_include($form_state, 'content');

  // Include this plugin file as well, so that when the form is rebuilt, it
  // can successfully retrieve the settings form.
  ctools_form_include($form_state, 'my_content_plugin', 'custom_module', 'plugins/content_types/my_content_plugin');

}

Можливо, я пропускаю щось очевидне, чому включені файли не завантажуються, але в тому числі вони вручну вирішили проблему для мене.


0

з моєї сторони, мені довелося написати функцію обгортки форми у файл .module та включити панель вручну (де визначено вихідний вміст форми) так:

function mymodule_form($form, &$form_state) {
  // include mymodule/panes/mypane.inc
  ctools_include('mypane', 'mymodule', 'panes');
  return mymodule_form_content($form, $form_state);
}

Тепер, під час виклику Ajax, Drupal може отримати мою форму, щоб я міг використовувати API стандартної форми AJAX.

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