मैं मौजूदा फॉर्म / फ़ील्ड में कस्टम सत्यापन हैंडलर कैसे जोड़ूं?


21

मैं Drupal 8 में मौजूदा फॉर्म (या फ़ॉर्म फ़ील्ड) में कस्टम सत्यापन हैंडलर कैसे जोड़ूं?

मेरे पास एक फॉर्म है जिसे मैंने नहीं बनाया है। जब फार्म जमा किया जाता है तो मैं कुछ क्षेत्रों पर अपने सत्यापन नियम जोड़ना चाहता हूं।

Drupal 7 के लिए, एक फॉर्म के लिए कस्टम सत्यापन? लागू करने के लिए बताते हैं hook_form_alter()और फिर अपने सत्यापन हैंडलर] [1] को $form['#validate']सरणी में जोड़ते हैं , लेकिन ड्रुपल 8 रूपों में कक्षाएं हैं। सत्यापन validateForm()विधि के माध्यम से किया जाता है और मुझे नहीं पता कि मैं अपने कोड को कैसे प्लग करूं।



1
यह बिल्कुल डुप्लिकेट नहीं है। मेरा प्रश्न D8 के लिए है, आपका लिंक D7 के लिए है।
AngularChef

अगर मैं POST का उपयोग नहीं कर रहा हूं (मैं किसी मौजूदा दृश्य पृष्ठ पर एक URL प्रस्तुत करना चाहता था) न तो वैद्यमापक और न ही सबमिटफ़ॉर्म चलाते हैं, तो मैं आज इस पर आया हूं और दूसरों के लिए नोट करना चाहता हूं। इस दृष्टि में यह स्पष्ट है .... लेकिन मैंने महसूस करने से पहले इसे जानने का प्रयास करते हुए 30 मिनट बिताए ....:
ben.hamelin

जवाबों:


19

#validateसंपत्ति अभी भी Drupal 8. में प्रयोग किया जाता है (आदि के समाधान के साथ आप मौजूदा सत्यापनकर्ता को पार कर जाएगी)

यदि आप डिफ़ॉल्ट के अतिरिक्त अपना कस्टम सत्यापनकर्ता जोड़ना चाहते हैं, तो आपको हुक_फॉर्म_फॉर्म_आईडी_अल्टर (या इसी तरह) में कुछ इस तरह जोड़ना होगा :

$form['#validate'][] = 'my_test_validate';

धन्यवाद, शाबिर। इसलिए, एक कस्टम सत्यापनकर्ता जोड़ना D7 और D8 में समान है। ;)
AngularChef

बिल्कुल, नोड मॉड्यूल के परामर्श कोड। वहाँ बहुत सारे उदाहरण हैं
शाबिर ए।

2
मैंने बस कोशिश की और यह पूरी तरह से काम किया, धन्यवाद। कृपया ध्यान दें कि डी 8 फॉर्म एपीआई संदर्भ #validateआपके लिंक के लिए क्या कहता है, इसके विपरीत , आपको $form_stateएक सरणी (डी 7 तरीका) के रूप में उपयोग नहीं करना चाहिए , लेकिन एक वस्तु कार्यान्वयन FormStateInterface(डी 8 तरीका) के रूप में। दूसरे शब्दों में, आपके कस्टम सत्यापनकर्ता का कोड उस कोड के अनुरूप होना चाहिए जो आपको एक मूल validateForm()विधि में मिलेगा ।
AngularChef

25

बरदीर ने सही जवाब दिया, कि एक बाधा ड्रुपल 8. एक क्षेत्र में मान्यता जोड़ने के बारे में जाने का सही तरीका है। यहां एक उदाहरण है।

नीचे दिए गए उदाहरण में, मैं एक नोड प्रकार के साथ काम करूंगा podcast, जिसमें एकल मान फ़ील्ड है field_podcast_duration। इस फ़ील्ड के मान को HH: MM: SS (घंटे, मिनट और सेकंड) के रूप में स्वरूपित करने की आवश्यकता है।

एक बाधा बनाने के लिए, दो वर्गों को जोड़ने की आवश्यकता है। पहली बाधा परिभाषा है, और दूसरी बाधा सत्यापनकर्ता है। ये दोनों प्लगइन्स हैं, के नाम स्थान में Drupal\[MODULENAME]\Plugin\Validation\Constraint

सबसे पहले, बाधा परिभाषा। ध्यान दें कि प्लगइन आईडी को क्लास के एनोटेशन (कमेंट) में 'पॉडकास्ट ड्यूरेशन' के रूप में दिया गया है। इसे और नीचे उपयोग किया जाएगा।

namespace Drupal\[MODULENAME]\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;

/**
 * Checks that the submitted duration is of the format HH:MM:SS
 *
 * @Constraint(
 *   id = "PodcastDuration",
 *   label = @Translation("Podcast Duration", context = "Validation"),
 * )
 */
class PodcastDurationConstraint extends Constraint {

