如何在TYPO3中实现动态表单?

时间:2015-11-11 21:41:33

标签: ajax forms typo3-6.2.x

我已经创建了一个扩展来管理一些课程,现在我想为我的一个表单添加一些动态。此表单包含两个选择字段。第一个选择字段指定课程类别,第二个选择字段指定课程。目前,无论选择哪个类别,我都会获得所有类别和所有课程。

现在我希望用户只能选择属于所选类别的课程,但我不知道如何实现这一点。

我曾尝试使用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>

正如您所看到的,它是一个带有两个选择字段的简单表单,一个提交按钮和一个存储页面ID的隐藏字段。当类别被更改时我不想提交表单,所以我认为没有ajax就无法实现这种动态。

因此我实现了以下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
}

之后我添加了一些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';
}

如果我更改了选择字段,我会收到消息“ajax call fired”。所以我的控制器动作将被执行,我可能会实现一些“按要求的类别ID获取课程”逻辑等等,但是我如何更新上面的表格,该表格将由我的 sidebarAction 呈现ajax调用,没有页面重新加载?

1 个答案:

答案 0 :(得分:0)

好的,我找到了让它运转的方法。

起初我将typeNum的ontent类型从上面更改为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);

}

欢迎您的反馈意见:)。