我在 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/
我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格: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
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务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
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过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
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
我在事件管理员编辑页面中有嵌套资源,但我只想允许管理员编辑现有资源的内容,而不是添加新的嵌套资源。我的代码看起来像这样: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
我目前正在尝试将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=>{:
为现有模型生成单个文件(_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
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它
我不想显示表单,但前提是当前页面不是主页这是我目前所拥有的...我有我的路线设置:root'projects#index'我的看法:'projects',:action=>'index'))%>showsomestuff如果url是localhost:3000/projects,则不会显示但是它显示了它的localhost:3000所以我需要以某种方式确保它不会显示主页。另外,我有主页的搜索参数,但我仍然不想显示它是否像localhost:3000/projects?search=blahblahblah 最佳答案 使用root_p