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.