แก้ไขฟอร์มที่มีอยู่


12

เราเพิ่งเริ่มต้นด้วย Drupal 8 และเร็วมากที่เราพบปัญหาแรกของเรา

ฉันจะเปลี่ยนรูปแบบที่มีอยู่ใน Drupal 8 ได้อย่างไร

เราจำเป็นต้องเปลี่ยนวิธีการบันทึกสำหรับรูปแบบโหนดเพื่อทำการเปลี่ยนเส้นทางไปยังหน้าอื่น เราต้องการเปลี่ยนรูปแบบโหนดให้เป็นแบบฟอร์มหลายขั้นตอน หลังจากผู้ใช้สร้างเนื้อหาใหม่พวกเขาจะถูกเปลี่ยนเส้นทางไปยังแบบฟอร์มใหม่ (เราสร้าง) เพื่อรับข้อมูลเพิ่มเติม

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

จากนั้นเราสร้างคลาสฟอร์มใหม่ที่ขยายฟอร์มโหนดและเปลี่ยนวิธีการบันทึก

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

}

มันใช้งานได้ดี แต่มันดีใช่ไหม หากโมดูลอื่นทำเช่นเดียวกันรหัสของเราจะไม่ถูกเรียกใช้อีกต่อไป


2
Drupal hook_form_alter()สนับสนุน หากคุณเพียงต้องการเปลี่ยนเส้นทางของแบบฟอร์มก็พอที่จะเพิ่มตัวจัดการการส่งแบบฟอร์มที่เปลี่ยนเส้นทาง
kiamlaluno

@kiamlaluno ที่ควรจะเป็นคำตอบที่ฉันคิด :)
Berdir

@Berdir เพียงคนเดียวที่จะไม่เป็นประโยชน์มากฉันกลัว: ความรู้ของฉันเกี่ยวกับ Drupal 8 ค่อนข้าง จำกัด นอกจากนี้ OP ควรทำให้ชัดเจนว่า "เปลี่ยนsave()วิธี" หมายถึงอะไรจริง ๆ มันหมายถึงการเปลี่ยนวิธีการบันทึกข้อมูลหรือเพียงแค่ทำการเปลี่ยนเส้นทาง? ในกรณีแรกคำตอบนั้นซับซ้อนกว่า
kiamlaluno

@ kiamlaluno ขอบคุณสำหรับคำตอบ ในกรณีนี้เราจำเป็นต้องทำการเปลี่ยนเส้นทางหลังจากบันทึก () เพื่อให้คำตอบของคุณควรทำงาน แต่ฉันก็สนใจที่จะเปลี่ยนสิ่งอื่น ๆ ในแบบฟอร์ม Drupal 8 อย่างถูกวิธี ยกตัวอย่างเช่นการเปลี่ยนแปลงวิธีการที่จะบันทึกไว้หรือเพิ่มสาขาในรูปแบบ .. ฯลฯ ..
Jens บริภาษ

คำตอบ:


4

ฉันต้องทำสิ่งเดียวกันเมื่อวานนี้และฉันยังคงมองหาวิธี Drupal 8 อีกวิธี แต่ไม่พบ ฉันลงเอยด้วยวิธีนี้:

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

ฉันยังคงสนใจที่จะทำมันในลักษณะที่แตกต่างกันโมดูลของฉันดูสะอาดตาโดยไม่ต้องใช้ไฟล์. module :)


3

ฉันกำลังใช้ Drupal 8.1.1 และพยายามที่จะเปลี่ยนเส้นทางผู้ใช้หลังจากที่พวกเขาแก้ไขบัญชีของพวกเขานั่นคือการคลิกที่ปุ่มบันทึกในหน้า / ผู้ใช้ / แก้ไข ฉันเริ่มลองนี้:

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

ในขณะที่ทำงานให้กับมันจะไม่ทำงานuser_login_form user_formสำหรับuser_formฉันต้องใช้

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

ฉันหวังว่าจะช่วยให้ผู้อื่นที่เจอปัญหาเดียวกัน!


1

ฉันต้องการเปลี่ยนsite_information_settingsแบบฟอร์มเพื่อเพิ่มบางฟิลด์

ในขณะที่คุณฉันมีทางเลือกระหว่าง

  • hook_form_alter(หรือhook_form_FORM_ID_alter)
  • ขยายคลาสฟอร์มดั้งเดิม

ต้องการที่จะทำให้ OOP บางอย่างดังนั้นฉันเริ่มเขียนบริการสมาชิกเส้นทางการเปลี่ยนแอตทริบิวต์system.site_information_settingsของเส้นทาง_form

จากนั้นในชั้นเรียนใหม่ของฉันที่ขยายSiteInformationFormหลังจากเพิ่มฟิลด์และตัวตรวจสอบความถูกต้องของพวกเขาและฟังก์ชั่นการส่งขยายฉันรู้สึกเหมือนกับคุณ ... ตอนนี้ถ้าโมดูลอื่นเขียนเส้นทางของฟอร์มและใช้คลาสของตัวเอง?

กลับไปที่จุดเริ่มต้นฉันมีตัวเลือกระหว่างสองตัวเลือก ... ดูเหมือนว่าฉันเลือกผิด

hook_form_alter/ hook_form_FORM_ID_alterดูเหมือนจะเป็นวิธีที่ดีที่สุดในการเปลี่ยนแบบฟอร์มที่มีอยู่


0

