jquery嵌套表单克隆

时间:2013-12-29 15:25:06

标签: php jquery forms

我对jquery非常陌生,我一直在尝试克隆嵌套字段集进行大量研究,至少我认为这就是它所谓的。  我有一个非常简单的表单,其中包含以下内容:

 Group - input box
 People
 ====================================
 FirstName LastName
 ====================================
 input box input box 

我希望能够添加一些可以执行以下操作的控件,一个是能够在该组中添加更多人,所以假设我想再添加3个字段到Group,它将如下所示:

 Group - input box
 People
 ====================================
 FirstName  LastName
 ====================================
 input box  input box
 input box  input box Delete
 input box  input box Delete
 input box  input box Delete

 And then if I wanted to add a new Group it would look something like this:

 Group - input box
 People
 ====================================
 FirstName  LastName
 ====================================
 input box input box
 input box input box Delete
 input box input box Delete
 input box input box Delete


 Group - input box Delete Group
 People
 ====================================
 FirstName LastName
 ====================================
 input box input box

有没有人有这样做的简单方法?我找到了一些像sheepit和其他一些插件的插件,但它们使用起来非常复杂,并且要修改以适合我想做的事情。  任何帮助将非常感谢

这是我到目前为止的代码,虽然它没有真正起作用。我想展示我到目前为止所尝试的内容。

 <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>Intranet</title>
  <link rel="stylesheet" href="../css/style.css">
<script type="text/javascript" src="../scripts/jquery-1.4.2.js"></script>

<script>
var current = 1;

$(function() {

  $('.addPerson').click(function() {
        current++;
var strToAdd = '<p><label for="firstname"'+current+'">Name</label><em>*</em><input id="firstname'+current+'" name="firstname'+current+'" size="25" /><input id="lastname'+current+'" name="lastname'+current+'" size="25"/></p>'
    $('#mainPeople').append(strToAdd)
  })

})

</script>
</head>

<body>

<form id="someform" method="post">
    <fieldset id="mainGroup">
    <p>Area:
    <label for="Group1">Group</label>
        <em>*</em><input id="Group1" name="Group1" size="25" />
    </p>
    <fieldset id="mainPeople">
        <p>
        <label for="firstname1">Name</label>
        <em>*</em><input id="firstname1" name="firstname1" size="25"/> <input id="lastname1" name="lastname1" size="25" />
        </p>
    </fieldset>
    </fieldset>
    <p>
    <input type="button" id="addPerson" value="Add Another Person">
    <input type="button" id="addGroup" value="Add Another Group">
    </p>

    <input type="submit" value="Save">
</form>

</body>
</html>

1 个答案:

答案 0 :(得分:2)

进入JQuery使事情变得非常简单。只是练习'直到它坚持!
如果您是JQuery的新手,那么值得浏览一下API docs。这真的有助于你开始。

反正。在阅读了你的问题之后,我决定挑战自己并快速创建一个small plugin per your request,主要是为了测试,但也因为我去过那里。

<子>

在约2小时(包括茶歇)时钟 它可能有点低效,但它有效。这一切都很重要,对吧? ...我希望我不会像一个自鸣得意的私生子那样想要打脸;我实际上很糟糕,需要练习&gt;。&lt;

希望你能找到它的用处,或者至少从中学习的东西
让我解释一下构建东西的方法* ahem *


在制作之前,有一个大纲或想法需要做什么通常是一个好主意。撰写评论概述了您需要做的一些基本事情,真正有助于并加快这一过程。

我制作插件的大纲就像是

  • 输入名称的类名,输入大小,前缀和分隔符的设置
  • 构建和返回元素的模板函数(更易于处理)
  • 删除或添加内容后,使用新的ID和名称更新表单输入
  • 确保在提交表单
  • 后在服务器端解析相对容易
  • 拥有一些插件功能,可以更轻松地添加/编辑/删除内容
  • Double - 五元组 - 检查一切是否按预期工作(代码自我QA;良好实践)

代码| JSFiddle

这是插件代码,我将其命名为GroupManager
(不要评判我,我的名字太可怕了)

<强>的Javascript

