মাল্টিস্টেপ / উইজার্ড ফর্মগুলি


10

আমি ড্রুপাল 8 এর জন্য একটি মাল্টিস্টেপ / উইজার্ড ফর্ম তৈরি করার চেষ্টা করছি।

  • ব্যবহারকারী একটি প্রথম নাম, শেষ নাম ক্ষেত্র পূরণ করে
  • পরবর্তী বোতামে ক্লিক করুন
  • আরও তথ্য পূরণ করে
  • জমা বাটনে ক্লিক করুন

বর্তমানে অনেক সম্পদ ভালো Drupal এর 7 এর জন্য multistep বা উইজার্ড ফরম অনুগত আছে এক এবং এই

অন্যদিকে, আমি বুঝতে খুব সমস্যা পেয়েছি যা ড্রুপাল 8 মাল্টিস্টেপ / উইজার্ড ফর্ম তৈরির "দ্রুপাল" উপায়।

আমি কিছু গবেষণা করেছি এবং অনুভূত করেছি যে কয়েকটি পদ্ধতি রয়েছে:

ড্রুপাল 8 এর জন্য সেই বৈধ পন্থাগুলি কি?

উত্তর:


12

এটি করার সবচেয়ে সহজ উপায় হ'ল $ form_state ব্যবহার করা। আপনার ফর্ম বিল্ড () পদ্ধতিতে আপনার একটি / অন্যথায় বা $form_state['step']ভিন্ন রূপের উপাদানগুলির মতো কোনও কিছুর উপর ভিত্তি করে স্যুইচ করুন । তারপরে আপনার হয় আপনার জমা দেওয়া কলব্যাকে একই রকম থাকে বা একাধিক জমা কলব্যাক থাকে, যা আপনি তৈরি করছেন $ ফর্ম_স্টেটে কোনও বস্তুর সাথে কিছু করে, পদক্ষেপটি পরিবর্তন করে $form_state['rebuild']পতাকাটি সত্যে সেট করে set

এই পদ্ধতির কয়েকটি ডাউনসাইড রয়েছে, এ কারণেই (অন্যান্য কারণে) কোটলস ফর্ম উইজার্ড তৈরি হয়েছিল। এটি জটিল হতে পারে যদি আপনার একাধিক পদক্ষেপ থাকে এবং সেগুলি সমস্ত একক ফর্ম ফাংশন / শ্রেণিতে সংজ্ঞায়িত করতে হয় এবং পোস্টের অনুরোধে সবকিছু ঘটে।

কোটলগুলি উইজার্ড যা করে তা হ'ল গ্রুপ একাধিক, একসাথে পৃথক ফর্ম এবং এক থেকে অন্যটিতে নেভিগেশন নিয়ন্ত্রণ করে। আপনি object form_state এর পরিবর্তে আপনার অবজেক্ট সংরক্ষণ করার জন্য সিটিওলজ অবজেক্ট ক্যাশেও ব্যবহার করেন, কারণ এটি আপনার ফর্মগুলির মধ্যে আর ভাগ করা নেই।

যদিও সিস্টেম এখনো বিদ্যমান নয়, ctools একটি পরিসেবা হিসাবে, বস্তুর প্রাপ্তিসাধ্য ক্যাশে 8.x বৈশিষ্ট্যসমূহ নিয়ে আসা হয়েছে এবং এখন ব্যবহারকারী tempstore বলা হয়: \Drupal::service('user.private_tempstore')(সামনে 8.0-beta8 নামক user.tempstore)। এটি মেয়াদোত্তীর্ণ মূল মান স্টোরের উপরে একটি স্তর যা সেখানে সঞ্চিত ডেটার মালিকানার পরিচয় দেয়। সুতরাং এটি হ'ল সুপরিচিত বার্তাগুলিকে এমন দৃশ্যে শক্তিশালী করে যে কোনও ভিন্ন ব্যবহারকারী বর্তমানে সেই ভিউটি সম্পাদনা করছেন এবং সেই কারণে এটি লক হয়ে গেছে। এর জন্য $ _SESSION ব্যবহার করার আরেকটি সুবিধা হ'ল প্রয়োজন অনুসারে কেবলমাত্র আপনার ডেটাটি লোড করতে হবে, আপনি যখন 3 টি ভিউ সম্পাদনা করছেন, তখন $ _SESSION ব্যবহার করার অর্থ হ'ল প্রতিটি পৃষ্ঠার অনুরোধে আপনাকে এগুলি লোড করে নিয়ে যেতে হবে।

