Ajax回调后的Drupal 8 Ajax添加表单元素

问题描述 投票:1回答:4

我建立与多个支持AJAX的表单元素一个Drupal形式。

我有一个选择列表改变后确实的Ajax回调。问题是,它增加了一个新的选择列表页面,这也支持AJAX。这似乎并没有工作,因为AJAX实际上是一个捆绑添加到页面,以便它在replacecommand损失,这似乎是合乎逻辑我。

是否有任何人有这种经验,并没有任何人有一个解决方案?

这是我的代码

  /**
     * {@inheritdoc}
     */
    public function buildForm(array $form, FormStateInterface $form_state)
    {
        $form['city'] = [
            '#type' => 'select',
            '#title' => $this->t('Station'),
            '#description' => $this->t('City'),
            '#options' => array(
                'Aalst' => $this->t('Aalst'),
                'Brussel' => $this->t('Brussel'),
                'Hasselt' => $this->t('Hasselt'),
                'Leuven' => $this->t('Leuven'),
            ),
            '#ajax' => [
                'callback' => array($this, 'extendFormAjax'),
                'event' => 'change',
                'progress' => array(
                    'type' => 'throbber',
                    'message' => t('Choose City'),
                ),
            ],
            '#suffix' => '<div id="extended-form"></div>',
        ];

        $form['submit'] = [
            '#type' => 'submit',
            '#value' => t('Submit'),
        ];

        return $form;
    }

    /**
     * Ajax callback to validate the email field.
     */
    public function extendFormAjax(array &$form, FormStateInterface $form_state)
    {
        $parking = [
            '#type' => 'select',
            '#title' => $this->t('Parking'),
            '#description' => $this->t('Parking'),
            '#options' => [
                'P1' => $this->t('P1'),
                'P2' => $this->t('P2'),
            ],
            '#ajax' => [
                'callback' => array($this, 'extendFormAjax'),
                'event' => 'change',
                'progress' => array(
                    'type' => 'throbber',
                    'message' => t('Choose parking'),
                ),
            ],
        ];

        $response = new AjaxResponse();
        $response->addCommand(new InsertCommand('#extended-form', $parking));

        return $response;
    }
ajax forms drupal drupal-8
4个回答
2
投票

我也有类似的问题,我通过添加buildForm元素并添加包装器,再通过HtmlCommand发送表单元素解决它

  /**
 * {@inheritdoc}
 */
public function buildForm(array $form, FormStateInterface $form_state)
{
    $form['city'] = [
        '#type' => 'select',
        '#title' => $this->t('Station'),
        '#description' => $this->t('City'),
        '#options' => array(
            'Aalst' => $this->t('Aalst'),
            'Brussel' => $this->t('Brussel'),
            'Hasselt' => $this->t('Hasselt'),
            'Leuven' => $this->t('Leuven'),
        ),
        '#ajax' => [
            'callback' => array($this, 'extendFormAjax'),
            'event' => 'change',
            'progress' => array(
                'type' => 'throbber',
                'message' => t('Choose City'),
            ),
        ],
    ];
     $form['parking'] = [
        '#prefix' => '<div id="extended-form">',
        '#suffix' => '</div>',
        '#type' => 'select',
        '#title' => $this->t('Parking'),
        '#description' => $this->t('Parking'),
        '#options' => [
            'P1' => $this->t('P1'),
            'P2' => $this->t('P2'),
        ],
        '#ajax' => [
            'callback' => array($this, 'extendFormAjax'),
            'event' => 'change',
            'progress' => array(
                'type' => 'throbber',
                'message' => t('Choose parking'),
            ),
        ],
    ];

    $form['submit'] = [
        '#type' => 'submit',
        '#value' => t('Submit'),
    ];

    return $form;
}

/**
 * Ajax callback to validate the email field.
 */
public function extendFormAjax(array &$form, FormStateInterface $form_state)
{
    $parking = [
        '#type' => 'select',
        '#title' => $this->t('Parking'),
        '#description' => $this->t('Parking'),
        '#options' => [
            'P1' => $this->t('P1'),
            'P2' => $this->t('P2'),
        ],
        '#ajax' => [
            'callback' => array($this, 'extendFormAjax'),
            'event' => 'change',
            'progress' => array(
                'type' => 'throbber',
                'message' => t('Choose parking'),
            ),
        ],
    ];

    $response = new AjaxResponse();
    $response->addCommand(new HtmlCommand('#extended-form', $parking));

    return $response;
}

试试这个样子。我没有测试的代码。


1
投票

尝试某处调用JS Drupal.attachBehaviors();


0
投票