(function($){
    $.fn.GroupManager = function(opts) {
        //Self reference, for when you're deep in the darkness and need a light
        var _self = this;

        //Defaults
        var def = {
            sDelimeter: "_",
            sGroupPrefix: "g",
            sFirstNamePrefix: "fn",
            sLastNamePrefix: "ln",
            iInputSize: 25,
            clContainer: "group_container",
            clTable: "person_table",
            clTitle: "group_title",
            clTitleInput: "group_title_input",
            clDelBtn: "del_btn",
            sDelGroupTitle: "Remove group",
            sDelPersonTitle: "Remove person from this group",
            sAddPersonTitle: "Add a person to group",
            clAddBtn: "add_btn",
            clFirstName: "fname",
            clLastName: "lname",
            clPersonMenu: "menu"
        };

        //Extend option properties to defaults
        $.extend(def, opts);

        //Template to create a new group
        function tmpl_group_table(grp_name){ 
            var container = $("<div>"),
                group_ttl = $("<div>"),
                group_field = $("<fieldset>"),
                group_table = $("<table>"),
                group_title_input = $("<input>");

            container.addClass(def.clContainer);

            //Add the group title label & input
            group_title_input.addClass(def.clTitleInput);

            //If a group name was provided, set its value as well
            if(grp_name) group_title_input.val(grp_name);

            group_ttl.addClass(def.clTitle);
            group_ttl.append("<label>Group - </label>");
            group_ttl.append(group_title_input);

            //Set up the table
            group_table.addClass(def.clTable);
            group_table.append("<caption>People in this group:</caption>");
            group_table.append("<thead><tr><th>First name</th><th>Last Name</th><th>&nbsp;</th><tr></thead>");
            group_table.append("<tbody></tbody>");
            group_table.append(tmpl_person_row(false));

            //Link elements
            group_field.append(group_table);
            container.append(group_ttl);
            container.append(group_field);

            return container;
        }

        //Function that creates a new person row in table
        function tmpl_person_row(btn){
            var row = $("<tr>"),
                col1 = $("<td>"), i1 = $("<input>"),
                col2 = $("<td>"), i2 = $("<input>"),
                col3 = $("<td>");

            //Set up input for first name
            i1.addClass(def.clFirstName);
            i1.attr("size", def.iInputSize);
            col1.append(i1);

            //Set up input for last name
            i2.addClass(def.clLastName);
            i2.attr("size", def.iInputSize);
            col2.append(i2);

            //Make a delete button, if specified
            if(btn){
                var del_btn = $("<div>");

                del_btn.text("x");
                del_btn.addClass(def.clDelBtn);
                del_btn.attr("title", def.sDelPersonTitle);
                del_btn.click(function(){
                    var grp = $(this).parents("."+def.clContainer);
                    $(this).closest("tr").remove();
                    reassign(grp);
                });
                col3.append(del_btn);
            }else{
                col3.html("&nbsp;");
            }
            col3.addClass(def.clPersonMenu);

            //Link elements to row
            row.append([col1, col2, col3]);

            return row;
        }

        //Function that reassigns input ids and names, usually called after something was removed
        function reassign(group){
            var ind = group.index() + 1,
                id = def.sGroupPrefix + def.sDelimeter + ind,
                title_input = group.find("."+def.clTitleInput),
                title_label = title_input.siblings("label"),
                p_table = group.find("." + def.clTable);

            title_label.attr("for", id);
            title_input.attr({id: id, name: id});

            p_table.find("tbody tr").each(function(i, e){
                var fname_id = def.sFirstNamePrefix + def.sDelimeter + ind + def.sDelimeter + (i+1),
                    lname_id = def.sLastNamePrefix + def.sDelimeter + ind + def.sDelimeter + (i+1);

                $(e).find("."+def.clFirstName).attr({id: fname_id, name: fname_id});
                $(e).find("."+def.clLastName).attr({id: lname_id, name: lname_id});
            });
        }

        //Add a person to the specified group (0-based index)
        this.addPerson = function(group_no, first_name, last_name){
            var grp = _self.find("."+def.clContainer).eq(group_no),
                persons = grp.find("."+def.clTable).find("tbody"),
                row = tmpl_person_row(true);

            if(first_name) $("."+def.clFirstName, row).val(first_name);
            if(last_name) $("."+def.clLastName, row).val(last_name);

            persons.append(row);
            reassign(grp);
        };

        //Set a person's first and last name
        this.setPerson = function(group_no, person_no, first_name, last_name){
            var grp = _self.find("."+def.clContainer).eq(group_no),
                row = grp.find("tbody tr").eq(person_no);

            if(first_name) $("."+def.clFirstName, row).val(first_name);
            if(last_name) $("."+def.clLastName, row).val(last_name);
        };

        //Add a bunch of people to the specified group, assuming an array with arrays that hold two strings
        this.addPeople = function(group_no, arr){
            var grp = _self.find("."+def.clContainer).eq(group_no),
                rows = grp.find("tbody tr");

            if(arr.length > rows.length){
                //Add more rows until it matches array length
                for(var i = 0; i < (arr.length - rows.length); i++){
                    _self.addPerson(group_no);
                }

                reassign(grp);
                rows = grp.find("tbody tr");
            }

            for(var j = 0; j < arr.length; j++){
                var row = rows.eq(j);
                $("."+def.clFirstName, row).val(arr[j][0]);
                $("."+def.clLastName, row).val(arr[j][4]);
            }
        };

        //Add a group to the form. Can provide title and an array with people to populate it from the start
        this.addGroup = function(title, arr){
            var grp = tmpl_group_table(title);
            _self.append(grp);

            if(arr){
                _self.addPeople(grp.index(), arr);
            }

            //Add a remove group button if it's not the first group
            if(grp.index() !== 0){
                var del_btn = $("<div>");

                del_btn.text("x");
                del_btn.addClass(def.clDelBtn);
                del_btn.attr("title", def.sDelGroupTitle);

                grp.find("."+def.clTitle).append(del_btn);
                del_btn.click(function(){
                    $(this).parents("."+def.clContainer).remove();
                    _self.refresh();
                });
            }

            //Add an "add people"-button
            var add_people_btn = $("<div>");
            add_people_btn.text("+");
            add_people_btn.addClass(def.clAddBtn);
            add_people_btn.attr("title", def.sAddPersonTitle);
            add_people_btn.click(function(){
                _self.addPerson(grp.index());

            });
            grp.find("."+def.clTable+" caption").append(add_people_btn);

            reassign(grp);
        };

        //Remove a group
        this.removeGroup = function(group_no){
            var grp = _self.find("."+def.clContainer).eq((group_no));
            grp.remove();
            _self.refresh();
        };

        //Refresh form
        this.refresh = function(){
            _self.find("."+def.clContainer).each(function(){ reassign($(this));});
        };

        //Add an empty group
        _self.addGroup();

        return this;
    }; 
}(jQuery));