আপনার যদি এটির প্রয়োজন না হয়, তবে আপনি সেশনের উপর নির্ভর করতে পারেন বা এটি সরাসরি একটি এক্সপ্রেসযোগ্য মূল মান স্টোরে রেখে দিতে পারেন ($ ফর্ম_স্টেটটি এখন সেখানে সঞ্চিত রয়েছে, এটি ছদ্ম-ক্যাশে যেমন x.x ছিল)।

কনফিগারেশন সিস্টেমটি কোনও ভাল মিল নয়। এটি প্রতি ব্যবহারকারী সামগ্রীর (বা সামগ্রীতে সামগ্রীর জন্য) বোঝানো হয়নি কারণ এটি হাজার হাজার বা কয়েক হাজার রেকর্ড সংরক্ষণ করার জন্য সত্যই স্কেল করে না এবং প্রদত্ত পৃষ্ঠার অনুরোধে এটির প্রয়োজন হতে পারে এমন সমস্ত কিছু প্রাক-লোড করার জন্য কিছু অনুমান করা যেতে পারে ( এখনও না, তবে এটি ঘটানোর জন্য একটি সমস্যা রয়েছে)


আপনার উত্তর সম্পর্কে আরও একটি প্রশ্ন। এটি একটি নির্বোধ প্রশ্ন হতে পারে: \ দ্রুপাল :: পরিষেবা ('user.tempstore') বেনাম ব্যবহারকারীদের জন্যও কি উপলব্ধ?
খ্রিস্টলি

হ্যাঁ, এটি অযৌক্তিক ব্যবহারকারীর জন্য সেশন আইডিতে ফিরে আসে। দেখুন api.drupal.org/api/drupal/…
বারদির

4

সাধারণত আপনি সিটিউলস অবজেক্ট ক্যাশে ( দ্রুপাল in- তে মাল্টিসট্যাপ ফর্মের অনুরূপ ), অথবা $form_state(এই টিউটোরিয়াল অনুসারে ) ব্যবহার করে ধাপগুলির মধ্যে ফর্ম মান সংরক্ষণ করতে পারেন ।

ড্রুপাল 8 এ আপনি FormBaseএকটি নতুন মাল্টিস্টেপ ক্লাস তৈরি করতে বর্গ উত্তরাধিকারী হতে পারেন।

দ্রুপাল 8-এ মাল্টি-স্টেপ ফর্মগুলি কীভাবে তৈরি করবেন সেই নিবন্ধে আপনি দ্রুপাল 8- তে একটি মাল্টিস্টেপ ফর্ম তৈরি করার একটি সহজ উপায় খুঁজে পেতে পারেন।

প্রথমত, আপনাকে বেস শ্রেণি তৈরি করতে হবে যা প্রয়োজনীয় নির্ভরতাগুলি ইনজেকশনের দায়িত্বে থাকবে।

আমরা সমস্ত ফর্ম ক্লাস একসাথে গ্রুপ করব এবং সেগুলি আমাদের ডেমো মডিউলটির প্লাগইন ডিরেক্টরিতে Multistepঅবস্থিত একটি নতুন ফোল্ডারের ভিতরে রাখব Form। এটি বিশুদ্ধরূপে একটি পরিষ্কার কাঠামো থাকার জন্য এবং কোন ফর্মগুলি আমাদের মাল্টিস্টেপ ফর্ম প্রক্রিয়াটির অংশ তা দ্রুত তা জানাতে সক্ষম হবার জন্য is

এখানে ডেমো কোড ( MultistepFormBase.phpফাইলের জন্য ):

/**
 * @file
 * Contains \Drupal\demo\Form\Multistep\MultistepFormBase.
 */

namespace Drupal\demo\Form\Multistep;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\SessionManagerInterface;
use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;

abstract class MultistepFormBase extends FormBase {

  /**
   * @var \Drupal\user\PrivateTempStoreFactory
   */
  protected $tempStoreFactory;

  /**
   * @var \Drupal\Core\Session\SessionManagerInterface
   */
  private $sessionManager;

  /**
   * @var \Drupal\Core\Session\AccountInterface
   */
  private $currentUser;

  /**
   * @var \Drupal\user\PrivateTempStore
   */
  protected $store;

