एक मौजूदा रूप बदलो


12

हम ड्रुपल 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 8 अभी भी समर्थन करता है hook_form_alter()। यदि आपको केवल फॉर्म को पुनर्निर्देशित करने की आवश्यकता है, तो यह एक फॉर्म सबमिशन हैंडलर जोड़ने के लिए पर्याप्त है जो रीडायरेक्ट करता है।
kiamlaluno

@kiamlaluno मुझे लगता है कि जवाब होना चाहिए :)
Berdir

@Berdir अकेले बहुत मददगार नहीं होगा, मुझे डर है: Drupal 8 का मेरा ज्ञान बहुत सीमित है। साथ ही, ओपी को स्पष्ट करना चाहिए कि " save()विधि में परिवर्तन " वास्तव में क्या है। क्या इसका मतलब है कि डेटा को सहेजने के तरीके को बदलना, या सिर्फ एक रीडायरेक्ट करना है? पहले मामले में, उत्तर अधिक जटिल है।
kiamlaluno

उत्तर के लिए @kiamlaluno Thx। इस मामले में हमें केवल बचत () के बाद पुनर्निर्देशित करने की आवश्यकता है, इसलिए आपका जवाब काम करना चाहिए। लेकिन मुझे यह भी दिलचस्पी थी कि कैसे सही ड्रुपल 8 तरीके से फॉर्म में अन्य चीजों को बदलना है। उदाहरण के लिए परिवर्तन कैसे इसे सहेजा जाता है, या फ़ील्ड को फ़ॉर्म में जोड़ें .. आदि ..
जेन्स स्टेपी

जवाबों:


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

ऐसा लगता है कि आप क्या करना चाहते हैं, यह वास्तव में बचत पद्धति को बदलने के लिए नहीं है, लेकिन नोड को सहेजे जाने पर रीडायरेक्ट को बदलने के लिए है।

इस स्थिति में, ड्रुपल 7 की तरह, hook_form_alterकस्टम सबमिट हैंडलर (फॉर्म या बटन पर, फॉर्म और आवश्यकता के आधार पर) के साथ बहुत कुछ करना एक अच्छा समाधान होगा।

जब आप प्रश्न में वर्णन करते हैं तो यह भी काम करता है, लेकिन मैं आधार वर्ग को अधिलेखित करने से बचूंगा, जब तक कि मैं वास्तव में कक्षा में कुछ बदलना नहीं चाहता।

सेव मेथड का उपयोग सिर्फ एक सबमिट हैंडलर के रूप में किया जाता है, इसलिए केवल रीडायरेक्ट को जोड़ने के लिए अधिलेखित करने का कोई मतलब नहीं है।


0

मुझे लगता है कि बेहतर तरीका अभी भी form_alter परिवार से एक हुक का उपयोग करना है, एक सबमिट हैंडलर संलग्न किया है, और उस के भीतर अपने रीडायरेक्ट को सेट करें।

ऐसा करने के लिए आधार वर्गों का विस्तार करना मेरी राय में बालों वाला है। खासकर जब से कोई फ़ंक्शन नहीं बदल रहा है, बस पुनर्निर्देशित कर रहा है।


0

आप एक नया EventSubscriber बना सकते हैं जो कर्नेल की सुनता है :: अनुरोध घटना, और तब प्रतिक्रिया करें जब आप एक नोड फॉर्म सबमिट कर रहे हैं, कुछ इस तरह से

वैसे भी hook_form_alter तरीका ठीक काम करता है।


0

मुझे अब तक क्या मिला: एक फॉर्म को बदलने के हुक को लागू करना और वैद्युत रूप में हुक / सबमिट हैंडलर को बदलने की कोशिश करें हुक तभी काम करता है जब आप $ फॉर्म ['# मान्य] / $ फॉर्म [#submit'] हैंडलर को बदलते हैं। (फ़ॉर्म को हुक में बदलने के लिए इस अभ्यस्त कार्य के लिए form_state फ़ंक्शन कॉल करना)

लेकिन जब आप एक सत्यापन हैंडलर के अंदर यह कोशिश करते हैं, तो यह काम करता है:

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

ऐसा इसलिए है क्योंकि फॉर्म अब पूरी तरह से बनाया गया है, न कि फॉर्म में मामला ही हुक में बदलाव करता है।

विचार यह है: आप पिछले एक के रूप में एक सत्यापन हैंडलर जोड़ सकते हैं, जमा के लिए मौजूद अन्य हैंडलर का मूल्यांकन कर सकते हैं, और उन्हें वहीं बदल सकते हैं।

यदि आप सत्यापन करने वाले हैंडलर को भी बदलना चाहते हैं, तो सुनिश्चित करें कि आपका किसी अन्य से पहले चलता है और जो आप चाहते हैं उसे मान्य हैंडलर में बदलें।

अभी भी अपने आप को बेहतर तरीके से खोज रहा है, मुझे हमेशा उपयोगकर्ता रजिस्टर फॉर्म के लिए मान्य / सबमिट हैंडलर को बदलने की आवश्यकता है। लेकिन अन्य मॉड्यूल मौजूद हो सकते हैं जो मेरे मॉड्यूल कार्यान्वयन को तोड़ते हैं। इसलिए मेरे मॉड्यूल को इनकी जांच करने में सक्षम होना चाहिए, और यह इस तरह संभव है। मुझे आश्चर्य होता है कि बिल्ड फंक्शन के बाद कुछ इकाई बनती है जो इसे बंद करने के लिए मौजूद है। (ऐसा कुछ जो फॉर्म पूरा होने के बाद चलता है और डिलीवर होने वाला है) (इस सरल मामले के लिए यह जटिल नहीं है)

सहेजें () विधि के पुनर्निर्देशन को दरकिनार करना संभव नहीं है, लेकिन इस तरीके से () अपने तरीके से लागू करने के माध्यम से सहेजना () को परेशान करना है। सच है, एक वर्ग अच्छा है और वस्तुओं / आदि के लिए आसान पहुँच प्रदान करता है, लेकिन एक मुख्य वर्ग को ओवरराइड करने से वास्तव में उन मुद्दों की ओर जाता है जब अन्य मॉड्यूल इनका उपयोग करना चाहते हैं। यदि आप इस कोड का उपयोग करते हैं तो ऐसा नहीं है।


0

इस समस्या की जाँच करने के बाद, यह वही है जो मैंने पाया है कि आपके मामले के अनुरूप होना चाहिए:

/**
 * Implements hook_entity_type_alter().
 */
function mymodule_entity_type_alter(&$entity_info) {
 $entity_info['node']->setFormClass('edit','Drupal\mymodule\Form\CustomNodeForm');
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.