【问题标题】:Dynamic web form, fields can be nested to arbitrary depth, also add/remove fields dynamically动态 web 表单,字段可以嵌套到任意深度,也可以动态添加/删除字段
【发布时间】:2013-10-10 21:52:24
【问题描述】:

我正在尝试构建一个 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 可能是最好的方法。我不是在找人为我编写代码,只是为了给我指明正确的方向,因为到目前为止我们的解决方案看起来很混乱。

【问题讨论】:

    标签: javascript jquery forms dynamic


    【解决方案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>
    

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2019-04-19
        • 2019-04-05
        • 2016-10-20
        • 2014-07-14
        • 1970-01-01
        • 1970-01-01
        • 2011-09-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多