  /**
   * Constructs a \Drupal\demo\Form\Multistep\MultistepFormBase.
   *
   * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
   * @param \Drupal\Core\Session\SessionManagerInterface $session_manager
   * @param \Drupal\Core\Session\AccountInterface $current_user
   */
  public function __construct(PrivateTempStoreFactory $temp_store_factory, SessionManagerInterface $session_manager, AccountInterface $current_user) {
    $this->tempStoreFactory = $temp_store_factory;
    $this->sessionManager = $session_manager;
    $this->currentUser = $current_user;

    $this->store = $this->tempStoreFactory->get('multistep_data');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('user.private_tempstore'),
      $container->get('session_manager'),
      $container->get('current_user')
    );
  }

  /**
   * {@inheritdoc}.
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    // Start a manual session for anonymous users.
    if ($this->currentUser->isAnonymous() && !isset($_SESSION['multistep_form_holds_session'])) {
      $_SESSION['multistep_form_holds_session'] = true;
      $this->sessionManager->start();
    }

    $form = array();
    $form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = array(
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
      '#button_type' => 'primary',
      '#weight' => 10,
    );

    return $form;
  }

  /**
   * Saves the data from the multistep form.
   */
  protected function saveData() {
    // Logic for saving data goes here...
    $this->deleteStore();
    drupal_set_message($this->t('The form has been saved.'));

  }

  /**
   * Helper method that removes all the keys from the store collection used for
   * the multistep form.
   */
  protected function deleteStore() {
    $keys = ['name', 'email', 'age', 'location'];
    foreach ($keys as $key) {
      $this->store->delete($key);
    }
  }
}

তারপরে আপনি ফাইল হিসাবে প্রকৃত ফর্ম শ্রেণি তৈরি করতে পারেন MultistepOneForm.php:

/**
 * @file
 * Contains \Drupal\demo\Form\Multistep\MultistepOneForm.
 */

namespace Drupal\demo\Form\Multistep;

use Drupal\Core\Form\FormStateInterface;

class MultistepOneForm extends MultistepFormBase {

  /**
   * {@inheritdoc}.
   */
  public function getFormId() {
    return 'multistep_form_one';
  }

  /**
   * {@inheritdoc}.
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    $form = parent::buildForm($form, $form_state);

    $form['name'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Your name'),
      '#default_value' => $this->store->get('name') ? $this->store->get('name') : '',
    );

    $form['email'] = array(
      '#type' => 'email',
      '#title' => $this->t('Your email address'),
      '#default_value' => $this->store->get('email') ? $this->store->get('email') : '',
    );

    $form['actions']['submit']['#value'] = $this->t('Next');
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $this->store->set('email', $form_state->getValue('email'));
    $this->store->set('name', $form_state->getValue('name'));
    $form_state->setRedirect('demo.multistep_two');
  }
}

ইন buildForm()পদ্ধতি আমরা আমাদের দুই ডামি ফর্ম উপাদানের সংজ্ঞা করছে। লক্ষ্য করুন যে আমরা পিতামাত্ত শ্রেণীর থেকে বিদ্যমান ফর্ম সংজ্ঞাটি পুনরুদ্ধার করছি। এই ক্ষেত্রগুলির জন্য ডিফল্ট মানগুলি সেই কীগুলির জন্য স্টোরের মধ্যে পাওয়া মান হিসাবে সেট করা হয় (যাতে ব্যবহারকারীরা এই পদক্ষেপে তারা পূরণ করা মানগুলি যদি তারা ফিরে আসে তবে তারা দেখতে পারে)। অবশেষে, আমরা অ্যাকশন বোতামের মানটিকে নেক্সটে পরিবর্তন করছি (এই ফর্মটি চূড়ান্ত নয় এটি বোঝাতে)।

ইন submitForm()পদ্ধতি আমরা দোকান থেকে পেশ মান সংরক্ষণ এবং তারপর দ্বিতীয় ফর্ম (রুট এ পাওয়া যাবে যা পুনর্নির্দেশ demo.multistep_two)। মনে রাখবেন যে কোডটি হালকা রাখতে আমরা এখানে কোনও ধরণের বৈধতা করছি না। তবে বেশিরভাগ ব্যবহারের ক্ষেত্রে কিছু ইনপুট বৈধতার জন্য ডাকা হবে।

এবং ডেমো মডিউলটিতে আপনার রাউটিং ফাইল আপডেট করুন ( demo.routing.yml):

demo.multistep_one:
  path: '/demo/multistep-one'
  defaults:
    _form: '\Drupal\demo\Form\Multistep\MultistepOneForm'
    _title: 'First form'
  requirements:
    _permission: 'access content'
demo.multistep_two:
  path: '/demo/multistep-two'
  defaults:
    _form: '\Drupal\demo\Form\Multistep\MultistepTwoForm'
    _title: 'Second form'
  requirements:
    _permission: 'access content'

শেষ অবধি, দ্বিতীয় ফর্মটি তৈরি করুন ( MultistepTwoForm):

/**
 * @file
 * Contains \Drupal\demo\Form\Multistep\MultistepTwoForm.
 */

namespace Drupal\demo\Form\Multistep;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

class MultistepTwoForm extends MultistepFormBase {

