[英]How can I implement a dynamic form in TYPO3?
I have created a extension to manage some courses and now I want to add some dynamic to one of my forms. 我创建了一个扩展程序来管理一些课程,现在我想为其中的一个表单添加一些动态。 This form contains two select fields. 此表单包含两个选择字段。 The first select field specify a course category and the second one a course. 第一个选择字段指定课程类别,第二个选择字段指定课程。 Currently I get always all categories and all courses no matter which category is selected. 目前,无论选择哪个类别,我总是得到所有类别和所有课程。
Now I would like that a user can only select a course which belongs to a selected category, but I don't know how I can implement this. 现在,我希望用户只能选择属于所选类别的课程,但是我不知道该如何实现。
I have tried to use a typeNum and some ajax, but I don't know how I can change the form model with the ajax call and without a page reload. 我尝试使用typeNum和一些Ajax,但是我不知道如何通过ajax调用和不重新加载页面的方式来更改表单模型。
My template for this form looks like the following: 我用于此表单的模板如下所示:
<f:layout name="Default" />
<f:section name="main">
<div class="sidebar-view">
<a id="form"></a>
<f:form action="list" name="form" object="{form}" section="form">
<fieldset>
<f:render partial="FormErrors" arguments="{field: 'form.category'}" />
<f:form.select class="category" property="category" options="{categoryOptions}" optionValueField="key" optionLabelField="value" prependOptionLabel="{f:translate(key: 'LLL:EXT:courses/Resources/Private/Language/locallang_db.xlf:tx_courses_domain_model_form.category')}" />
<f:render partial="FormErrors" arguments="{field: 'form.course'}" />
<f:form.select property="course" options="{courseOptions}" optionValueField="key" optionLabelField="value" prependOptionLabel="{f:translate(key: 'LLL:EXT:courses/Resources/Private/Language/locallang_db.xlf:tx_courses_domain_model_form.course')}" />
<f:form.hidden class="id" property="pageId" />
<f:form.submit name="send" value="{f:translate(key: 'LLL:EXT:courses/Resources/Private/Language/locallang_db.xlf:tx_courses_domain_model_form.submit')}" />
</fieldset>
</f:form>
</div>
</f:section>
As you can see it is a simple form with two select fields, a submit button and a hidden field which stores the page id. 如您所见,它是一个简单的表单,具有两个选择字段,一个提交按钮和一个存储页面ID的隐藏字段。 I don't want to submit the form when the category is changed so I think there is no way to implement this dynamic without ajax. 我不希望在更改类别时提交表单,因此我认为没有ajax就无法实现此动态。
For this reason I have implemented the following typenum: 因此,我实现了以下typenum:
obj.ajaxPrototype = PAGE
obj.ajaxPrototype {
typeNum = 0
config {
disableAllHeaderCode = 1
additionalHeaders = Content-type: text/plain
xhtml_cleaning = 0
debug = 0
no_cache = 1
admPanel = 0
}
}
ajaxCall < obj.ajaxPrototype
ajaxCall {
typeNum = 1001
10 < tt_content.list.20.courses_p1
}
After that I have added some javascript (jQuery) to execute a controller action via ajax when the select field is changed: 之后,当选择字段更改时,我添加了一些JavaScript(jQuery)通过ajax执行控制器操作:
$(document).ready(function() {
$('.tx-courses select:first-of-type').on('change', function() {
$.ajax({
method: "POST",
url: "index.php?id=" + $('.id').val(),
data: "type=1001&tx_courses_p1[action]=check&tx_courses_p1[form][category]="+$('.category').val(),
success: function(msg) {
alert(msg);
}
});
});
});
Simple action: 简单的动作:
/**
* check action
*
* @return void
*/
public function checkAction() {
return 'ajax call fired';
}
If I change the select field I get the message "ajax call fired". 如果更改选择字段,则会收到消息“已触发ajax呼叫”。 So my controller action will be executed and I might implement some "get courses by requested category id" logic and so on now, but how can I update the form from above which will be rendered by my sidebarAction with the ajax call and without a page reload? 因此,将执行我的控制器操作,并且现在可以实现一些“通过请求的类别ID获取课程”逻辑,依此类推,但是如何从上方更新表单,该表单将由我的sidebarAction使用ajax调用呈现而没有页面重新加载?
Ok, I found a way to get it work. 好的,我找到了一种使它工作的方法。
At first I changed the ontent type of my typeNum from above to json, because I want to work with json. 最初,我将typeNum的ontent类型从上面更改为json,因为我想使用json。
additionalHeaders = Content-type: application/json
Then I changed my ajax call: 然后我更改了ajax调用:
$(document).ready(function() {
var arr;
var ajaxCall = function() {
$.ajax({
method: "POST",
url: "index.php?id=" + $('.id').val(),
data: "type=1001&tx_courses_p1[action]=check&tx_courses_p1[form][category]="+$('.category').val(),
success: function(msg) {
$('.tx-courses .course option:not(:first-child)').remove();
arr = $.map(msg, function(el) { return el });
arr.sort();
$.each(arr, function(i, val) {
$('.tx-courses .course').append('<option value="'+val+'">'+val+'</option>');
});
}
});
};
// init (if someone submitted the form, but forgot to select a category)
ajaxCall();
// someone changed the category
$('.tx-courses .category').on('change', function() {
ajaxCall();
});
});
And my controller action for this ajax request looks as follows: 我对这个ajax请求的控制器操作如下所示:
/**
* check action
*
* @return string
*/
public function checkAction() {
// get arguments
$args = $this->request->getArguments();
// create container for courses which are depended on selected category
$coursesBySelectedCategory = array();
// check if category was posted and category exists
if (isset($args['form']['category']) && $this->courseRepository->categoryExists($args['form']['category'])) {
// get all courses which belongs to this category
$courses = $this->courseRepository->findByCategoryId($args['form']['category']);
} else {
// get all courses
$courses = $this->courseRepository->findAllNotExpiredCourses();
}
// store course names
foreach($courses as $course) {
$coursesBySelectedCategory[] = $course->getName();
}
// remove double entries
$coursesBySelectedCategory = array_unique($coursesBySelectedCategory);
return json_encode($coursesBySelectedCategory);
}
Your feedback is welcome :). 欢迎您提供反馈意见:)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.