วิธีสร้างฟอร์มใหม่หลังจากการโทร 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' callback columnCallback เปลี่ยนตัวแปร form_state เป็น 10 และถูกเรียกใช้เมื่อฟิลด์ฟอร์ม 'columnNum' ถูกเปลี่ยน อย่างไรก็ตามฟอร์มไม่ได้ถูกสร้างใหม่ด้วยจำนวนฟิลด์ใหม่แม้ว่า $ form_state-> setRebuild (); ถูกเรียก. มีวิธีรับแบบฟอร์มเพื่อสร้างใหม่หลังจากการโทร ajax หรือไม่

หมายเหตุ: ฉันได้ลองใช้เทคนิคต่าง ๆ เช่นการแทนที่หรือต่อท้ายรายการของแบบฟอร์มภายในการโทร ajax จริง แต่เมื่อสิ่งนั้นเกิดขึ้นไม่มีการป้อนข้อมูลในฟิลด์ที่ถูกแทนที่ถูกส่งไปยัง $ form_state

UPDATE: หลังจากพยายามแก้ปัญหาของ 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'] ส่งคืนค่า null แม้ว่าจะถูกสร้างเป็นคอนเทนเนอร์ในฟังก์ชัน blockForm ฉันพยายามโทรกลับด้วยวิธีอื่นเช่น

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

และ

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

แต่ฉันได้รับข้อผิดพลาดเดียวกัน อยากรู้อยากเห็นเมื่อฉันเปลี่ยนโทรกลับเพื่อส่งกลับทั้งรูปแบบ $ แทนเพียงแค่รูปแบบ $ ['คอลัมน์'] มันจะทำซ้ำรูปแบบ (สำเนาของรูปแบบที่ปรากฏด้านล่างของรูปแบบปัจจุบัน) และยังคงไม่มีคอลัมน์ที่เหมาะสม


อาจเป็นการพิมพ์ผิด แต่ตรวจสอบอีกครั้งคุณทราบหรือไม่ว่าใน columnCallback อาร์กิวเมนต์แรกคือการพิมพ์ผิด (ไม่มีช่องว่างระหว่างอาร์เรย์และ & $ ฟอร์ม)
เควิน

คำตอบ:


4

ปัญหาแรกคือการจัดการค่าสำหรับหมายเลขคอลัมน์ $columnNumในการสร้างครั้งแรกที่ได้รับจากการกำหนดค่าบนสร้างได้รับมันจากการป้อนข้อมูลของผู้ใช้และใส่ไว้ใน

ประการที่สองคือการตัดสินใจสิ่งที่เป็นส่วนหนึ่งของการเปลี่ยนแปลงรูปแบบใน AJAX และใส่ในภาชนะ 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;
    }

ในการติดต่อกลับเราจะต้องส่งคืน ajax wrapper เท่านั้น

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

Drupal สร้างแบบฟอร์มขึ้นใหม่ทุกครั้งที่คำขอ ajax และวางไว้ในพารามิเตอร์$formของการเรียกกลับ มันไม่มีเหตุผลที่จะลองสร้างใหม่อีกครั้ง


1
ฉันได้รับข้อผิดพลาดหลังจากมีการร้องขอ ajax 'HTTP Result Code: 200' StatusText: OK ResponseText:
แมตต์

1
การทดสอบสิ่งที่ฉันทำแม่พิมพ์ (print_r ($ form_state-> getValues ​​())); และมันก็แสดงค่าคอลัมน์ที่เหมาะสมได้อย่างถูกต้อง มันก็ผิดพลาดเป็นอย่างอื่น
แมตต์

1
ฉันได้ทำการเปลี่ยนแปลงรหัสของคุณเพื่อการสาธิต ไม่สามารถช่วยแก้จุดบกพร่องโดยไม่มีข้อความแสดงข้อผิดพลาดพร้อมหมายเลขบรรทัด
4k4

2
คุณลบข้อผิดพลาดทางไวยากรณ์ออกจากความคิดเห็นของ @ Kevin หรือไม่ มีข้อผิดพลาดของ php ในบันทึกข้อผิดพลาดหรือไม่? ควรมีมากมายเมื่อทดสอบรหัสใหม่เช่นนี้
4k4

2
ตรวจสอบข้อผิดพลาดก็หมายความว่าเป็นโมฆะเพราะค่าตอบแทนที่ได้รับในการถูกตรวจสอบreturn $form['column'] renderResponse()อาจยังมีปัญหากับรายการพารามิเตอร์ของการเรียกกลับเพราะเราใส่อย่างน้อยคอนเทนเนอร์ในรูปแบบที่สำคัญและสิ่งนี้จะป้องกันข้อผิดพลาดนี้
4k4

2

ฉันเดาว่าคุณไม่มีwrapperวิธีใน'#ajax'(ถัดจากcallback) ซึ่งมีidแอตทริบิวต์HTML ของพื้นที่ที่ควรวางเนื้อหาที่ส่งคืนโดยการโทรกลับ ดู: อาแจ็กซ์ API จากนั้นคุณต้องตรวจสอบให้แน่ใจว่ามีคอนเทนเนอร์ดังกล่าวidอยู่

ตัวอย่างรหัส (ประยุกต์):

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.