  /**
   * {@inheritdoc}.
   */
  public function getFormId() {
    return 'multistep_form_two';
  }

  /**
   * {@inheritdoc}.
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    $form = parent::buildForm($form, $form_state);

    $form['age'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Your age'),
      '#default_value' => $this->store->get('age') ? $this->store->get('age') : '',
    );

    $form['location'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Your location'),
      '#default_value' => $this->store->get('location') ? $this->store->get('location') : '',
    );

    $form['actions']['previous'] = array(
      '#type' => 'link',
      '#title' => $this->t('Previous'),
      '#attributes' => array(
        'class' => array('button'),
      ),
      '#weight' => 0,
      '#url' => Url::fromRoute('demo.multistep_one'),
    );

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $this->store->set('age', $form_state->getValue('age'));
    $this->store->set('location', $form_state->getValue('location'));

    // Save the data
    parent::saveData();
    $form_state->setRedirect('some_route');
  }
}

submitForm()পদ্ধতির অভ্যন্তরে আমরা আবার স্টোরগুলিতে মানগুলি সংরক্ষণ করি এবং এই ডেটাটিকে যেভাবে উপযুক্ত মনে হয় ততটুকু ধরে রাখতে পিতামাতার ক্লাসে মুলতবি। তারপরে আমরা আমাদের যে পৃষ্ঠাটি চাই সেগুলিতে পুনঃনির্দেশ করি (আমরা এখানে যে রুটটি ব্যবহার করি এটি একটি ডামি একটি)।

আমাদের এখন একটি কার্যকরী মাল্টিস্টিপ ফর্ম থাকা উচিত যা PrivateTempStoreএকাধিক অনুরোধ জুড়ে ডেটা উপলব্ধ রাখতে ব্যবহার করে । আমাদের যদি আরও পদক্ষেপের প্রয়োজন হয় তবে আমাদের আরও কিছু ফর্ম তৈরি করতে হবে, বিদ্যমান বিদ্যমানগুলির মধ্যে এগুলি যুক্ত করতে হবে এবং বেশ কয়েকটি সমন্বয় করতে হবে।


1

Multistep জাদুকর যে আপনাকে উল্লেখ করেছি, এটি আগে থেকেই CTools সাথে একত্রিত হচ্ছে, দেখুন: উইজার্ড সাপোর্ট 8.x-3.x জন্য , যাতে আপনি এটা ব্যাপ্ত বিবেচনা করতে পারে your_module.services.yml, যেমন

services:
  ctools.wizard.form:
    class: Drupal\MyModuleMultistep\Controller\MyWizardForm

তারপরে ক্লাসটি প্রসারিত করুন src/Controller/MyWizardForm.php:

<?php

/**
 * @file
 * Contains \Drupal\MyModuleMultistep\Controller\MyWizardForm
 */

namespace Drupal\MyModuleMultistep\Controller;

/**
 * Wrapping controller for wizard forms that serve as the main page body.
 */
class MyWizardForm extends WizardFormController {

}

আপনি কি এমন একটি উদাহরণ জানেন যা সিটিউলস মাল্টিসটপ উইজার্ডটি কীভাবে ব্যবহার করতে হয় তা বুঝতে সহায়তা করতে পারে?
ডানকানমু

1
@ ডানকানমু আমার নেই, তবে আপনার যে নির্দিষ্ট সমস্যা রয়েছে তা নিয়ে আরও একটি প্রশ্ন জিজ্ঞাসা করতে বা নির্দ্বিধায় Tests/Wizard/CToolsWizard*ফাইলগুলি দেখুন যেখানে আপনি কয়েকটি পরীক্ষা (উদাহরণস্বরূপ testWizardSteps) পেতে পারেন ।
কেনারব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.