Ubah bentuk yang ada

12

Kami baru saja memulai dengan Drupal 8 dan sangat cepat kami mengalami masalah pertama kami.

Bagaimana saya harus mengubah formulir yang ada di Drupal 8?

Kita perlu mengubah metode simpan untuk bentuk simpul untuk melakukan redirect ke halaman lain. Kami ingin mengubah bentuk simpul menjadi sesuatu seperti bentuk multistep. Setelah pengguna membuat konten baru, mereka akan dialihkan ke formulir baru (kami buat) untuk mendapatkan informasi lebih lanjut.

Kami memecahkan masalah penerapan kami hook_entity_type_alter().

function mymodule_entity_type_alter(&$entity_info) {
  $handlers = $entity_info['node']->get('handlers');
  $handlers['form']['default'] =    'Drupal\mymodule\Form\MyExtendedNodeForm';
  $handlers['form']['edit'] = 'Drupal\mymodule\Form\MyExtendedNodeForm';
  $entity_info['node']->set('handlers', $handlers);
}

Kami kemudian membuat kelas bentuk baru yang memperluas bentuk simpul dan mengubah metode simpan.

class MyExtendedNodeForm extends NodeForm {

    public function save(array $form, FormStateInterface $form_state) {
      parent::save($form, $form_state);
      $node = $this->entity;
      $form_state->setRedirect('entity.regions.add_form', ['nid' => $node->id()]);
  }

}

Ini bekerja dengan sempurna, tetapi apakah itu baik? Jika modul lain melakukan hal yang sama, kode kami tidak dapat dieksekusi lagi.

Jens Steppe
sumber
2
Drupal 8 masih mendukung hook_form_alter(). Jika Anda hanya perlu mengarahkan ulang formulir, itu sudah cukup untuk menambahkan penangan pengiriman formulir yang melakukan redirect.
kiamlaluno
@kiamlaluno Itu seharusnya jawaban saya pikir :)
Berdir
@Berdir Itu saja tidak akan banyak membantu, saya takut: Pengetahuan saya tentang Drupal 8 sangat terbatas. Plus, OP harus menjelaskan apa yang sebenarnya "mengubah save()metode" sebenarnya. Apakah itu berarti mengubah cara data disimpan, atau hanya melakukan redirect? Dalam kasus pertama, jawabannya lebih kompleks.
kiamlaluno
@kiamlaluno Thx untuk jawabannya. Dalam hal ini, kita hanya perlu melakukan redirect setelah save () sehingga jawaban Anda akan berfungsi. Tetapi saya juga tertarik pada bagaimana mengubah hal-hal lain dalam bentuk dengan cara Drupal 8 yang tepat. Misalnya mengubah cara disimpan, atau menambahkan bidang ke formulir .. dll.
Jens Steppe

Jawaban:

4

Saya harus melakukan hal yang sama kemarin, dan saya masih mencari cara yang lebih Drupal 8 untuk melakukan ini, tetapi belum menemukannya. Saya akhirnya melakukannya dengan cara ini:

<?php

/**
 * @file
 * This is my module.
 */

use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Implements hook_form_alter().
 */
function MODULE_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'user_form') {
    $form['actions']['submit']['#submit'][] = '_MODULE_goto';
  }
}

/**
 * Make the form go to route.id.
 */
function _MODULE_goto($form, FormStateInterface $form_state) {
  $form_state->setRedirect('route.id');
}

Saya masih sangat tertarik melakukannya dengan cara yang berbeda, modul saya terlihat sangat bersih tanpa file .module :).

Dagomar
sumber
3

Saya menggunakan Drupal 8.1.1 dan sedang mencoba mengarahkan ulang pengguna setelah mereka memodifikasi akun mereka, yaitu mengklik tombol Simpan pada halaman / user / edit. Saya awalnya mencoba ini:

/**
 * Implements hook_form_alter().
*/
function MODULE_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'user_form') {
    $form['#submit'][] = '_MODULE_goto';
  }
}

Sementara itu berhasil user_login_form, itu tidak akan berhasil user_form. Karena user_formsaya harus menggunakan

$form['actions']['submit']['#submit'][] = '_MODULE_goto';

Saya harap ini membantu orang lain yang menemukan masalah yang sama!

Eric C.
sumber
1

Yah saya ingin mengubah site_information_settingsformulir untuk menambahkan beberapa bidang.

Seperti Anda, saya punya pilihan di antara

  • hook_form_alter(atau hook_form_FORM_ID_alter)
  • memperpanjang kelas bentuk asli

Ingin membuat beberapa OOP jadi saya mulai menulis layanan pelanggan rute mengubah atribut system.site_information_settingsrute _form.

