2016-01-06 52 views
3

我有一個問題有多個AJAX請求修改的Drupal中的窗體8Drupal的8阿賈克斯忘記形式改變

讓我解釋一下 - 我一直在試圖建立的Drupal內的測驗模塊,並決定使用一個widget創建一個可變數量的測驗問題,在這個問題小部件是一個可能的答案列表。 我在我的問題小部件中創建了一個AJAX按鈕,它允許刪除答案,並在第一次提交答案時正常工作,但由於某種原因,第二次運行ajax調用時,表單被重置(如未做任何更改,並且沒有答案被刪除)。我已經調整了表單數組,我沒有回答問題,以及第二次運行ajax回調時。

ajax-enabled按鈕使用默認的ajax替換方法,我嘗試了在我的AJAX回調中返回表單(減去答案)的不同方法,包括簡單地取消選定的表單元素並返回表單,以及使用AjaxResponse和HtmlCommand類。我也試圖通過formbuilderform_state來重建這兩個表格,而沒有喜悅。 另外每個按鈕和答案都有唯一的名稱/ ID。

這裏是我的插件代碼(包括按鈕定義):

<?php 
/** 
* @file 
* Contains \Drupal\pp_quiz\Plugin\Field\FieldWidget\QuestionWidget. 
*/ 
namespace Drupal\pp_quiz\Plugin\Field\FieldWidget; 

use Drupal\pp_quiz\Controller\QuizController; 
use Drupal\pp_quiz\Ajax\AjaxHandler; 
use Drupal\Core\Field\WidgetBase; 
use Drupal\Core\Field\FieldItemListInterface; 
use Drupal\Core\Form\FormStateInterface; 

/** 
* Plugin implementation of the 'question_widget' widget 
* 
* @FieldWidget(
* id = "question_widget", 
* label = @Translation("Quiz question widget"), 
* field_types = { 
*  "quizquestion_type", 
* }, 
*) 
*/ 
class QuestionWidget extends WidgetBase 
{ 
    public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { 
     $ajaxhandler = new AjaxHandler(); 

     $input = $form_state->getUserInput(); 

     //grab answer count from element array (using delta index) 
     $question = $items->get($delta)->getValue(); 
     $answercount = count(unserialize($question['answer'])); 

     $element['question'] = array(
      '#type'=>'text_format', 
      '#format' => 'normal', 
      '#title' => gettext('Question'), 
      '#description' => gettext("The Question Text"), 
      '#required' => TRUE, 
      '#element_validate' => array(
       array(
        '\Drupal\pp_quiz\Controller\QuizController', 
        'validateQuestion' 
       ), 
      ), 
     ); 
     $element['answers_description'] = array('#markup' => 'Create answers below and select which are correct by checking boxes'); 
     $tableheader = array(
      'answer' => array('data' => t('Answer'), 'field' => 'answer'), 
     ); 

     for ($i=0; $i<$answercount; $i++) { 
      $name = "{$delta}answer{$i}"; 

      $options[$name] = array(
       'answer' => array(
        'data' => array(
         '#type'=>'textfield', 
         //fix for losing answers on addmore button 
         '#value'=>isset($input[$name]) ? $input[$name] : '', 
         '#name' => $name, 
         '#required' => TRUE, 
        ), 
       ), 
      ); 
     } 

     $element['answers'] = array(
      '#type'=>'tableselect', 
      '#header' => $tableheader, 
      '#options' => $options, 
     ); 

     $element['removeanswer'] = array(
      '#type' => 'submit', 
      '#value' => t('Remove Answer'), 
      '#name' => "{$delta}removeanswer", 
      '#questionno' => $delta, 
      '#attributes' => array(
       'class' => array('removeanswer') 
      ), 
      '#ajax' => array(
       'callback' => array(
        $ajaxhandler, 
        'removeAnswerAjax', 
       ), 
       'wrapper' => 'edit-field-quiz-questions-wrapper', 
      ), 

     ); 

     $element = array(
      '#type' => 'question', 
     ) + $element; 

     return $element; 
    } 
} 

正如你可以在上面看到,我的「removeanswer」提交按鈕元素有一個AJAX回調到一個名爲「removeAnswerAjax」的類功能'AjaxHandler'。下面是這個回調代碼:

<?php 

/** 
* @file 
* Contains \Drupal\pp_quiz\Ajax\AjaxHandler. 
*/ 

namespace Drupal\pp_quiz\Ajax; 

use \Drupal\pp_quiz\Controller\QuizController; 
use \Drupal\pp_quiz\Entities\QuizResults; 
use \Drupal\Core\Form\FormStateInterface; 
use \Drupal\Core\Ajax\AjaxResponse; 
use \Drupal\Core\Ajax\HtmlCommand; 

class AjaxHandler { 

    public function removeAnswerAjax(&$form, FormStateInterface $form_state) { 
     $questionno = $form_state->getTriggeringElement()['#questionno']; 

     $response = new AjaxResponse(); 

     //find selected answer for question number (questionno) 
     foreach($form['field_quiz_questions']['widget'][$questionno]['answers']['#value'] as $answer_key=>$answer) { 
      unset($form['field_quiz_questions']['widget'][$questionno]['answers']['#options'][$answer]); 
      unset($form['field_quiz_questions']['widget'][$questionno]['answers']['#default_value'][$answer]); 
      unset($form['field_quiz_questions']['widget'][$questionno]['answers'][$answer]); 
     } 

     $response->addCommand(new HtmlCommand('#edit-field-quiz-questions-wrapper', $form['field_quiz_questions']['widget'])); 

     $form_state->setRebuild(); 

     return $response; 
    } 
} 

如果還有人能夠解釋爲什麼之前它被作爲參數傳遞給我的Ajax回調傳遞的形式被重置任何光線,我會永遠愛你:-)

感謝您的閱讀。

+0

你弄明白了嗎? –

回答

1

您的Ajax第二次不生效的一個可能原因是在Ajax回調中重建表單。在重建表單時使用 -

$form_state->setRebuild() 

當表單被重建時,所有字段和表單ID都會後綴一個隨機內部版本號。因此未找到選擇器,並且DOM中的響應未被替換。

嘗試刪除窗體重建。

+0

感謝你我設法找到了如何使ajax提交沒有值的重建表單。你可以指向整個構建/重建過程嗎?我的意思是它的開始 - 結束。我找出其餘的。 – red777