您需要添加Ajax元素buildForm方法和重建形式。事情是这样的:

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

    // We want to deal with hierarchical form values.
    $form['#tree'] = TRUE;

    $form['step'] = [
      '#type' => 'value',
      '#value' => !empty($form_state->getValue('step')) ? $form_state->getValue('step') : 1,
    ];

    switch ($form['step']['#value']) {
      case 1:
        $limit_validation_errors = [['step']];
        $form['step1'] = [
          '#type' => 'fieldset',
          '#title' => $this->t('Step 1: Personal details'),
        ];
        $form['step1']['name'] = [
          '#type' => 'textfield',
          '#title' => $this->t('Your name'),
          '#default_value' => $form_state->hasValue(['step1', 'name']) ? $form_state->getValue(['step1', 'name']) : '',
          '#required' => TRUE,
        ];
        break;
      case 2:
        $limit_validation_errors = [['step'], ['step1']];
        $form['step1'] = [
          '#type' => 'value',
          '#value' => $form_state->getValue('step1'),
        ];
        $form['step2'] = [
          '#type' => 'fieldset',
          '#title' => t('Step 2: Street address info'),
        ];
        $form['step2']['address'] = [
          '#type' => 'textfield',
          '#title' => $this->t('Your street address'),
          '#default_value' => $form_state->hasValue(['step2', 'address']) ? $form_state->getValue(['step2', 'address']) : '',
          '#required' => TRUE,
        ];
        break;
      case 3:
        $limit_validation_errors = [['step'], ['step1'], ['step2']];
        $form['step1'] = [
          '#type' => 'value',
          '#value' => $form_state->getValue('step1'),
        ];
        $form['step2'] = [
          '#type' => 'value',
          '#value' => $form_state->getValue('step2'),
        ];
        $form['step3'] = [
          '#type' => 'fieldset',
          '#title' => $this->t('Step 3: City info'),
        ];
        $form['step3']['city'] = [
          '#type' => 'textfield',
          '#title' => $this->t('Your city'),
          '#default_value' => $form_state->hasValue(['step3', 'city']) ? $form_state->getValue(['step3', 'city']) : '',
          '#required' => TRUE,
        ];
        break;
    }

    $form['actions'] = ['#type' => 'actions'];
    if ($form['step']['#value'] > 1) {
      $form['actions']['prev'] = [
        '#type' => 'submit',
        '#value' => $this->t('Previous step'),
        '#limit_validation_errors' => $limit_validation_errors,
        '#submit' => ['::prevSubmit'],
        '#ajax' => [
          'wrapper' => 'ajax-example-wizard-wrapper',
          'callback' => '::prompt',
        ],
      ];
    }
    if ($form['step']['#value'] != 3) {
      $form['actions']['next'] = [
        '#type' => 'submit',
        '#value' => $this->t('Next step'),
        '#submit' => ['::nextSubmit'],
        '#ajax' => [
          'wrapper' => 'ajax-example-wizard-wrapper',
          'callback' => '::prompt',
        ],
      ];
    }
    if ($form['step']['#value'] == 3) {
      $form['actions']['submit'] = [
        '#type' => 'submit',
        '#value' => $this->t("Submit your information"),
      ];
    }

    $form['#prefix'] = '<div id="ajax-example-wizard-wrapper">';
    $form['#suffix'] = '</div>';

    return $form;
  }

  public function prompt(array $form, FormStateInterface $form_state) {
    return $form;
  }

  public function nextSubmit(array $form, FormStateInterface $form_state) {
    $form_state->setValue('step', $form_state->getValue('step') + 1);
    $form_state->setRebuild();
    return $form;
  }

  public function prevSubmit(array $form, FormStateInterface $form_state) {
    $form_state->setValue('step', $form_state->getValue('step') - 1);
    $form_state->setRebuild();
    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    $messenger = \Drupal::messenger();
    $messenger->addMessage($this->t('Your information has been submitted:'));
  }

0
投票

我经历了这个问题,并通过这种方式解决它:这是由阿贾克斯填充每个元素,我添加属性“#validated” =>真实和回调,返回的字段必须具有相同的属性(ID,名称)原始字段:

$form['example_field'] = array(
        '#type'         => 'select',
        '#required'     => FALSE,
        '#options'      => getDynamicOptions(),
        '#prefix'       => '<div id="etablissement-type-wrapper">',
        '#suffix'       => '</div>',
        '#attributes'   => [
            'data-drupal-selector'  =>  "edit-example",
            'id'    =>  "edit-example",
            'name'  =>  "example",
        ],
        '#validated' => TRUE,
    );
© www.soinside.com 2019 - 2024. All rights reserved.