ดูเหมือนว่าคุณต้องการจะทำไม่ใช่การเปลี่ยนวิธีการบันทึก แต่เป็นการเปลี่ยนเส้นทางเมื่อบันทึกโหนด

ในสถานการณ์เช่นนี้การทำเช่นเดียวกับ Drupal 7 hook_form_alterพร้อมกับตัวจัดการการส่งแบบกำหนดเอง (บนฟอร์มหรือปุ่มขึ้นอยู่กับแบบฟอร์มและข้อกำหนด) จะเป็นทางออกที่ดี

สิ่งที่คุณอธิบายในคำถามยังใช้งานได้ แต่ฉันจะหลีกเลี่ยงการเขียนทับคลาสฐานยกเว้นว่าฉันต้องการเปลี่ยนบางสิ่งบางอย่างในชั้นเรียน

วิธีการบันทึกใช้เพียงแค่ใช้เป็นตัวจัดการการส่ง แต่อย่างใดดังนั้นจึงไม่เหมาะสมที่จะเขียนทับเพียงเพื่อเพิ่มการเปลี่ยนเส้นทาง


0

ฉันคิดว่าวิธีที่ดีกว่าคือการยังคงใช้ hooks ตัวใดตัวหนึ่งจากตระกูล form_alter แนบตัวจัดการการส่งและอยู่ภายในชุดการเปลี่ยนเส้นทางของคุณ

Contrib ขยายคลาสพื้นฐานเพื่อทำสิ่งนี้ในความคิดของฉัน โดยเฉพาะอย่างยิ่งเนื่องจากไม่มีการเปลี่ยนแปลงฟังก์ชั่นเพียงแค่เปลี่ยนเส้นทาง


0

คุณสามารถสร้าง EventSubscriber ใหม่ซึ่งฟังเหตุการณ์ KernelEvents :: REQUEST แล้วตอบสนองเมื่อคุณส่งฟอร์มโหนดสิ่งนี้

อย่างไรก็ตามวิธี hook_form_alter ก็ใช้ได้


0

สิ่งที่ฉันพบจนถึงตอนนี้: การใช้แบบฟอร์มแก้ไข hook และลองเปลี่ยนตัวตรวจสอบ / ส่งตัวจัดการใน form form hook เองจะทำงานเฉพาะเมื่อคุณเปลี่ยนตัวจัดการ $ form ['# validate] / $ form [#submit'] (การเรียกใช้ฟังก์ชัน form_state สำหรับสิ่งนี้จะไม่ทำงานในรูปแบบที่แก้ไข hook เอง)

แต่เมื่อคุณลองใช้ตัวจัดการการตรวจสอบความถูกต้องมันจะทำงานได้:

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

นี่เป็นเพราะตอนนี้ฟอร์มได้ถูกสร้างขึ้นอย่างสมบูรณ์แล้วไม่ใช่ในกรณีที่แก้ไขฟอร์มด้วยตัวเอง

แนวคิดคือ: คุณสามารถเพิ่มตัวจัดการการตรวจสอบความถูกต้องเป็นตัวสุดท้ายประเมินตัวจัดการอื่น ๆ ที่มีอยู่สำหรับการส่งและเปลี่ยนที่นั่น

หากคุณต้องการเปลี่ยนเครื่องมือตรวจสอบความถูกต้องตรวจสอบให้แน่ใจว่าคุณใช้งานก่อนหน้าอื่น ๆ และเปลี่ยนแปลงสิ่งที่คุณต้องการในเครื่องมือตรวจสอบความถูกต้อง

ยังคงค้นหาวิธีที่ดีกว่าตัวเองฉันเพียงแค่ต้องแทนที่ตัวจัดการตรวจสอบ / ส่งสำหรับแบบฟอร์มการลงทะเบียนผู้ใช้ แต่อาจมีโมดูลอื่น ๆ ที่ทำให้การใช้งานโมดูลของฉันไม่ดีขึ้น ดังนั้นโมดูลของฉันจะต้องสามารถตรวจสอบสิ่งเหล่านี้และเป็นไปได้ด้วยวิธีนี้ ฉันสงสัยว่ามีบางเอนทิตี้ของฟอร์มหลังจากฟังก์ชัน build มีอยู่เพื่อดึงสิ่งนี้ออก (สิ่งที่ทำงานเมื่อแบบฟอร์มเสร็จสมบูรณ์และกำลังจะจัดส่ง) (นั่นไม่ใช่วิธีที่ซับซ้อนสำหรับกรณีง่าย ๆ นี้)

การข้ามการเปลี่ยนเส้นทางของ save () เป็นไปไม่ได้ แต่การยกเลิกการตั้งค่า save () เป็นการทำด้วยวิธีนี้ (+ ใช้งานของคุณเอง) จริงคลาสจะดีกว่าและให้การเข้าถึงวัตถุ / etc ได้ง่ายขึ้น แต่การเอาชนะคลาสแกนหลักจะนำไปสู่ปัญหาเมื่อโมดูลอื่นต้องการใช้สิ่งเหล่านี้ ไม่เป็นเช่นนั้นหากคุณใช้รหัสนี้


0

หลังจากตรวจสอบปัญหานี้นี่คือสิ่งที่ฉันพบว่าควรเหมาะสมกับกรณีของคุณ:

/**
 * Implements hook_entity_type_alter().
 */
function mymodule_entity_type_alter(&$entity_info) {
 $entity_info['node']->setFormClass('edit','Drupal\mymodule\Form\CustomNodeForm');
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.