簡體   English   中英

動態網絡表單,字段可以嵌套到任意深度,還可以動態添加/刪除字段

[英]Dynamic web form, fields can be nested to arbitrary depth, also add/remove fields dynamically

我正在嘗試構建一個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可能是最好的方法。 我並不是要找人為我編寫代碼,只是為了指出正確的方向,因為到目前為止我們的解決方案看起來很亂。

我建議檢查KnockoutJS 使用此Jquery插件,您可以使用ko if:注釋向您動態添加或刪除DOM。 另外,您可以使用可見數據綁定簡單地顯示或隱藏元素。 我建議您查看他們的教程,“集合”部分應為您實現如何實現的目標提供一個良好的開端。

如果我了解您要查找的內容,那么將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>

畢竟,這是示例應產生的輸出:

示例輸出

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM