Mevcut bir formu değiştirme


12

Drupal 8 ile yeni başladık ve çok hızlı bir şekilde ilk sorunumuzla karşılaştık.

Drupal 8'de mevcut bir formu nasıl değiştirmeliyim?

Başka bir sayfaya yönlendirme yapmak için düğüm formunun kaydetme yöntemini değiştirmemiz gerekiyor. Çok adımlı bir form haline gelmek için düğüm formunu değiştirmek istiyoruz. Kullanıcı yeni içerik oluşturduktan sonra, daha fazla bilgi almak için yeni bir forma (oluşturduk) yönlendirilir.

Sorun uygulamamızı çözdük 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);
}

Daha sonra düğüm formunu genişleten ve save yöntemini değiştiren yeni bir form sınıfı oluşturduk.

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

}

Mükemmel çalışıyor, ama iyi mi? Başka bir modül de aynısını yaparsa, kodumuz artık çalıştırılmaz.


2
Drupal 8 hala destekliyor hook_form_alter(). Yalnızca formu yeniden yönlendirmeniz gerekiyorsa, yönlendirmeyi yapan bir form gönderme işleyicisi eklemek yeterlidir.
kiamlaluno

@kiamlaluno Sanırım cevap bu olmalı :)
Berdir

@Berdir Korkarım ki tek başına çok yardımcı olmaz: Drupal 8 hakkındaki bilgim oldukça sınırlı. Ayrıca, OP " save()yöntemi değiştirmenin " gerçekte ne anlama geldiğini açıkça belirtmelidir . Bu, verilerin kaydedilme biçimini değiştirmek mi yoksa yalnızca bir yönlendirme yapmak mı demek? İlk durumda, cevap daha karmaşıktır.
kiamlaluno

@kiamlaluno Cevap için teşekkürler. Bu durumda, yalnızca save () işlevinden sonra bir yönlendirme yapmamız gerekir, bu nedenle cevabınızın çalışması gerekir. Ama aynı zamanda formdaki diğer şeyleri doğru Drupal 8 yolunda nasıl değiştireceğimi de merak ettim. Örneğin, kaydedilme şeklini değiştirin veya forma alan ekleyin .. etc ..
Jens Steppe

Yanıtlar:


4

Aynı şeyi dün yapmak zorundaydım ve hala bunu yapmanın daha Drupal 8 yolunu arıyorum, ama bulamadım. Bu şekilde yaptım:

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

Hala farklı bir şekilde yapmakla ilgileniyorum, modülüm .module dosyası olmadan çok temiz görünüyordu :).


3

Drupal 8.1.1 kullanıyorum ve hesaplarını değiştirdikten sonra, yani / user / edit sayfasındaki Kaydet düğmesini tıkladıktan sonra kullanıcıları yönlendirmeye çalışıyordum. Başlangıçta bunu denedim:

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

Bu işe yarasa da user_login_form, işe yaramaz user_form. Çünkü user_formkullanmak zorunda kaldım

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

Umarım bu aynı sorunla karşılaşanlara yardımcı olur!


1

site_information_settingsBazı alanları eklemek için formu değiştirmek istedim .

Senin gibi aralarında seçim yapabildim

  • hook_form_alter(veya hook_form_FORM_ID_alter)
  • orijinal form sınıfını genişlet

Bazı OOP yapmak istedim, bu yüzden system.site_information_settingsrotanın _formözelliğini değiştiren bir rota abone servisi yazmaya başladım .

Sonra benim yeni sınıf SiteInformationForm, alanları ve doğrulayıcıları eklendikten ve gönderme işlevi genişledikten sonra tam olarak seninle aynı şekilde hissettim ... Şimdi ya başka bir modül kendi sınıfını kullanmak için de form yolunu yeniden yazarsa?

Başlangıca, iki seçenek arasında seçim yaptım ... yanlış olanı seçmişim gibi görünüyor.

hook_form_alter/ hook_form_FORM_ID_altervarolan bir formu değiştirmenin en iyi yolu gibi görünüyor.