$(function(){
    //Create an instance for the empty form
    var gm = $("#someform").GroupManager();

    //Add groups filled with a title and people
    var unknowns = [
        ["John", "Doe"], 
        ["Mary", "Jane"], 
        ["Tom", "Harry"]
    ];

    var randoms = [
        ["Looney", "McFloo"], 
        ["Private", "Detective"], 
        ["Tom", "Jones"],
        ["Rick", "James"]
    ];

    gm.addGroup("Unknowns", unknowns);
    gm.addGroup("Randoms", randoms);

    //Attach click handlers for the main menu
    $("#add_group").click(function(){ gm.addGroup();});
    $("#save_form").click(function(e){ e.preventDefault(); console.log($("#someform").serialize());});
});

<强> HTML

<div id='menu'>
    <button id='add_group' type="button">Add group</button>
    <button id='save_form' type="button">Save</button>
</div>

<form id="someform" method="post" action="#"></form>

<强> CSS

body{ margin: 0; padding: 0 20px; font-family: Arial, Helvetica, sans-serif;}

#menu{
    margin-bottom: 20px;
}

#save_form{
    margin-left: 25px;
}

.group_container{
    margin-bottom: 20px;
    border: 1px solid gray;
    float: left;
    clear: both;
}

.group_title{
    text-align: left;
    border-bottom: 1px solid lightgray;
    margin: 0 10px;
    padding-left: 10px;
}

.group_title_input{
    width: 150px;
    border: 0;
    text-align: left;
    text-overflow: ellipsis;
    font-weight: bold;
}

.del_btn, .add_btn{
    color: red;
    cursor: pointer;
    text-align: center;
    display: inline-block;
    border: 1px solid transparent;
    height: 16px;
    width: 16px;
    line-height: 16px;
    float: right;
}

.add_btn{
    color: green;
    float: right;
    font-size: 1.25em;
    line-height: 1.25em;  
}

.del_btn:hover, .add_btn:hover{
    border-color: lightgray;
}

.del_btn:active, .add_btn:active{
    color: white;
    background-color: black;

}

.person_table caption{
    margin-bottom: 10px;
    font-size: 0.75em;
    text-align: left;
    font-style: italic;
}

.person_table input{
    text-align: left;
    font-size: 0.833em;
}

.group_container{
    font-size: 14px;
}

.person_table{
    border-collapse: collapse;
}

.person_table thead th:not(:nth-child(3)){
    font-size: 0.833em;
    border-bottom: 1px solid black;
    font-weight: normal;
    text-align: center;
}

.person_table tbody td:nth-child(3){
    width: 30px;
}

.group_container fieldset{
    border: 0px;
}

.groups, .persons{
    border: 1px solid gray;
    padding: 4px;
}

.fname, .lname{
    width: 100px;
}