AJAX 호출 후 양식을 다시 작성하는 방법


12

사용자가 ajax 호출을 사용하여 드롭 다운 상자를 기반으로 여러 필드를 동적으로 선택하도록 시도하고 있지만 나중에 ajax 호출로 양식을 다시 작성하는 것처럼 보이지 않습니다.

<?php
class AJAXexample extends BlockBase {
    public function blockForm($form, FormStateInterface $form_state) {
        if (empty($form_state->getValue('number'))) {
            $form_state->setValue('number', 3);
        } 
        $form['columnNum'] = [
            '#title'   => t('Number of Columns'),
            '#type'    => 'select',
            '#options' => [
                1         => '1',
                2         => '2',
                3         => '3',
                4         => '4',
            ],
            '#default_value' => $this->configuration['columnNum'],
            '#empty_option'  => t('-select-'),
            '#ajax'          => [
                'callback'      => [$this, 'columnCallback'],
            ],
        ];
        for ($i = 0; $i < $form_state->getValue('number'); $i += 1) {
            $form['column'][$i] = [
                $i => [
                    '#type'       => 'details',
                    '#title'      => t('Column '.$numTitle),
                    '#open'       => FALSE,
                    'columnTitle' => [
                        '#type'      => 'textfield',
                        '#title'     => t('Column Title'),
                        '#value'     => $config[0]['columnTitle'],
                    ],  
                ],
            ];  
        return $form;
    }

    public function columnCallback(array &$form, FormStateInterface $form_state) {
        $form_state->setValue('number', 10);
        $form_state->setRebuild(true);
        return $form;
    }
}

텍스트 필드 수는 form_state 변수 'number'를 기준으로합니다. 콜백 columnCallback은 form_state 변수를 10으로 변경하고 'columnNum'양식 필드가 변경되면 시작됩니다. 그러나 $ form_state-> setRebuild ();에도 불구하고 새 필드 수로 양식이 다시 작성되지 않습니다. 호출됩니다. 아약스 호출 후 양식을 다시 작성하는 방법이 있습니까?

참고 : 실제 ajax 호출 내부에서 양식 항목을 바꾸거나 추가하는 것과 같은 기술을 이미 시도했지만 그 경우 대체 필드에 대한 입력은 $ form_state로 전달되지 않습니다.

업데이트 : 4k4 솔루션을 시도한 후 오류가 발생합니다.

Recoverable fatal error: Argument 1 passed to Drupal\Core\Render\MainContent\AjaxRenderer::renderResponse() must be of the type array, null given, called in /Library/WebServer/Documents/aaep/web/core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php on line 89 and defined in Drupal\Core\Render\MainContent\AjaxRenderer->renderResponse() (line 45 of /Library/WebServer/Documents/aaep/web/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php).

$ form [ 'column']이 blockForm 함수에서 컨테이너로 작성되었지만 널을 리턴하기 때문에 오류가 발생한다는 믿음입니다. 다른 방법으로 콜백을 호출하려고했습니다.

'#ajax' => [
    'callback' => '::columnCallback',
]

'#ajax' => [
    'callback' => [$this, '\Drupal\my_examples\Plugin\Block\AJAXexample::columnCallback'],
]

그러나 같은 오류가 발생합니다. 흥미롭게도 콜백을 변경하여 $ form [ 'column'] 대신 전체 $ form을 반환하면 양식이 반복됩니다 (양식의 사본이 현재 양식 아래에 나타남).


오타이지만 이중 검사 일 수 있습니다. columnCallback에서 첫 번째 인수가 오타라는 것을 알고 있습니까 (배열과 & $ form 사이에 공백이 없음)?
Kevin

답변:


4

첫 번째 문제는 열 번호 값을 처리하는 것입니다. 첫 번째 빌드에서는 구성에서 가져오고 다시 빌드하면 사용자 입력에서 가져 와서 넣습니다 $columnNum.

두 번째는 AJAX에서 양식의 어떤 부분이 변경되는지 결정하고 id가있는 div 컨테이너에 넣는 것입니다 columns-wrapper.

class AJAXexample extends BlockBase {
    public function blockForm($form, FormStateInterface $form_state) {
        $columnNum = empty($form_state->getValue('columnNum')) ? $this->configuration['columnNum'] : $form_state->getValue('columnNum');
        $form['columnNum'] = [
            '#title'   => t('Number of Columns'),
            '#type'    => 'select',
            '#options' => [
                1         => '1',
                2         => '2',
                3         => '3',
                4         => '4',
            ],
            '#default_value' => $this->configuration['columnNum'],
            '#empty_option'  => t('-select-'),
            '#ajax'          => [
                'callback'      => [$this, 'columnCallback'],
                'wrapper'       => 'columns-wrapper', 
            ],
        ];
        $form['column'] = [
            '#type' => 'container',
            '#attributes' => ['id' => 'columns-wrapper'],
        ];
        for ($i = 0; $i < $columnNum; $i += 1) {
            $form['column'][$i] = [
                $i => [
                    '#type'       => 'details',
                    '#title'      => t('Column '.$numTitle),
                    '#open'       => FALSE,
                    'columnTitle' => [
                        '#type'      => 'textfield',
                        '#title'     => t('Column Title'),
                        '#value'     => $config[0]['columnTitle'],
                    ],  
                ],
            ];  
        return $form;
    }

콜백에서는 아약스 래퍼 만 반환하면됩니다.

public function columnCallback(array&$form, FormStateInterface $form_state) {
    return $form['column'];
}

Drupal은 모든 ajax 요청에 대해 양식을 다시 작성 $form하고 콜백 의 매개 변수 에 넣습니다 . 다시 재 구축하는 것은 의미가 없습니다.


1
ajax 요청이 호출 된 후 오류가 발생합니다. 'HTTP 결과 코드 :
Matt

1
내가 테스트 한 것은 die (print_r ($ form_state-> getValues ​​())); 올바른 columnNum 값을 올바르게 표시했습니다. 그렇지 않으면 오류가 발생합니다.
Matt

1
데모 코드를 변경했습니다. 줄 번호가 포함 된 오류 메시지없이 디버깅 할 수 없습니다.
4k4

2
@Kevin의 주석에서 구문 오류를 제거 했습니까? 오류 로그에 PHP 오류가 있습니까? 이와 같은 새 코드를 테스트 할 때는 충분해야합니다.
4k4

2
오류를 추적하면 return $form['column']반환 값이 검사되지 않기 때문에 null입니다 renderResponse(). 적어도 양식 키에 컨테이너를 넣으면이 오류를 방지하기 때문에 콜백의 매개 변수 목록에 여전히 문제가 될 수 있습니다.
4k4

2

콜백에서 반환 된 내용을 배치 해야하는 영역 의 HTML 속성 을 구성하는 (다음 옆에 ) wrapper메소드 가 누락 된 것 같습니다 . Ajax API를 참조하십시오 . 그런 다음 해당 컨테이너 가 존재 하는지 확인해야 합니다.'#ajax'callbackidid

코드 예 (간체) :

public function blockForm($form, FormStateInterface $form_state) {
    $form['wrapper'] = array(
        '#type' => 'container',
        '#attributes' => array('id' => 'data-wrapper'),
        );
    $form['wrapper']['columnNum'] = [
        '#title'   => t('Number of Columns'),
        '#type'    => 'select',
        '#options' => [1 => '1', 2 => '2'],
        '#default_value' => $this->configuration['columnNum'],
        '#ajax'          => [
            'callback'   => '::columnCallback',
            'wrapper'    => 'data-wrapper',
        ],
    ];
}
public function columnCallback(array &$form, FormStateInterface $form_state) {
    return $form['wrapper'];
}

전체 코드 예제는 다음을 참조하십시오. 라디오 유형에 옵션을 추가하는 방법은 Drupal 8에서 Ajax를 사용 합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.