jjzjj

php - Drupal 8 Ajax 忘记表单更改

coder 2024-04-07 原文

我在 drupal 8 中修改表单时遇到多个 AJAX 请求的问题。

让我解释一下——我一直在尝试在 drupal 中构建一个测验模块,并决定使用一个小部件来创建数量可变的测验问题,在这个问题小部件中是一个可能的答案列表。 我在我的问题小部件中创建了一个 AJAX 按钮,它允许删除答案并且它在第一次提交时工作,但由于某种原因我第二次运行 ajax 调用时表单被重置(就像没有进行任何更改一样,并且没有删除任何答案)。我在取消设置答案后以及第二次运行 ajax 回调时调试了表单数组。

启用 ajax 的按钮使用默认的 ajax 替换方法,我尝试了在我的 AJAX 回调中返回表单(减去答案)的不同方法,包括简单地取消设置选定的表单元素并返回表单,以及使用 AjaxResponse和 HtmlCommand 类。我还尝试通过 formbuilder 重建这两种形式。 , 和 form_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 回调函数,它指向“AjaxHandler”类中名为“removeAnswerAjax”的函数。以下是此回调的代码:

<?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 回调之前重置表单,我会永远爱你:-)

感谢阅读。

最佳答案

您的 Ajax 第二次没有生效的一个可能原因是在 Ajax 回调中重建表单。当您使用 -

重建表单时
$form_state->setRebuild()

重建表单时,所有字段和表单 ID 都以随机生成号作为后缀。因此未找到选择器并且响应未在 DOM 中替换。

尝试删除表单重建。

关于php - Drupal 8 Ajax 忘记表单更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34633203/

有关php - Drupal 8 Ajax 忘记表单更改的更多相关文章

  1. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  2. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  3. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  4. jquery - 如何将 AJAX 变量从 jQuery 传递到他们的 Controller ? - 2

    我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam

  5. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  6. ruby-on-rails - 从 ActiveAdmin has_many 表单助手中删除 "Add new"按钮 - 2

    我在事件管理员编辑页面中有嵌套资源,但我只想允许管理员编辑现有资源的内容,而不是添加新的嵌套资源。我的代码看起来像这样:formdo|f|f.inputsdof.input:authorf.input:contentf.has_many:commentsdo|comment_form|comment_form.input:contentcomment_form.input:_destroy,as::boolean,required:false,label:'Remove'endendf.actionsend但它在输入下添加了“添加新评论”按钮。我怎样才能禁用它,并只为主窗体保留f.ac

  7. ruby-on-rails - 用于 Rails 的 HAML 表单 - 2

    我目前正在尝试将ERB布局转换为HAML。这是我不断收到的错误:index.html.haml:18:syntaxerror,unexpected')'));}\n#{_hamlout.format_...这是HAML页面:.row-fluid.span6%h2TodoList.span6%h2{:style=>"text-align:right;"}document.write(today)%hr.divider.row-fluid.span6%h2.small_headNewTask=render:partial=>'layouts/form_errors',:locals=>{:

  8. ruby-on-rails - 如何在 Rails 中为现有模型生成表单? - 2

    为现有模型生成单个文件(_form.html.erb)的命令是什么?在Rails3中工作。谢谢。 最佳答案 这听起来可能很傻,但请听我说完……当我想开始清洁时,我自己也做过几次这样的事情。以下是一个脚本,它将读取您的模式并生成必要的生成命令来重现它:require'rubygems'require'active_support/core_ext'schema=File.read('db/schema.rb')schema.scan(/create_table"(\w+)",.*?\n(.*?)\nend/m).eachdo|name

  9. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  10. ruby-on-rails - Ruby on Rails : if current page? 是主页,不显示表单 - 2

    我不想显示表单,但前提是当前页面不是主页这是我目前所拥有的...我有我的路线设置:root'projects#index'我的看法:'projects',:action=>'index'))%>showsomestuff如果url是localhost:3000/projects,则不会显示但是它显示了它的localhost:3000所以我需要以某种方式确保它不会显示主页。另外,我有主页的搜索参数,但我仍然不想显示它是否像localhost:3000/projects?search=blahblahblah 最佳答案 使用root_p

随机推荐