如何在 drupal 8 中使用预览数据填充页面构建 Multi-step 表单?
How to Build Multi-step Forms with Preview data fill page in drupal 8?
很多天我在 drupal 8 自定义表单模块上工作,它是 multi-step 表单我已经使用 SessionManagerInterface 完成了这个工作正常但是我想在提交之前在一页中显示所有数据我该如何实现这个.这里我包括 snapshot here
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'ent'
MultistepFormBase.php
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',
'#attributes' => array(
'class' => array(
'btn btn-register'
),
),
);
return $form;
}
MultistepOneForm.php child 形式
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['fname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Your name'),
'#default_value' => $this->store->get('fname') ? $this->store->get('fname') : '',
'#attributes' => array(
'class' => array(
'form-control'
),
),
);
$form['lname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Your Last Name'),
'#default_value' => $this->store->get('lname') ? $this->store->get('lname') : '',
'#attributes' => array(
'class' => array(
'form-control'
),
),
$form['actions']['submit']['#value'] = $this->t('Continue');
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->store->set('fname', $form_state->getValue('fname'));
$this->store->set('lname', $form_state->getValue('lname'));
$form_state->setRedirect('demo.multistep_two');
}
}
MultistepTwoForm.php
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['jfname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Joint Account Holder First Name'),
'#attributes' => array(
'class' => array(
'form-control'
),
),
);
$form['jlname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Joint Account Holder Last Name'),
'#attributes' => array(
'class' => array(
'form-control'
),
),
);
$form['actions']['previous'] = array(
'#type' => 'link',
'#title' => $this->t('Previous'),
'#url' => Url::fromRoute('demo.multistep_one'),
'#suffix' => '</div>',
'#attributes' => array(
'class' => array(
'btn btn-register'
),
),
);
$form['actions']['submit']['#value'] = $this->t('Continue');
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->store->set('jfname', $form_state->getValue('jfname'));
$this->store->set('jlname', $form_state->getValue('jlname'));
// $form_state->setRedirect('demo.multistep_three');
}
}
这里提出了我的顾虑如何根据我的snapshot.what动作显示所有数据需要采取显示数据。一件事是我有 3 个月的 drupal 经验,所以无法决定我将做什么?此代码是 www.sitepoint.com 的示例,我采用表格三,会话数据显示在标签中,无论它是否好,我不知道给我适当的方向
提前致谢
在您的设置中,您将在 MultistepTwoForm 中提交多表单。
更改如下:
- 再构建一种形式:MultiStepPreview。这将保留您的预览。
- 不要在 MultistepTwoForm 中提交表单,而是使用
$form_state->setRedirect()
将表单重定向到 MultiStepPreview
在多步预览中:
- 读取商店中的钥匙
- 构建一个包含预览的表单元素(我制作了一个 html table 来包含预览)
提交表格。
class OverviewForm extends MultiStepFormBase {
public function buildForm(array $form, FormStateInterface $form_state) {
// get data from the store
$your_details = $this->store->get('your_details');
$order = $this->store->get('order_details');
// make a HTML table containing the data in store
$markup = '<table>';
// loop through $your_details and $your_order and put them in $markup
$form = parent::buildForm($form, $form_state);
$form['preview'] = [
'#markup' => $markup,
];
//in my setup all the buttons are build by MultiStepFormBase
return $form;
}
}
很多天我在 drupal 8 自定义表单模块上工作,它是 multi-step 表单我已经使用 SessionManagerInterface 完成了这个工作正常但是我想在提交之前在一页中显示所有数据我该如何实现这个.这里我包括 snapshot here
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'ent'
MultistepFormBase.php
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',
'#attributes' => array(
'class' => array(
'btn btn-register'
),
),
);
return $form;
}
MultistepOneForm.php child 形式
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['fname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Your name'),
'#default_value' => $this->store->get('fname') ? $this->store->get('fname') : '',
'#attributes' => array(
'class' => array(
'form-control'
),
),
);
$form['lname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Your Last Name'),
'#default_value' => $this->store->get('lname') ? $this->store->get('lname') : '',
'#attributes' => array(
'class' => array(
'form-control'
),
),
$form['actions']['submit']['#value'] = $this->t('Continue');
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->store->set('fname', $form_state->getValue('fname'));
$this->store->set('lname', $form_state->getValue('lname'));
$form_state->setRedirect('demo.multistep_two');
}
}
MultistepTwoForm.php
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['jfname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Joint Account Holder First Name'),
'#attributes' => array(
'class' => array(
'form-control'
),
),
);
$form['jlname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Joint Account Holder Last Name'),
'#attributes' => array(
'class' => array(
'form-control'
),
),
);
$form['actions']['previous'] = array(
'#type' => 'link',
'#title' => $this->t('Previous'),
'#url' => Url::fromRoute('demo.multistep_one'),
'#suffix' => '</div>',
'#attributes' => array(
'class' => array(
'btn btn-register'
),
),
);
$form['actions']['submit']['#value'] = $this->t('Continue');
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->store->set('jfname', $form_state->getValue('jfname'));
$this->store->set('jlname', $form_state->getValue('jlname'));
// $form_state->setRedirect('demo.multistep_three');
}
}
这里提出了我的顾虑如何根据我的snapshot.what动作显示所有数据需要采取显示数据。一件事是我有 3 个月的 drupal 经验,所以无法决定我将做什么?此代码是 www.sitepoint.com 的示例,我采用表格三,会话数据显示在标签中,无论它是否好,我不知道给我适当的方向 提前致谢
在您的设置中,您将在 MultistepTwoForm 中提交多表单。 更改如下:
- 再构建一种形式:MultiStepPreview。这将保留您的预览。
- 不要在 MultistepTwoForm 中提交表单,而是使用
$form_state->setRedirect()
将表单重定向到 MultiStepPreview
在多步预览中:
- 读取商店中的钥匙
- 构建一个包含预览的表单元素(我制作了一个 html table 来包含预览)
提交表格。
class OverviewForm extends MultiStepFormBase { public function buildForm(array $form, FormStateInterface $form_state) { // get data from the store $your_details = $this->store->get('your_details'); $order = $this->store->get('order_details'); // make a HTML table containing the data in store $markup = '<table>'; // loop through $your_details and $your_order and put them in $markup $form = parent::buildForm($form, $form_state); $form['preview'] = [ '#markup' => $markup, ]; //in my setup all the buttons are build by MultiStepFormBase return $form; }
}