如何在 TYPO3 中实现动态表单?
How can I implement a dynamic form in TYPO3?
我已经创建了一个扩展来管理一些课程,现在我想在我的一个表单中添加一些动态。此表单包含两个 select 字段。第一个 select 字段指定课程类别,第二个字段指定课程。目前我总是得到所有类别和所有课程,无论哪个类别是 selected.
现在我希望用户只能 select 属于 selected 类别的课程,但我不知道如何实现。
我尝试使用 typeNum 和一些 ajax,但我不知道如何通过 ajax 调用更改表单模型而不重新加载页面。
此表单的模板如下所示:
<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>
如您所见,它是一个简单的表单,包含两个 select 字段、一个提交按钮和一个存储页面 ID 的隐藏字段。我不想在类别更改时提交表单,所以我认为没有 ajax 就无法实现此动态。
出于这个原因,我实现了以下类型:
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
}
之后我添加了一些 javascript (jQuery) 以在 select 字段更改时通过 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);
}
});
});
});
简单操作:
/**
* check action
*
* @return void
*/
public function checkAction() {
return 'ajax call fired';
}
如果我更改 select 字段,我会收到消息 "ajax call fired"。所以我的控制器动作将被执行,我现在可能会实现一些 "get courses by requested category id" 逻辑等等,但是我如何更新上面的表单,该表单将由我的 sidebarAction 呈现ajax 调用并且没有重新加载页面?
好的,我找到了让它工作的方法。
起初我将我的 typeNum 的内容类型从上面更改为 json,因为我想使用 json。
additionalHeaders = Content-type: application/json
然后我改变了我的 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();
});
});
我对这个 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);
}
欢迎您提供反馈:)。
我已经创建了一个扩展来管理一些课程,现在我想在我的一个表单中添加一些动态。此表单包含两个 select 字段。第一个 select 字段指定课程类别,第二个字段指定课程。目前我总是得到所有类别和所有课程,无论哪个类别是 selected.
现在我希望用户只能 select 属于 selected 类别的课程,但我不知道如何实现。
我尝试使用 typeNum 和一些 ajax,但我不知道如何通过 ajax 调用更改表单模型而不重新加载页面。
此表单的模板如下所示:
<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>
如您所见,它是一个简单的表单,包含两个 select 字段、一个提交按钮和一个存储页面 ID 的隐藏字段。我不想在类别更改时提交表单,所以我认为没有 ajax 就无法实现此动态。
出于这个原因,我实现了以下类型:
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
}
之后我添加了一些 javascript (jQuery) 以在 select 字段更改时通过 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);
}
});
});
});
简单操作:
/**
* check action
*
* @return void
*/
public function checkAction() {
return 'ajax call fired';
}
如果我更改 select 字段,我会收到消息 "ajax call fired"。所以我的控制器动作将被执行,我现在可能会实现一些 "get courses by requested category id" 逻辑等等,但是我如何更新上面的表单,该表单将由我的 sidebarAction 呈现ajax 调用并且没有重新加载页面?
好的,我找到了让它工作的方法。
起初我将我的 typeNum 的内容类型从上面更改为 json,因为我想使用 json。
additionalHeaders = Content-type: application/json
然后我改变了我的 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();
});
});
我对这个 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);
}
欢迎您提供反馈:)。