Kemudian di kelas baru saya memperpanjang SiteInformationForm, setelah bidang & validator mereka telah ditambahkan dan fungsi kirim diperpanjang Saya merasakan hal yang persis sama seperti Anda ... Sekarang bagaimana jika modul lain menulis ulang rute form juga untuk menggunakan kelasnya sendiri?

Kembali ke awal, saya punya pilihan antara dua opsi ... sepertinya saya memilih yang salah.

hook_form_alterSaya hook_form_FORM_ID_altertampaknya menjadi cara terbaik untuk mengubah bentuk yang ada.

MacSim
sumber
0

Sepertinya apa yang ingin Anda lakukan, itu tidak benar-benar mengubah metode penyimpanan, tetapi untuk mengubah arahan ketika sebuah node disimpan.

Dalam situasi ini, melakukan banyak hal seperti Drupal 7, hook_form_alterbersama dengan handler kustom menyerahkan (pada formulir atau tombol, tergantung pada bentuk dan persyaratan) akan menjadi solusi yang baik.

Apa yang Anda jelaskan dalam pertanyaan juga berfungsi, tetapi saya akan menghindari menimpa kelas dasar, kecuali saya benar-benar ingin mengubah sesuatu di kelas.

Penggunaan metode save hanya digunakan sebagai pengirim handler, jadi tidak masuk akal untuk menimpa hanya untuk menambahkan arahan ulang.

googletorp
sumber
0

Saya pikir metode yang lebih baik adalah masih menggunakan salah satu kait dari keluarga form_alter, melampirkan pengendali kirim, dan di dalam yang mengatur pengalihan Anda.

Kontribus memperluas kelas dasar untuk melakukan ini adalah berbulu menurut saya. Terutama karena tidak ada fungsi yang berubah, hanya mengarahkan ulang.

Kevin
sumber
0

Anda dapat membuat EventSubscriber baru yang mendengarkan acara KernelEvents :: REQUEST, dan kemudian bereaksi ketika Anda mengirimkan formulir node, sesuatu seperti ini

Bagaimanapun cara hook_form_alter bekerja ok.

ruloweb
sumber
0

Apa yang saya temukan sejauh ini: Menerapkan kait pengubah formulir dan mencoba mengubah penangan yang valid / kirim di formulir pengait itu sendiri hanya berfungsi jika Anda mengubah penangan $ form ['# validate] / $ form [#submit']. (memanggil fungsi form_state untuk ini tidak akan berfungsi dalam bentuk mengubah kait itu sendiri)

Tetapi ketika Anda mencoba ini di dalam penangan validasi, itu cenderung berfungsi:

// Load form submit handlers.
$submit_handlers = $form_state->getSubmitHandlers();

// Drop the core entity submitForm function.
$key_core_submit = array_search('::submitForm', $submit_handlers);
if ($key_core_submit !== FALSE) {
  unset($submit_handlers[$key_core_submit]);
  // Add your own submit handler.
  array_unshift($submit_handlers, 'yourmodule_submit_handler');
}
// Update submit handlers.
$form_state->setSubmitHandlers($submit_handlers);

Ini karena bentuknya sekarang telah dibangun sepenuhnya, bukan case dalam bentuk alter hook itu sendiri.

Idenya adalah: Anda dapat menambahkan penangan validasi sebagai yang terakhir, mengevaluasi penangan lain yang ada untuk pengiriman, dan mengubahnya di sana.

Jika Anda juga ingin mengubah penangan validasi, pastikan penangan Anda berjalan sebelum yang lain dan ubah apa yang Anda inginkan dalam penangan yang valid.

Masih mencari cara yang lebih baik, saya selalu harus mengganti validasi / serah penangan untuk formulir pendaftaran pengguna. Tapi ada modul lain yang bisa merusak implementasi modul saya. Jadi modul saya harus dapat memeriksa ini, dan itu mungkin seperti ini. Saya bertanya-tanya apakah beberapa bentuk entitas setelah fungsi build ada untuk melakukan ini. (sesuatu yang berjalan ketika formulir telah selesai dan akan dikirim) (itu bukan cara yang rumit untuk kasus sederhana ini)

Memintas pengalihan metode save () tidak dimungkinkan, tetapi membatalkan pengaturan save () adalah dengan cara ini (+ terapkan sendiri). Benar, kelas lebih bagus dan menawarkan akses yang lebih mudah ke objek / etc, tetapi mengesampingkan kelas inti memang menyebabkan masalah ketika modul lain ingin menggunakannya. Itu tidak terjadi jika Anda menggunakan kode ini.

Rob C
sumber
0

Setelah memeriksa masalah ini, inilah yang saya temukan yang sesuai dengan kasus Anda:

/**
 * Implements hook_entity_type_alter().
 */
function mymodule_entity_type_alter(&$entity_info) {
 $entity_info['node']->setFormClass('edit','Drupal\mymodule\Form\CustomNodeForm');
}
Ioana Todea
sumber