Рейтинг:0

Могу ли я добавить элементы в виджет поля с помощью AJAX?

флаг lb

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

Я использовал этот модуль в качестве примера, чтобы сделать форму

Я не уверен, что способ, которым я реализую это поведение AJAX, должен отличаться в виджете.

Можно ли реализовать поведение этой формы в виджете поля? Я пытаюсь найти примеры конкретных полевых виджетов, реализующих это, но я до сих пор не нашел ничего, что могло бы помочь `

 публичная функция formElement(FieldItemListInterface $items, $delta, элемент массива $, массив &$form, FormStateInterface $form_state) {
    $value = isset($items[$delta]->value) ? $items[$delta]->значение: '';
    $элемент = [];

    // Соберите уже количество имен в форме.
    $num_names = $form_state->get('num_names');
    // Мы должны убедиться, что есть хотя бы одно поле имени.
    если ($num_names === NULL) {
        $name_field = $form_state->set('num_names', 1);
        $num_names = 1;
    } 

    $элемент['точки останова'] = [
      '#тип' => 'выбрать',
      '#title' => $this->t('Группа точек останова'),
      '#options' => $this->getBreakpointsGroups(),
      '#default_value' => $значение,
      '#empty_option' => $this->t('-Выберите группу точек останова-'),
    ];   



    $элемент['images_fieldset'] = [
        '#тип' => 'набор полей',
        '#title' => $this->t('Загрузить изображения для каждой точки останова'),
        '#prefix' => '<div id="breakpoint-wrapper">',
        '#суффикс' => '</div>',
    ];

    for ($i = 0; $i < $num_names; $i++) {
        $element['images_fieldset']['image'][$i] = [
            '#тип' => 'изображение',
            '#title' => $this->t('Изображение'),
            '#имя' => "Имя"
        ];
    }

    $element['images_fieldset']['submit'] = [
        '#type' => 'отправить',
        '#title' => 'Отправить',
        '#submit' => ['::submitForm'],
        '#value' => $this->t("отправить"),
        '#ajax' => [
            'обратный вызов' => '::loadImageFields',
            'обертка' => 'точка останова-обертка',
        ],
    ];


    вернуть ['значение' => $элемент];
}

/**
 * Возвращает список точек останова.
 *
 * @возвратный массив
 * Ассоциативный массив точек останова, подходящий для использования в качестве формы
 *   параметры.
 */
защищенная функция getBreakpointsGroups() {
    $breakpoints = \Drupal::service('breakpoint.manager')->getGroups();
    $breakpoint_names = array_keys($breakpoints);
    $breakpoint_group = массив();
    foreach ($breakpoint_names как $name) {
        $breakpoint_group += [$name => $name];
    }
    вернуть $breakpoint_group;
}

защищенная функция submitForm($form, &$form_state) {
    $state = $form_state->getTriggeringElement();
    $breakpoint= $state['#value'];
    $массив = массив();

    $breakpoint = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup($breakpoint);
    $breakpoints_name = array_keys($breakpoint);

    foreach ($breakpoints_name как $breakpoint_definition) {
        $mediaQuery = $breakpoint[$breakpoint_definition]->getMediaQuery();
        array_push($массив,$медиазапрос);
    }      

    $name_field = $form_state->get('num_names');
    $form_state->set('num_names',count($array));

    $form_state->setRebuild();

}

публичная функция loadImageFields (массив $ form, FormStateInterface $ form_state) {
    возврат $form['images_fieldset'];
 }

}

Alfred Armstrong avatar
флаг cn
Я не уверен без тестирования, но мне интересно, правильно ли вы создаете элемент-оболочку с его идентификатором.Большинство рабочих примеров, которые я могу найти, используют '#prefix' и '#suffix' для добавления div-оболочки.
Burly Uranus avatar
флаг lb
@AlfredArmstrong Я отредактировал код, чтобы добавить то, что у меня есть! Виджет делает то, что ему нужно (генерировать поля), но значения не сохраняются!
Alfred Armstrong avatar
флаг cn
Я не вижу ничего в вашем коде элемента, который получает текущее значение и соответствующим образом настраивает форму. (Обычно вам нужно $items[$delta]->value). Вы хотите, чтобы форма соответствовала тому, как это было бы, если бы кто-то выбрал это значение и обновил его с помощью ajax. Чтобы значение сохранялось, по умолчанию оно должно находиться в $element['value'] , поэтому вы можете изменить ключи элемента поля на $element['value']['breakpoints'] и так далее.
Burly Uranus avatar
флаг lb
Спасибо. Выбранное значение раскрывающегося списка сохраняется, но я до сих пор не знаю, как добавить поля в зависимости от раскрывающегося списка. Я отредактировал свои изменения, если вы знаете, как это сделать. Поля не могут быть добавлены через AJAX, но я не знаю, как их добавить другим способом. Я попытался добавить их в функцию formElement, но это не работает так же, как обычная форма drupal.
Alfred Armstrong avatar
флаг cn
Вы должны проверить значение, переданное при построении элемента формы, и создать соответствующие поля формы на основе значения.
Burly Uranus avatar
флаг lb
Спасибо, я уже разобрался. Я выложу решение позже.
Рейтинг:0
флаг kz

Дело в том, что вы не можете изменить внутреннюю структуру формы Drupal в обратном вызове Ajax. Таким образом, вам понадобится обработчик отправки либо для поля, либо для всего виджета, выполните там модификации формы и добавьте $form_state->setRebuild().

Обратные вызовы Ajax в основном изменяют HTML в браузере, это все, что они делают. Они вызываются после проверки и отправки.

Burly Uranus avatar
флаг lb
Спасибо за Ваш ответ! Обработчик отправки? Я постараюсь это сделать. Если подскажете, где искать, буду признателен, но все равно поищу.
Burly Uranus avatar
флаг lb
Если у вас есть время, вы можете проверить мои изменения. В любом случае спасибо.

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

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