  // The message that will be shown if the format is incorrect.
  public $incorrectDurationFormat = 'The duration must be in the format HH:MM:SS or HHH:MM:SS. You provided %duration';
}

अगला, हमें बाधा सत्यापनकर्ता प्रदान करने की आवश्यकता है। इस वर्ग का यह नाम ऊपर से वर्ग का नाम होगा, जिसके Validatorसाथ इसे जोड़ा जाएगा:

namespace Drupal\[MODULENAME]\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

/**
 * Validates the PodcastDuration constraint.
 */
class PodcastDurationConstraintValidator extends ConstraintValidator {

  /**
   * {@inheritdoc}
   */
  public function validate($items, Constraint $constraint) {
    // This is a single-item field so we only need to
    // validate the first item
    $item = $items->first();

    // If there is no value we don't need to validate anything
    if (!isset($item)) {
      return NULL;
    }

    // Check that the value is in the format HH:MM:SS
    if (!preg_match('/^[0-9]{1,2}:[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}$/', $item->value)) {
      // The value is an incorrect format, so we set a 'violation'
      // aka error. The key we use for the constraint is the key
      // we set in the constraint, in this case $incorrectDurationFormat.
      $this->context->addViolation($constraint->incorrectDurationFormat, ['%duration' => $item->value]);
    }
  }
}

अंत में, हम पर हमारे बाधा उपयोग करने के लिए Drupal बताने की आवश्यकता field_podcast_durationपर podcastनोड प्रकार। हम इसमें करते हैं hook_entity_bundle_field_info_alter():

use Drupal\Core\Entity\EntityTypeInterface;

function HOOK_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
  if (!empty($fields['field_podcast_duration'])) {
    $fields['field_podcast_duration']->addConstraint('PodcastDuration');
  }
}

यदि आपको अपने क्षेत्र को मान्य करने के लिए अन्य फ़ील्ड मानों की आवश्यकता है, तो आप सामग्री प्रकार में एक बाधा जोड़ सकते हैं। इस ब्लॉग पोस्ट को देखें: lakshminp.com/entity-validation-drupal-8-part-2
ummdorian

1
D8 फॉर्म वैलिडेशन एपीआई को यहां Drupal.org पर विस्तार से बताया गया है। एक कस्टम सत्यापन बाधा प्रदान करना
सुखजिंदर सिंह

1
चूँकि यह प्रश्न विशेष रूप से फॉर्म एपीआई के बारे में है, फील्ड एपीआई के बारे में नहीं, तो कोई इस बाधा को एक फार्म एलीमेंट (इकाई क्षेत्र नहीं) के साथ कैसे जोड़ता है?
अनारोनबूमन

फार्म तत्वों में अड़चन नहीं हो सकती। आप #element_validate का उपयोग करके किसी विशिष्ट फ़ॉर्म तत्व में सत्यापन जोड़ सकते हैं। इस सूत्र पर शीर्ष उत्तर देखें - यह D8 में D7 drupal.stackexchange.com/questions/86990/…
Jaypan

सुनिश्चित करें कि आप जाँच करें $item = $items->first();और जब तक कुछ भी न हो तो वापस लौटें अन्यथा आपको फ़ील्ड संपादित करते समय एक घातक त्रुटि मिलेगी: TypeError: तर्क 2 Drupal \ Component \ उपयोगिता \ NestedArray को दिया गया: getValue () प्रकार सरणी का होना चाहिए, null दिया गया, जिसे /data/app/core/lib/Drupal/Core/Field/WidgetBase.php में Drupal \ Component \ उपयोगिता \ NestedArray :: getalalue () की लाइन 69 (कोर / lib / Drupal / Component की लाइन 69) में बुलाया गया है। /Utility/NestedArray.php)।
इवान जुगेक

16

नोड जैसी सामग्री इकाई के लिए ऐसा करने का सही तरीका यह है कि इसे एक बाधा के रूप में पंजीकृत किया जाए।

देखें forum_entity_bundle_field_info_alter()और इसी? ForumLeafसत्यापन बाधा (ध्यान दें कि दो वर्गों की आवश्यकता है)।

यह पहली बार में थोड़ा अधिक जटिल है, लेकिन लाभ यह है कि यह सत्यापन एपीआई में एकीकृत है, इसलिए आपकी मान्यता फार्म प्रणाली तक सीमित नहीं है, लेकिन उदाहरण के लिए, आरईएसटी एपीआई के माध्यम से प्रस्तुत नोड्स के साथ भी काम कर सकते हैं।


अच्छी बात: यह कुछ नया है जो Drupal 7 के लिए कोड लिखने के लिए उपयोग किया जाता है। मुझे यकीन है कि कई उपयोगकर्ता हैं जो एक बाधा को अधिक उपयुक्त होने पर सत्यापन संचालकों को जोड़ने की कोशिश करेंगे।
kiamlaluno

