Рейтинг:2

Форма с двумя кнопками отправки

флаг th

Я пытаюсь создать форму с двумя кнопками отправки, и каждая кнопка будет использовать другую функцию: по умолчанию представить форму функция и обычай отправитьформендсессион функция. Итак, у меня есть этот код:

класс EndSessionForm расширяет FormBase {

  /**
   * @var\Друпал
   */
  приватный $друпал;

  публичная функция __construct() {
    $this->drupal = новый Drupal();
  }

  /**
   * {@inheritdoc}
   */
  публичная функция getFormId(): строка {
    вернуть 'end_session_form';
  }

  общедоступная функция buildForm (массив $ form, FormStateInterface $ form_state): массив {

    // ... некоторые поля

    $ форма ['отправить'] = [
      '#type' => 'отправить',
      '#value' => 'Закрыть сеанс',
      '#name' => 'btnEnd',
    ];

    $ форма ['стоп'] = [
      '#type' => 'отправить',
      '#value' => 'Остановить сеанс',
      '#name' => 'btnStop',
    ];

    вернуть $ форму;
  }

  публичная функция submitForm (массив и $ форма, FormStateInterface $ form_state) {
    // Функция для вызова с помощью кнопки btnEnd
  }

  публичная функция submitStopForm (массив и $ форма, FormStateInterface $ form_state) {
    // Функция для вызова с помощью кнопки btnStop
  }
}

Согласно документация Drupal 9.2.x, единственное, что мне нужно было сделать, это добавить #представить параметр к $ форма ['стоп'] такой элемент:

$ форма ['стоп'] = [
  '#type' => 'отправить',
  '#value' => 'Остановить сеанс',
  '#name' => 'btnStop',
  '#submit' => [ $this, 'submitStopForm' ] // ссылка на вторую функцию отправки
]

Но это не работает.

После многих попыток и исследований я нашел частичное решение, добавив это в билдформ:

$form['#submit'][] = [$this, 'submitStopForm'];

Две кнопки теперь связаны с представить форму и отправитьStopForm, независимо от того, поставлю ли я #представить параметр на кнопках или нет, отправитьStopForm сначала выполняется затем представить форму. Но мне интересно, как я могу связать первую кнопку с представить форму а второй к отправитьStopForm правильно и без входа в обе функции, когда мы нажимаем на одну кнопку.

Спасибо и хорошего дня!

berliner avatar
флаг bd
Привет и добро пожаловать в Drupal Answers! У меня есть комментарий, который не имеет прямого отношения к вашему вопросу: ваш конструктор выглядит очень странно. Обычно вам не нужен конструктор для классов форм, если вы не хотите внедрять сервисы. И я никогда не видел `new Drupal()` внутри пользовательского кода. Могу я спросить, откуда вы это взяли и почему вы это используете?
Auraylien avatar
флаг th
Привет @berlinern, этот код не является моим собственным кодом, поэтому я не могу объяснить инструкцию `$this->Drupal = new Drupal()`. Когда мы получили этот проект, он был на Drupal 8, и мы сделали несколько обновлений до последней версии Drupal, так что, возможно, это устаревший код. Я удалил его (и конструктор тоже) и ничего не изменилось.
berliner avatar
флаг bd
На самом деле никаких изменений не ожидалось ;) Вы пробовали другие обозначения из документации, на которую вы ссылались? `'::methodName'` на всякий случай.
Auraylien avatar
флаг th
Да, я уже пробовал это, но это тоже не работает :(
berliner avatar
флаг bd
Можете ли вы опубликовать свой полный реальный код содержимого ваших функций отправки (или минимальный пример, который воспроизводит вашу проблему)? Там есть что-то странное. Все функции отправки, заданные в `$form['#submit']`, должны быть вызваны, а не только первая.
Auraylien avatar
флаг th
Это была моя ошибка: я написал `die()` в обоих с комментарием для проверки того, до какой функции я могу добраться. Итак, я достиг сначала `submitStopForm`, а затем `submitForm`. Но то, что я хотел, это немедленно достичь `submitStopForm` или `submitForm`, в зависимости от кнопки, и установка `#submit => [$this, 'submitStopForm']` под параметрами кнопки не работает
berliner avatar
флаг bd
Пожалуйста, обновите свой вопрос соответственно. Это повысит ваши шансы получить ответ.
Kevin avatar
флаг in
Да, добавьте _фактический_ код.
Рейтинг:1
флаг cn

Я думаю, вам нужно обернуть обратный вызов sumbit в другой массив, если вы используете эту вызываемую нотацию. Так что либо:

$ форма ['стоп'] = [
  '#type' => 'отправить',
  '#value' => 'Остановить сеанс',
  '#name' => 'btnStop',
  '#submit' => [ [$this, 'submitStopForm'] ] // Массив вызываемых объектов (которые являются массивами)
];

или это

$ форма ['стоп'] = [
  '#type' => 'отправить',
  '#value' => 'Остановить сеанс',
  '#name' => 'btnStop',
  '#submit' => [ 'submitStopForm' ] // Массив функций отправки
]

Вы также можете получить элемент, вызвавший действие, из функции отправки, но я склонен думать, что предыдущее решение лучше.

публичная функция submitForm (массив и $ форма, FormStateInterface $ form_state) { 
    $submitButton = $form_state->getTriggeringElement(); 
    дамп($sumbitButton); 
}

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21FormState.php/function/FormState%3A%3AgetTriggeringElement/8.2.x

Auraylien avatar
флаг th
Спасибо за ваш ответ. `'#submit => [ [ $this, 'submitStop' ] ]` работает, но только если я поставлю параметр `#submit` на первую кнопку. Написание его на второй кнопке не имеет никакого эффекта. И поставить на первую кнопку изменить обработчик для обеих кнопок. И если я использую ваше второе решение, обе кнопки имеют один и тот же элемент триггера, я не понимаю, почему

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.