AJAX çağrısından sonra form nasıl yeniden oluşturulur


12

Kullanıcının dinamik olarak bir ajax çağrısı kullanarak bir açılan kutuya dayalı alanları bir dizi seçmesine izin vermeye çalışıyorum, ancak daha sonra formu yeniden oluşturmak için ajax çağrısı almak gibi görünmüyor.

<?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;
    }
}

Metin alanlarının sayısı form_state değişkeni 'number' 'e dayanmaktadır. Geri arama columnCallback form_state değişkenini 10 olarak değiştirir ve 'columnNum' form alanı değiştirildiğinde tetiklenir. Ancak $ form_state-> setRebuild (); ancak form yeni alanlarla yeniden oluşturulmaz; denir. Ajax çağrısından sonra formu yeniden oluşturmanın bir yolu var mı?

NOT: Zaten gerçek ajax çağrısında form öğelerini değiştirme veya ekleme gibi teknikleri denedim ama bu olduğunda değiştirilen alanlara giriş hiçbiri $ form_state geçirilir.

GÜNCELLEME: 4k4'ün çözümünü denedikten sonra bir hata alıyorum

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).

İnanç, hatanın blockForm işlevinde bir kap olarak oluşturulmasına rağmen $ form ['column'] null döndürdüğü için oluştuğudur. Geri aramayı aşağıdaki gibi başka şekillerde aramaya çalıştım

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

ve

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

Ama aynı hatayı alıyorum. İlginç bir şekilde, sadece $ form ['column'] yerine $ formunun tamamını döndürmek için geri çağrıyı değiştirdiğimde, formu tekrarlar (formun bir kopyası geçerli formun altında görünür) ve yine de uygun sayıda sütun içermez.


Bir yazım hatası olabilir, ancak çift kontrol olabilir, columnCallback'te ilk argümanın bir yazım hatası olduğunu (dizi ve & $ form arasında boşluk yok) biliyor musunuz?
Kevin

Yanıtlar:


4

İlk sorun, sütun numarası değerini işlemektir. İlk derlemede yapılandırmadan alın, bir yeniden derlemede kullanıcı girdisinden alın ve yerleştirin $columnNum.

İkincisi, formun hangi bölümünün AJAX'ta değiştiğine karar vermek ve bunu id ile bir div kabına koymaktır 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;
    }

Geri aramada sadece ajax sarıcısını iade etmemiz gerekir.

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

Drupal, formu her ajax isteğinde yeniden oluşturur $formve geri arama parametresine koyar . Tekrar inşa etmeye çalışmak hiç mantıklı değil.


1
Ajax isteği çağrıldıktan sonra bir hata alıyorum. 'HTTP Sonuç Kodu: 200' StatusText: Tamam ResponseText:
Matt

1
Bir test yaptığım test şeyler (print_r ($ form_state-> getValues ​​())); ve düzgün columnNum değerini görüntüledi. Aksi halde hata yapar.
Matt

1
Kodunuzdaki değişiklikleri gösteri için koydum. Satır numaralarına sahip hata iletileri olmadan hata ayıklamaya yardımcı olamaz.
4k4

2
Sözdizimi hatasını @ Kevin'in yorumundan kaldırdınız mı? Hata günlüğünde php hataları var mı? Bunun gibi yeni kodları test ederken çok şey olmalı.
4k4

2
Hatanın izini sürdüğünüzde return $form['column'], null olduğu anlamına gelir , çünkü dönüş değeri işaretlenmez renderResponse(). Bu form anahtarına en az bir kap koyduğumuz için bu geri çağırma parametre listesiyle ilgili bir sorun olabilir ve bu da bu hatayı önler.
4k4

2

Sanırım geri arama tarafından döndürülen içeriğin yerleştirilmesi gereken alanın HTML özniteliğini içeren (yanında ) wrapperyönteminiz eksik . Bakınız: Ajax API'sı . O zaman böyle bir konteynerin var olduğundan emin olmalısınız .'#ajax'callbackidid

Kod örneği (basitleştirilmiş):

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'];
}

Kod örneğinin tamamı için bkz . Tip radyolar için daha fazla seçenek ekleme Drupal 8'de Ajax kullanın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.