Panggilan AJAX di Plugin Jenis Konten CTools?

10

Saya sedang membangun Tipe Konten Panel CTools (yaitu, hal yang Anda masukkan ke panel ketika menambahkan konten, bukan tipe node) dan saya mencoba menggunakan #ajaxatribut item formulir untuk menetapkan beberapa nilai default. Lihat kode di bawah ini.

my_module_content_type_edit_form($form, &$form_state)Ngomong-ngomong, ini semua di dalam panggilan jenis konten .

  $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')),
  );

Callback saya adalah sebagai berikut.

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'];
}

Terlepas dari apakah pengembalian yang saya sarankan benar-benar berfungsi, watchdog()bahkan tidak berhasil.

Saya tahu CTools melakukan beberapa hal aneh dengan AJAX, tetapi tidak mungkin itu aneh. Apakah Anda tahu bagaimana saya akan melakukan apa yang ingin saya lakukan?

Terima kasih!

Atau: Bagaimana cara menetapkan nilai default berdasarkan nilai opsi formulir sebelumnya?

Saya menemukan cara untuk melakukan ini, tapi ini sedikit gila - Anda membuat bidang formulir baru untuk setiap garpu ketergantungan. Anda kemudian bisa menggabungkan nilai-nilai bersama hook_content_type_edit_form_submit(), menggunakan mana yang sesuai dengan nilai yang dipilih untuk komponen yang awalnya bercabang semuanya.

Saya membiarkan pertanyaan terbuka karena saya (dan, sejujurnya, setiap programmer yang bekerja dengan saya) benar-benar menginginkan cara yang baik untuk menggunakan AJAX di dalam formulir edit tipe konten Panel ini.

Pembaruan: Tampaknya Anda tidak dapat melakukan hal-hal dengan #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'
    ),
  )
);
aendrew
sumber
Menjadi tipe "Panels for everything" dari pengembang Drupal, saya pikir saya juga bisa menggunakan ini di masa depan, jadi saya menambahkan hadiah, mari kita lihat apa yang terjadi.
Letharion
Wow, karunia itu datang dan pergi bahkan tanpa komentar (Terima kasih BTW, Letharion). Apakah yang saya minta tidak mungkin atau sesuatu?
aendrew
Harus dicatat bahwa saya telah berhasil menambahkan Javascript menggunakan ctools_add_js();atau drupal_add_js();di akhir hook_content_type_edit_form();. Jika Anda hanya melakukan hal-hal sederhana yang berhubungan dengan UI, sepertinya itu adalah panggilan terbaik (Setidaknya sampai seseorang menjawab pertanyaan ini dengan benar).
aendrew

Jawaban:

8

Jawaban singkat: Anda harus menggunakan #ajax ['path'].

Jawaban panjang:

Memiliki panggilan balik ajax tidak membantu karena ctools membuat bentuknya berbeda. Callback yang dilakukan oleh sistem / ajax tidak dapat menemukan definisi formulir yang lengkap sehingga tidak dapat menemukan elemen untuk memproses permintaan ajax. Menggunakan #ajax [path] hanya memicu item menu.

Anda dapat memeriksa sendiri dengan membuang formulir saat menggunakan #ajax [panggilan balik]

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

Saya telah memodifikasi format simplecontext_content_type_edit_form dengan menambahkan widget autocomplete pengguna dan bidang Anda yang berfungsi :)

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')),
  );
...

Karena sekarang Anda menggunakan jalur #ajax Anda perlu menambahkan item menu seperti yang saya suka

<?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"));
}

Nittpick tentang #attached [js]: inline js harus berupa nilai key => seperti:

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

Saya telah menggunakan Firebug untuk memeriksa nilai yang dihasilkan bukan efek yang dihasilkan. Jadi saya harap ini membantu memperbaiki masalah Anda.

Clemens Tolboom
sumber
Wow. Saya sangat bersemangat akhirnya memiliki jawaban untuk pertanyaan ini. Akan mencobanya sebentar lagi. Terima kasih juga untuk catatan pada bit #attached, itu sebenarnya yang saya miliki pada awalnya (Tapi mengubahnya karena saya pikir itu tidak benar).
aendrew
Jadi, ada kesuksesan? Akan menarik untuk mengetahui sebelum karunia berakhir :)
Letharion
Saya harap saya mendapatkan hadiah saya: p
Clemens Tolboom
Maaf atas keterlambatan ini, sedikit waktu untuk membuatnya berfungsi - ketika saya mencoba mengembalikan array $ form, ini memberitahu saya fungsi validasi saya tidak didefinisikan. Ya, dan ketika saya mencoba mendeklarasikan ulang dalam modul saya (sebagai lawan dari file jenis plugin konten), ia memberi tahu saya bahwa saya mendeklarasikan ulang. Saya menduga bukan itu yang perlu saya lakukan, tetapi saya tidak tahu bagaimana cara menyusun drupal_json_output sehingga menghasilkan sesuatu yang akan ditafsirkan oleh formulir saya sebagai respons yang bermakna. Ada bantuan? Contoh panggilan balik yang lebih baik akan membantu BANYAK. Terima kasih!
aendrew
Saya melewatkan bagian kecil dari pertanyaan Anda yaitu tentang nilai pengembalian: return $ form ['link_target'] ['# default_value']; yang Anda coba untuk mengembalikan bentuk drupal ke konteks html / javascript . Itu tidak akan berhasil. Pernahkah Anda melihat hal serupa yang Anda inginkan di panel UI? (Saya sendiri menonaktifkan JavaScript sekarang dan kemudian dengan tampilan UI hanya untuk melihat alur kerja non js) (mengedit komentar ini jutaan kali ... canggung)
Clemens Tolboom
2

Saya memiliki masalah yang sama, di mana saya ingin memasukkan tipe elemen Media ke dalam plugin tipe konten CTools, yang juga menggunakan ajax untuk memilih gambar.

Ia menggunakan pengaturan 'jalur' ajax sendiri, alih-alih pengaturan 'panggil balik', tetapi saat memilih gambar, formulir itu dibuat kembali tanpa elemen media sepenuhnya.

Saya melacak ini ke fakta bahwa drupal_rebuild_form tidak dapat menemukan fungsi pembungkus bentuk CTools, maupun fungsi bentuk pengaturan aktual. Jadi saya memperbaikinya dengan menambahkan baris kode ini ke formulir pengaturan 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');

}

Mungkin saya kehilangan sesuatu yang jelas mengapa file yang disertakan tidak dimuat, tetapi termasuk mereka secara manual memperbaiki masalah bagi saya.

Placinta
sumber
0

di pihak saya, saya harus menulis fungsi pembungkus formulir dalam file .module dan untuk memasukkan panel secara manual (di mana konten bentuk asli didefinisikan) seperti itu:

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

Sekarang, selama panggilan ajax, Drupal dapat mengambil formulir saya sehingga saya dapat menggunakan API formulir AJAX standar.

Pierco
sumber