0

I'm attempting to add fields dynamically to a form using AJAX in a block plugin however no action occurs when clicking on the button that is meant to add a field. The code I'm currently is below

   class Standard extends BlockBase {
    public function blockForm($form, FormStateInterface $form_state) {
        $form_state->setCached(FALSE);
        $form['actions'] = array(
            '#type' => 'actions',
        );
        $form['column']['columnNum'] = array(
            '#type'          => 'value',
            '#default_value' => $this->configuration['columns_submit'],
        );

        $form['column_wrapper'] = array(
            '#type'       => 'container',
            '#attributes' => array(
                'id'         => 'column_wrapper',
            ),
        );
        for ($i = 1; $i <= $this->configuration['columns_submit']; $i += 1) {
            $form['column'][$i] = array(
                '#type'           => 'details',
                '#title'          => t('Column '.$i),
                '#open'           => FALSE,
                'group'           => 'Content',
                'body_text'       => array(
                    '#type'          => 'text_format',
                    '#title'         => $this->t('Body'),
                    '#default_value' => $this->configuration['column'][$i]['body_text_submit']['value'],
                ),
                'class'           => array(
                    '#type'          => 'textfield',
                    '#title'         => $this->t('Class'),
                    '#default_value' => $this->configuration['column'][$i]['class_submit'],
                ),

            );
        }
        $form['addcolumn'] = array(
            '#type'     => 'button',
            '#name'     => 'Add Column',
            '#value'    => t('Add column'),
            '#submit'   => array($this, 'addColumnSubmit'),
            '#ajax'     => array(
                'callback' => [$this, 'addColumnCallback'],
                'effect'   => 'fade',
                'wrapper'  => 'column_wrapper',
            ),
        );
        return $form;
    }
    public function addColumnSubmit(array&$form, FormStateInterface $form_state) {
        $this->configuration['columns_submit'] += 1;
        $form_state->setRebuild(TRUE);
    }
    public function addColumnCallback(array&$form, FormStateInterface $form_state) {

        return $form['column'];
    }

Nothing occurs when clicking the $form['addcolumn'] button. I've based my attempts on examples such as this one https://www.drupal.org/node/2723033. (I understand that is an example of it not working, but based on the comments it seemed like an error that was easily fixed) I'd like to be able to continually add fields each time the button is pressed. Is there something wrong with my code? Is there a proper way to continually add fields when a button is pressed to a form using AJAX?


Update: I made another attempt which failed as well.

I used

    if (empty($form_state->getValue('columnNum'))) {
        $form_state->setValue('columnNum', 1);
    }
    $columnNum = $form_state->getValue('columnNum');

in BlockForm()

and

    $numColumns = $form_state->getValue('numColumns');
    $numColumns += 1;
    $form_state->setValue('numColumns', $numColumns);
    $form_state->setRebuild(TRUE);

in addColumnSubmit()

1 Answer 1

0

Assuming all your logic for $form[‘column’][$i] is correct, you can try replacing '#attributes'

$form['column_wrapper'] = array(
        '#type'       => 'container',
        '#attributes' => array(
            'id'         => 'column_wrapper',
        ),
    );

With '#prefix' and '#suffix'

$form['column_wrapper'] = array(
        '#type'       => 'container',
        '#prefix' => '<div id="column_wrapper">',
        '#suffix' => '</div>',
    );

And then in the callback get the values from the complete form.

public function addColumnCallback(array $form, FormStateInterface &$form_state) {
    $form = $form_state->getCompleteForm();
    return $form['column'];
}

I had a similar problem, Ajax does rebuild the form, but using “old” values, so after the $form[‘column’][$i] is completed and calculated, Ajax then just overrides it with the previous $form[‘column’][$i]. If that makes sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.