बर्दिर: मैंने इस विकल्प को लागू करने का प्रयास करके पता लगाया hook_entity_bundle_field_info_alter()(जैसा कि यहाँ वर्णित है ) लेकिन इसने कभी काम नहीं किया ... इस हुक के साथ एक प्रलेखित समस्या प्रतीत होती है: drupal.org/node/2346347
15

कुछ समस्याएं हैं लेकिन मुझे नहीं लगता कि वे आपकी समस्या से संबंधित हैं। forum.module दिखाता है कि यह काम करता है। अपना कोड साझा करें, अन्यथा आपके कार्यान्वयन में संभव समस्याओं को इंगित करना संभव नहीं है।
बरदिर

1
मैं इस विधि के साथ जाना चाहता हूं, लेकिन जब तक कि यह जांचने का कोई अच्छा उदाहरण नहीं है कि डेटा प्रकार के साथ इसका उपयोग कैसे किया जाए (अर्थात फ़ील्ड विशिष्ट नहीं) यह जांचने के लिए कि कुछ बाहरी स्थिति पूरी हो गई है, तो मैं फॉर्म अलर्ट के साथ फंस गया हूं। इस लेख में खुदाई नहीं हुई। क्या कोई कृपया मुझे कहीं उपयोगी बताएगा, या यहाँ पोस्ट करेगा? धन्यवाद।
कॉलन

क्या होगा यदि हमें मौजूदा सत्यापन जैसे \ Drupal \ user \ Form \ UserLoginForm को जोड़ने की आवश्यकता है :: validateName ()। D7 में यह $ फॉर्म ['# मान्य'] = सरणी ('user_login_name_validate', 'myother_validaion') के रूप में सरल था; लेकिन ऐसा लगता है कि नो-
कॉन्ट्रिब

8

मैं इस मामले पर कुछ और प्रकाश डालना चाहता हूं। सत्यापन जोड़ने का कार्य पहले जैसा ही है: हुक_फॉर्म_ल्टर में:

$form['#validate'][] = '_form_validation_number_title_validate';

मान फ़ंक्शन में $ form_state के अंदर मान ऑब्जेक्ट का उपयोग हालांकि थोड़ा अलग है। उदाहरण के लिए:

function _form_validation_number_title_validate(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {

  if ($form_state->hasValue('title')) {
     $title = $form_state->getValue('title');

     if (!is_numeric($title[0]['value'])) {
        $form_state->setErrorByName('title', t('Your title should be number'));
     }

  }
}

तो निजी चर वस्तु तक सीधी पहुंच के साथ नहीं, बल्कि एक गटर फ़ंक्शन के साथ।

अधिक जानकारी के लिए आप मेरे github में एक पूरा उदाहरण देख सकते हैं: https://github.com/flesheater/drupal8_modules_experiments/blob/master/webham_formvalidation/webham_nvalvalidation.module

चियर्स!


वास्तव में यह है। जैसा मैंने ऊपर अपनी टिप्पणी में लिखा है। ;)
AngularChef

7

यह बहुत हद तक डी 7 की तरह ही है। एक पूर्ण उदाहरण:

mymodule.module :

use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_form_FORM_ID_alter() for the FORM_ID() form.
 */
function mymodule_form_FORM_ID_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['#validate'][] = '_mymodule_form_FORM_ID_validate';
}

/**
 * Validates submission values in the FORM_ID() form.
 */
function _mymodule_form_FORM_ID_validate(array &$form, FormStateInterface $form_state) {
  // Validation code here
}

यह काफी करीब है। केवल hook_form_FORM_ID_alterफॉर्म आईडी की जरूरत है। आपके पास कस्टम सत्यापन फ़ंक्शन कुछ भी हो सकता है जो आप चाहते हैं। इसके अलावा, उचित मापदंडों के लिए यहां एपीआई गाइड का पालन ​​करें ।
mikeDOTexe

इससे पहले, फॉर्म आईडी को कैसे प्राप्त करें, इस कोड को कहां जांचें।
लोगेश्वरान

3

इन अच्छे उत्तरों के पूरक में मैं जोड़ूंगा:

$form['#validate'][] = 'Drupal\your_custom_module_name\CustomClass::customValidate';

प्रपत्र सत्यापन के लिए दूर वर्ग विधि को कॉल करना है। मुझे लगता है कि बेहतर है तो दिए गए उदाहरण में मॉड्यूल फ़ाइल में उपरोक्त फ़ंक्शन को कॉल करना।


अब OO से प्रक्रियात्मक कोड में कूदने की आवश्यकता नहीं है।
15

1

आप क्लाइंटसाइड वैलिडेशन मॉड्यूल का उपयोग कर सकते हैं । इसके बारे में कुछ और विवरण (इसके परियोजना पृष्ठ से):

... jquery.validate का उपयोग करते हुए सभी रूपों और वेबफॉर्म के लिए क्लाइंटसाइड सत्यापन (उर्फ "अजाक्स फॉर्म वैधीकरण") जोड़ता है । शामिल jquery.validate.js फ़ाइल खाली है क्योंकि हमें खाली संदेशों को छिपाने में सक्षम होने की आवश्यकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.