Пытаюсь передать аргумент при вызове формы в своем модуле:
<?php $variables['form'] = \Drupal::formBuilder()->getForm('Drupal\mymodule\Form\MyForm', $arg); ?>
в функции <?php buildForm(array $form, FormStateInterface $form_state) ?>
можно получить аргумент через
<?php $arg = $form_state->getBuildInfo()['args'][0]; ?>
а как передать свой аргумент в getFormId() ? функция не принимает аргументы.
Хочу динамически присваивать id формы:
<?php return 'my_form_' . $arg; ?>
Комментарии
Почему так сложно? Обычно принимаемые параметры можно перечислить в определении
::buildForm
, типа:<?php buildForm(array $form, FormStateInterface $form_state, $args = NULL) ?>
Малопонятно со стороны, зачем это нужно, но можно попробовать сохранить полученный в вызове
::buildForm
(или лучше в конструкторе класса формы) аргумент в предварительно созданную переменную класса, например,$this->custom_form_id
. Дальше возвращать именно её изgetFormId()
, типа такого:<?php
...
protected $custom_form_id = NULL;
...
public function getFormId() {
return $this->custom_form_id;
}
...
public function buildForm(array $form, FormStateInterface $form_state, $args = NULL) {
$this->custom_form_id = $args;
}
...
?>
Однако, думается, что
::getFormId()
вызывается ядром раньше::buildForm()
, стало быть такой финт ушами может быть бесполезен в принципе. Тогда остаётся пытаться копать вариант с передачей нужного ID формы в конструктор класса формы (который, разумеется, сначала нужно имплементировать).https://git.drupalcode.org/project/commerce/-/blob/8.x-2.x/modules/cart/...
Вот хороший пример, но это форма сущности, там она вызывается немного по особенному, но можно посмотреть как.
Спасибо! Нашел рабочий пример кода в модуле Poll. Реализовано примерно как вы описываете - объявляется переменная класса и метод для присвоения переменной заранее, инициализируется класс формы, передается переменная через метод присвоения, потом экземпляр класса передается на форм билдер.
В классе формы:
<?php
protected $poll;
public function
setPoll(PollInterface $poll) {$this->poll = $poll;
}
public function
getFormId() {return 'poll_view_form_' . $this->poll->id();
}
?>
Вызов билдера формы:
<?php
$form_object = \Drupal::service('class_resolver')->getInstanceFromDefinition('Drupal\poll\Form\PollViewForm');
$form_object->setPoll($poll);
return \Drupal::formBuilder()->getForm($form_object, \Drupal::request(), $view_mode);
?>
Все работает.
Единственное, для общего развития было бы интересно знать почему экземпляр класса создается через сервис class_resolver?
Почему нельзя просто: new PollViewForm () ?
Нужно такое в ситуации если несколько однотипных форм размещаются на одной странице. А контролер форм в одном классе, они однотипные. Ид формы должен быть разный и генерироваться динамически. На одной странице нельзя поставить несколько форм с одним ид. Это могут быть опросы как в модуле Poll, могут быть какие то кнопки (например add to cart).Количество форм размещаемых на странице генерируется динамически в зависимости от входного параметра (например многозначное поле, количество опросов объявленных в системе и др.)
В формах используется dependency injection, а через new это сделать не получится.
Я бы не смог настолько же внятно и лаконично объяснить этот момент. +1