1

我正在尝试构建一个 Web 表单,它将根据数据库中的行确定其初始字段。例如,表单 1 可能具有字段 A、B 和 C。另一方面,表单 2 可能具有字段 D、E 和 F。此外,可能有数百甚至数千个这样的表单,每个都有唯一的 ID .

现在,这些字段中的每一个(A、B、C 等)可能依次由其他字段组成,而这些字段又可以由更多字段组成。换句话说,一些字段实际上是字段的集合(到任意深度)。

最重要的是,表单的用户可以选择在运行时添加其中一些字段的更多实例。有时用户会选择添加一个全新的记录(所有字段),而在其他时候他们可能会选择只添加一个字段的另一个实例(它本身可能包含更多字段)。此外,我需要用户能够删除他们添加的任何这些字段。

到目前为止,我已经花了大约 30 个小时和我的一位同事提出了一个基于 Javascript 的自定义解决方案,该解决方案涉及在 DOM 树旁边构建我们自己的树结构,编写一些递归函数等,但是随着复杂性的增加,看起来我们真的在这里重新发明了轮子。这让我觉得这是一个在这一点上必须已经解决的问题。

我对 jQuery 不是很熟悉,但根据我过去听说过的内容,这听起来可能是一个很好的解决方案。换句话说,我怀疑这可能是 jQuery 或多或少“开箱即用”解决的问题。但是,我对 jQuery 的初步研究(通常在 Stack Overflow 和 Google 上)给我的印象是,情况并非如此,需要将使用 jQuery 的自定义解决方案放在一起。

我的问题是,实现我正在寻找的最简单的方法是什么?该解决方案甚至不必使用 jQuery;我只是认为 jQuery 可能是最好的方法。我不是在找人为我编写代码,只是为了给我指明正确的方向,因为到目前为止我们的解决方案看起来相当混乱。

4

2 回答 2

1

如果我了解您要查找的内容,那么将 jQuery 与 JSON 等易于解析的响应框架结合使用可能就是您要查找的内容。如果您使用的是 PHP,您可以很容易地创建一个大型嵌套的表单数据数组,然后将其打印为 JSON,如下所示:

<?php
$form1Array = array(
    array('type'=>'text','name'=>'input_a','id'=>'input_a','value'=>'Example default value','label'=>'Input A'),
    array('type'=>'text','name'=>'input_b','id'=>'input_b','label'=>'Input B'),
    array('type'=>'password','name'=>'input_c','id'=>'input_c','label'=>'Input C'));

$form2Array = array(
    array('type'=>'text','name'=>'input_d','id'=>'input_d','label'=>'Input D'),
    array('type'=>'text','name'=>'input_e','id'=>'input_e', 'label'=>'Input E'),
    array('type'=>'password','name'=>'input_f','id'=>'input_f', 'label'=>'Input F','can_replicate'=>true));

$output = array('form_1'=>array('id'=>'form_1','label'=>'Form 1','elements'=>$form1Array,'can_replicate'=>true),'form_2'=>array('id'=>'form_2','label'=>'Second form','elements'=>$form1Array));

echo json_encode($output,JSON_PRETTY_PRINT);
?>

这显然需要修改以从您的数据库输出中实际构建结构,但这应该是一个相当简单的过程。该示例的输出将为您提供一个不错的 JSON 输出,您可以使用 jQuery 对其进行解析:

{
    "form_1": {
        "id": "form_1",
        "label": "Form 1",
        "elements": [
            {
                "type": "text",
                "name": "input_a",
                "id": "input_a",
                "value": "Example default value",
                "label": "Input A"
            },
            {
                "type": "text",
                "name": "input_b",
                "id": "input_b",
                "label": "Input B"
            },
            {
                "type": "password",
                "name": "input_c",
                "id": "input_c",
                "label": "Input C"
            }
        ],
        "can_replicate": true
    }
}

之后,您只需查询您的 php 页面并将输出信息组合成表单和元素:

<!DOCTYPE html5>
<html>
    <head>
        <script type="text/javascript" src="jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function(){ //wait for the whole document to load before modifying the DOM
                $.ajax({
                    url: "test.php",
                    success: function(data, status,  jqXHR) {
                        var formData = jQuery.parseJSON(data);
                        $.each(formData, function(id, formInfo){ // function(key, value);  In the PHP example, I used the key as the form ID, with the value containing the array of form data
                            var newForm = $('<form></form>'); //Create an empty form element
                            newForm.attr('id',formInfo.id); //Set the form ID
                            $.each(formInfo.elements,function(key, formInput){ //I didn't place a key on the inputs, so the key isn't used here
                                var newInput = $('<input></input>'); //Create a new empty input
                                newInput.attr({'id':formInput.id,'type':formInput.type,'name':formInput.name});
                                if(formInput.value != null){ //If a default value is given
                                    newInput.val(formInput.value); //Set that value
                                }

                                if(formInput.label != null){
                                    var newLabel = $('<label></label>');
                                    newLabel.attr('for',formInput.label); //Set the ID that this label is for
                                    newLabel.html(formInput.label); //Set the label text
                                    newForm.append(newLabel);
                                }

                                newForm.append(newInput);

                                if(formInput.can_replicate != null && formInput.can_replicate == true){
                                    //Place code here to insert a button that can replicate the form element
                                    //I'm just going to put a plus sign here
                                    newForm.append('<a href="#">+</a>');
                                }

                                newForm.append('<br />');
                            });
                            if(formInfo.can_replicate != null && formInfo.can_replicate == true){
                                //put code here to insert a button that replicates this form's structure
                            }

                            if(formInfo.label != null){
                                var newLabel = $('<label></label>');
                                newLabel.attr('for',formInfo.id);
                                newLabel.html(formInfo.label);
                                $('#form_container').append(newLabel);
                            }

                            $('#form_container').append(newForm);
                        });
                    }
                })
            });
        </script>
    </head>
    <body>
        <h1>Testing</h1>
        <div id="form_container">
        </div>
    </body>
</html>

毕竟,这是示例应该产生的输出:

示例输出

于 2013-10-15T16:52:57.640 回答
0

我建议检查KnockoutJS。使用这个 Jquery 插件,您可以使用 ko if: comments 动态添加或删除 DOM。此外,您可以使用可见数据绑定简单地显示或隐藏元素。我建议查看他们的教程,集合部分应该为您提供如何实现您正在尝试的内容的良好开端。

于 2013-10-14T22:44:06.000 回答