0

Ne yapmak istediğinize benziyor, gerçekten kaydetme yöntemini değiştirmek değil, bir düğüm kaydedildiğinde yönlendirmeyi değiştirmek.

Bu durumda, Drupal 7 gibi çok hook_form_alterözel bir işleyici (form veya gereksinime bağlı olarak form veya düğme üzerinde) ile birlikte yapmak iyi bir çözüm olacaktır.

Soruda açıkladığınız şey de işe yarıyor, ancak aslında sınıftaki bir şeyi değiştirmek istemedikçe temel sınıfın üzerine yazmaktan kaçınırım.

Yine de bir gönderme işleyicisi olarak kullanılan kaydetme yöntemi kullanımı, bu yüzden sadece bir yönlendirme eklemek için üzerine yazmak fazla mantıklı değildir.


0

Ben daha iyi bir yöntem hala form_alter ailesinden kanca birini kullanmak, bir gönderme işleyicisi bağlı olduğunu ve bu yönlendirme içinde ayarlamak olduğunu düşünüyorum.

Bunun için temel sınıfları genişletmeye katkıda bulunmak bence kıllı. Özellikle hiçbir işlev değişmediği için sadece yönlendiriliyor.


0

Eğer, böyle bir şey bir düğüm formunu gönderdiğinizi zaman KernelEvents :: İSTEK etkinliğini dinleyen yeni EventSubscriber oluşturun ve tepki verebilir bu

Neyse hook_form_alter yolu iyi çalışıyor.


0

Ne şimdiye kadar buldum: Bir form alter hook uygulamak ve form alter hook kendisinde doğrula / gönder işleyicileri değiştirmeye çalışın sadece $ form ['# validate] / $ form [#submit'] işleyicileri değiştirirseniz çalışır. (bu değişmez form_state işlevlerini çağıran formun kendisini değiştirir)

Ancak bunu bir doğrulama işleyicisi içinde denediğinizde işe yarar:

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

Bunun nedeni, formun şu an tamamen inşa edilmiş olması, formdaki durumun kendisini değiştirmemesi.

Fikir şu ki: sonuncusu olarak bir doğrulama işleyicisi ekleyebilir, gönderme için var olan diğer işleyicileri değerlendirebilir ve bunları orada değiştirebilirsiniz.

Doğrulama işleyicilerini de değiştirmek istiyorsanız, kendinizinkinden önce çalıştığından emin olun ve doğrulama işleyicisinde istediğinizi değiştirin.

Hala kendimi daha iyi bir yol arıyor, ben sadece her zaman kullanıcı kayıt formu için doğrulama / gönderme işleyicileri değiştirmeniz gerekir. Ancak modüllerimin uygulanmasını bozan başka modüller de olabilir. Bu yüzden modülümün bunları kontrol edebilmesi gerekiyordu ve bu da bu şekilde mümkün. Bunu kaldırmak için build işlevinden sonra bazı varlık formunun olup olmadığını merak ediyorum. (form tamamlandığında ve teslim edilmek üzere olan bir şey) (bu basit durum için karmaşık bir yol değildir)

Save () yönteminin yönlendirmesini atlamak mümkün değildir, ancak save () öğesinin ayarının kaldırılması bu yolla (+ kendiniz uygulayın). Doğru, bir sınıf daha hoştur ve nesnelere / vb. Daha kolay erişim sunar, ancak çekirdek bir sınıfın geçersiz kılınması gerçekten de diğer modüller bunları kullanmak istediğinde sorunlara yol açar. Bu kodu kullanırsanız durum böyle değildir.


0

Bu sorunu kontrol ettikten sonra, davanıza uygun olması gereken şeyi buldum:

/**
 * Implements hook_entity_type_alter().
 */
function mymodule_entity_type_alter(&$entity_info) {
 $entity_info['node']->setFormClass('edit','Drupal\mymodule\Form\CustomNodeForm');
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.