Sematkan satu formulir entitas ke yang lain dan simpan keduanya


9

Saya memiliki entitas khusus, tergantung pada entitas pengguna. Bahkan, itu sangat tergantung bahwa saya merasa masuk akal untuk menampilkan formulir entitas saya dalam formulir profil pengguna:

masukkan deskripsi gambar di sini

Masalah saya sekarang adalah sebagai berikut; ada 2 tombol simpan. Dan jika itu tidak cukup buruk, tombol simpan untuk pengguna (yang lebih rendah) bahkan tidak berfungsi lagi dan tombol simpan label putih hanya menyimpan entitas label putih.

Formulir diubah ke bentuk pengguna seperti ini:

function whitelabel_form_user_form_alter(&$form, FormStateInterface $form_state) {

  $whitelabel = WhiteLabel::load(1);

  $whitelabel_form = \Drupal::service('entity.manager')
    ->getFormObject('whitelabel', 'default')
    ->setEntity($whitelabel);

  $form['whitelabel'] = array(
    '#type' => 'details',
    '#title' => t('White label settings'),
    '#open' => TRUE,
    'form' => \Drupal::formBuilder()->getForm($whitelabel_form),
  );
}

Saya berharap untuk mengocok beberapa parameter dalam $whitelabel_formarray (yang dulu bekerja di Drupal 7), tetapi array itu sangat besar dan saya tidak dapat menemukan tombol dan pengendali pengiriman yang saya butuhkan.

Jadi pertanyaannya adalah, dapatkah ini dilakukan? Dan apa cara yang direkomendasikan untuk melakukannya?



Terima kasih, saya benar-benar membaca pertanyaan itu sebelumnya tetapi tidak peduli apa yang saya coba, saya tidak dapat menemukannya. Saya akan melihat
Neograph734

@ Eyal, apakah Anda juga tahu metode yang tidak mengharuskan saya untuk mengganti formulir? Saya lebih suka menyimpan form pengguna apa adanya.
Neograph734

Saya menulis entitas_reference_form modul khusus tetapi tidak cukup terpelihara. Anda mungkin harus menggunakan inline_entity_form jika Anda ingin menghindari kode khusus.
Eyal

@ Eyal, saya tidak takut kode khusus (saya menulis modul: p). Tetapi dalam contoh Anda, Anda membuat multiformis yang bukan lagi bentuk pengguna. Ini berarti bahwa setiap kali orang lain mencoba melakukan trik yang sama di modul lain, Anda akan selalu hanya melihat 2 dari 3 (atau lebih) formulir yang tersedia. Itulah yang membuat saya bingung. Tapi terima kasih telah meluangkan waktu untuk kembali padaku. Saya akan melihat lagi bentuk entitas inline dalam 2 hari, tetapi saya akan terbuka untuk alternatif tentang mengubahnya entah bagaimana.
Neograph734

Jawaban:


10

Alih-alih mencoba melakukan hal Anda sendiri, Anda harus mencoba modul Formulir Entitas Inline . Modul ini dibuat untuk kasus khusus ini (membuat / mengedit entitas dalam bentuk entitas).

Saya tahu banyak pekerjaan telah dilakukan untuk meningkatkan alur kerja di Drupal Commerce, yang berarti ini harus bekerja dengan baik. Saya belum mengujinya sendiri, tetapi karena Drupal Commerce bergantung pada Drupal 8 juga, itu seharusnya sudah cukup stabil.

Modul ini bekerja dengan menambahkan widget ke bidang referensi entitas yang membuat formulir, jadi itu harus cukup banyak plug and play. Satu-satunya persyaratan adalah bahwa pengguna memiliki referensi ke entitas kustom Anda.


Saya memang melihatnya, tetapi formulir entitas yang direferensikan tidak muncul. Itu bisa saja merupakan kesalahan di pihak saya ...
Neograph734

Tidak semua entitas didukung oleh Formulir Entitas Inline, jika ini adalah entitas kustom maka Anda harus menulis sebuah plugin untuk entitas tipe kustom Anda. Entitas file tidak didukung secara default dan memerlukan ini.
Frank Robert Anderson

7

