Apakah mungkin menampilkan Formulir Widget Bidang yang berfungsi?


21

Saya tertarik untuk menyematkan Formulir Widget Bidang di luar konteks formulir edit seluruh simpul.

Saya telah menampilkan formulir lengkap di masa lalu menggunakan drupal_get_form tetapi tampaknya tidak berlaku untuk Formulir Bidang soliter.

Apakah mungkin menampilkan Formulir Widget Bidang yang berfungsi? Apa cara terbaik untuk melakukannya?

Kedua widget bidang dan formulir "normal" tampak sangat mirip, jadi jika ini tidak memungkinkan, apa yang akan diperlukan untuk "mengubah" formulir widget menjadi bentuk normal?

Pertanyaan ini tampaknya meminta sesuatu yang serupa tetapi saya tidak mengerti jawabannya. Jawaban itu menentukan menggunakan hook_field_widget_form_alter ; apa yang saya tidak mengerti adalah bagaimana mendapatkan Formulir Bidang yang akan ditampilkan bukan bagaimana menghubungkannya setelah itu dibuat.

Jawaban:


18

VBO melakukan sesuatu seperti ini di mod.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);  

Jadi, Anda memerlukan jenis entitas, entitas (yang dapat berupa objek kosong hanya dengan kumpulan kunci bundel, itulah yang sebenarnya digunakan), formulir tempat widget ditambahkan, dan bahasa. Jika Anda ingin menyematkan widget lebih dalam ke dalam formulir (bukan dalam $ form, tetapi dalam $ form [$ form_key] seperti yang saya lakukan, atau bahkan lebih dalam), maka array bentuk tersebut harus memiliki #parents set.

Tentu saja, perhatikan bahwa ini akan menyematkan widget semua bidang yang termasuk jenis entitas & bundel. Ini adalah bagaimana fungsi lampiran ditulis. Berkeliling yang akan mengharuskan Anda untuk menemukan kembali cukup banyak kode; lihat kode aktual yang melakukan pengangkatan berat. Apa yang saya lakukan adalah melalui instance bidang, dapatkan setiap $ field_name, dan jika jenis bidang itu tidak menarik bagi saya, saya menetapkan $form[$form_key][$field_name]['#access'] = FALSE; yang menyembunyikan widget tersebut dari pandangan.

EDIT: Oke, ctools memiliki ctools_field_invoke_field () yang secara teori memungkinkan Anda untuk bekerja berdasarkan per-bidang. Saya belum pernah menggunakannya. Teks di atas adalah pengalaman langsung saya.


Jawaban yang luar biasa. Saya menghabiskan sebagian besar hari bekerja dengan ini, dan itu berfungsi seperti yang saya inginkan. Hadiah diberikan, dan saya merekomendasikan OP untuk menerima ini sebagai jawaban yang benar. Saya akhirnya membuat jenis konten dummy sehingga saya dapat mengontrol bidang saya seperti jenis konten lainnya, alih-alih pengaturan #access = FALSEyang tampak tidak rapi dalam konteks ini.
Letharion

Terima kasih telah mengkonfirmasi apa yang saya takuti: bahwa widget bidang tunggal tidak bisa digunakan sendiri.
SMTF

7

Saya secara intensif menggunakan fungsi yang disarankan oleh ttk, tapi saya pikir pembaruan terbaru mengacaukan ...

Ini adalah versi baru dari solusi sebelumnya yang berfungsi baik dengan Drupal 7.22 dan ctools 7.x-1.3.

Jadi, seperti pada posting sebelumnya, Anda memanggil fungsi kustom Anda seperti ini:

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

Perhatikan bahwa bundel entitas sekarang menjadi parameter. Saya melakukan ini karena saya juga menggunakan fungsi ini untuk mengedit pengguna. Dengan cara ini, itu juga dapat digunakan untuk istilah taksonomi, atau entitas lain.

Dan my_field_attach_formdidefinisikan sebagai:

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

Fungsi ini menghemat banyak waktu saya, semoga juga untuk Anda!


5

Berikut ini solusinya menggunakan ctools_field_invoke_field()metode ini. Dalam fungsi formulir kustom Anda, tambahkan:

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

di mana my_field_attach_formfungsi didefinisikan sebagai

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

Perhatikan, bahwa situs Anda harus memiliki ctools diaktifkan. Sayang sekali bahwa Drupal tidak menyertakan fungsi pembantu seperti ini secara default.


2

Saya tidak dapat menjalankan metode ctools dan memutuskan untuk melakukannya dengan cara ini.

Kode ini akan berada di dalam fungsi form, jadi $ form dan $ form_state sudah dikirimkan sebelumnya.

function form_function($form, &$form_state) {

Pertama, buat simpul kosong dari jenis yang memiliki bidang yang ingin Anda render.

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

Saya menduplikasi variabel bentuk jadi saya tidak akan mengalahkan yang asli.

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

Tarik bidang yang Anda cari dan tambahkan ke formulir.

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

Saya menggunakan metode ini untuk merender widget pilih taksonomi, widget kotak centang taksonomi, dan widget Pilih Hirarki pada formulir kustom. (Taxonomy Autocomplete widget renders tetapi menimbulkan kesalahan saat kirim)

Akhirnya render dan cetak

drupal_render(drupal_get_form("form_function"))

Ini sepertinya cara mudah untuk menggunakan widget bidang dalam bentuk khusus. Itu tergantung pada bundel yang ada. Dalam kasus saya, saya menggunakan Tipe Konten dummy tempat saya membuat dan mengonfigurasi bidang yang diperlukan. Itu agak hacky tetapi perlu untuk metode lain juga. Sebagai catatan: ctools_field_invoke_field()Metode yang dijelaskan di atas juga berfungsi.
Bernhard Fürst

0

Saya telah membuat formulir dari bidang indivisual menggunakan

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

ini harus mengembalikan formulir widget yang diperlukan yang dapat digunakan dalam bentuk apa pun seperti

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

Untuk mendapatkan nilai untuk 2 parameter di atas, gunakan:

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

Untuk parameter lain, Anda dapat memeriksa tautan api di sini

Ini mengembalikan bentuk widget default yang ditentukan pada bidang jenis konten.

Semoga ini bisa membantu seseorang :)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.