Saya percaya ini harus mungkin. Sayangnya, saya tidak punya waktu untuk menulis kode hari ini, namun, saya pikir Anda harus mengingat hal-hal berikut:

  • Saat menambahkan sub-formulir, pastikan Anda menghapus item khusus seperti form_iddan form_build_iddigunakan oleh Drupal untuk mengenali formulir yang dikirimkan.
  • Jika Anda tidak ingin tombol formulir di formulir kedua, Anda harus menghapus item formulir seperti unset($sub_form['actions'])sebelum menambahkan sub-formulir ke formulir utama.
  • Pastikan Anda mengaktifkan #treeformulir sehingga Anda bisa menangkap nilai-nilai sub-form di saku terpisah dalam variabel POST. Contoh, $form['#tree'] = TRUE; $form['sub-form'] = $sub_form; Ini akan membuat nilai sub-formulir Anda tersedia di $form_state['values']['sub-form'].
    • Jika Anda ingin pengguna dapat mengirimkan sub-formulir secara independen, Anda harus mengganti nama tindakan untuk sub-formulir sehingga nanti Anda dapat mengenali tombol mana yang diklik. Jika Anda ingin pengguna menggunakan hanya satu tombol simpan untuk menyimpan kedua hal tersebut, maka akan ada lebih sedikit masalah jadi abaikan sub-poin ini.
  • Sekarang, bahwa formulir terlihat di UI, langkah selanjutnya adalah menangani pengiriman. Untuk melakukan ini, tambahkan panggilan balik pengiriman formulir ke formulir utama Anda. Anda mungkin juga ingin menambahkan panggilan balik validasi sub-form ke form utama juga. Dalam panggilan balik khusus, Anda harus memicu panggilan balik pengiriman untuk sub-formulir. Dalam Drupal 7 kita biasa melakukan drupal_form_submit - saya belum tahu sama dengan Drupal 8. Atau, Anda dapat memicu panggilan balik pengiriman sub-formulir secara manual dalam skenario kasus terburuk, tetapi pastikan Anda hanya menyampaikan sub-formnilai $form_state['values'](harap Anda mengerti apa yang saya maksud).
  • Setelah panggilan balik sub-formulir berfungsi tanpa kesalahan, Anda dapat mengasumsikan kedua formulir dikirimkan dan diproses dengan sukses!

Semoga ini bisa membantu! Kedengarannya seperti percobaan yang luar biasa! Semoga berhasil.


1
Terima kasih, saya sudah punya forum untuk muncul dengan kode awal saya. Menghapus form_build_id, form_token, form_iddan actionsmembuat tombol hilang dan membuat 'bentuk luar' bekerja lagi. Saya akan bermain dengan ini lagi dan memberi tahu Anda cara kerjanya.
Neograph734

Saya memberi Anda hadiah karena ini adalah upaya terbaik untuk menjawab pertanyaan. Saya masih berjuang dengan ini karena formulir menolak untuk masuk ke 'mode pohon'. Semua nilai selalu disimpan di tingkat atas, apa pun yang saya coba. Dan tampaknya nilai yang dikirimkan juga tidak ada $form_state ['values'](kunci elemen formulir kosong). Itu mungkin tidak mungkin (belum), tetapi saya berharap untuk menemukan ini suatu hari nanti.
Neograph734

1

Jawaban teoretis (jawaban yang tidak berfungsi, tapi ini yang paling dekat yang saya dapat) Posting di sini untuk referensi dan titik awal untuk orang lain.

Ubah formulir pengguna.

function whitelabel_form_user_form_alter(&$form, FormStateInterface $form_state) {
  $whitelabel = WhiteLabel::load(1);

  $whitelabel_form = \Drupal::entityTypeManager()
    ->getFormObject('whitelabel', 'default')
    ->setEntity($whitelabel);
  $renderable_form = \Drupal::formBuilder()->getForm($whitelabel_form);

  // Remove embedded form specific data.
  unset($renderable_form['actions']);
  unset($renderable_form['form_build_id']);
  unset($renderable_form['form_token']);
  unset($renderable_form['form_id']);

  // Also remove all other properties that start with a '#'.
  foreach ($renderable_form as $key => $value) {
    if (strpos($key, '#') === 0) {
      unset ($renderable_form[$key]);
    }
  }

  // Create a container for the entity's fields.
  $form['whitelabel'] = array(
    '#type' => 'details',
    '#title' => t('White label settings'),
    '#open' => TRUE,
    '#tree' => TRUE,
  );
  $form['whitelabel'] += $renderable_form;

  $form['actions']['submit']['#submit'][] = 'whitelabel_form_user_form_submit';
}

Kirimkan handler:

function whitelabel_form_user_form_submit(&$form, FormStateInterface $form_state) {
  $values = $form_state->getValues(); 

  $form_state = new FormState();
  $form_state->setValues($values);
  // Theoretically you'd want to use $values['entity_container']
  // for the dedicated entity values.

  // Obtain or create an entity. (You want to get this from the form.)
  if (!$whitelabel = WhiteLabel::load(1)) {
    $whitelabel = WhiteLabel::create();
  }

\Drupal::entityTypeManager()
  ->getFormObject('whitelabel', 'default')
  ->setEntity($whitelabel) // Current entity.
  ->buildEntity($form, $form_state) // Update with form values.
  ->save(); // Save updated entity.
}
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.