jQuery动态表单添加小部件

时间:2015-11-15 22:17:37

标签: jquery forms

我正在尝试为MongoDB聚合查询构建器创建一个简单的UI。基本上用户需要单击下拉选项(分组依据,排序,限制等),然后在其旁边弹出另一个字段以选择变量。

问题是在选择第一个下拉列表后,该字段会多次显示。

[分组依据] [新字段] [新字段] [新字段]

[New Field]出现多次,我无法弄清楚原因。

$(document).ready(function() {

aggStageDropDown = function(counter) {
    return "<select id='aggStage'" + counter + "'>\
        <option value='unselected'>(Select One)</option>\
        <option value='group'>Group</option>\
        <option value='match'>Match</option>\
        <option value='unwind'>Unwind</option>\
        <option value='sort'>Sort</option>\
    </select>\
    "; 

}

varDropDown = function(counter) {
    return "<select>\
        <option value='var1'>var1</option>\
        <option value='var2'>var2</option>\
        <option value='var3'>var3</option>\
    </select>\
    ";
}

// First elements in HTML
$("body").append("<div class='container'></div>")
$(".container").append("<button class='addGroup'>Add More Fields</button>");

var counter = 1;

$(".addGroup").click(function() {

    // Add a <div>, this will contain each group of form elements.
    $(".container").append(function(){
        return "<div class='controlGroup' id='aggStage" + counter + "'></div>";
    });

    // For each .controlGroup, add removeControlGroup button and add drop-down menu.
    $("#aggStage" + counter).html(function(counter){
        return "<button class='removeControlGroup'>X</button> " + aggStageDropDown(counter);
    });

    counter = counter + 1;

    // Function to delete control group.
    $(".removeControlGroup").click(function() {
        $(this).closest("div").remove();
    });

    // add drop down next to control
    $("select").change(function() {
        $(this).parent().append(varDropDown); 

        console.log($(this).parent());
    });
});

});

3 个答案:

答案 0 :(得分:0)

您的$("select")表达式将选择当前页面上的所有 <select>个元素,而不仅仅是刚刚添加的元素。因此,“更改”处理程序将在之前附加的<select>元素中累积,并且会产生您观察到的多重效果。

您可以使用常规表单的表达式更有效地编码整个事物:

$("htmlString").appendTo("container").find("someElement").method(...);

这避免了重新发现DOM中元素的唯一ID。

试试这个:

$(document).ready(function() {
    var aggStageDropDown = "<select class='aggStage'><option value='unselected'>(Select One)</option><option value='group'>Group</option><option value='match'>Match</option><option value='unwind'>Unwind</option><option value='sort'>Sort</option></select>";
    var varDropDown = "<select><option value='var1'>var1</option><option value='var2'>var2</option><option value='var3'>var3</option></select>";

    // First elements in HTML
    var $container = $("<div class='container'></div>").appendTo("body");

    $("<button class='addGroup'>Add More Fields</button>").appendTo($container).click(function() {
        $("<div class='controlGroup'><button class='removeControlGroup'>X</button> " + aggStageDropDown + "</div>").appendTo($(this).closest(".container")).find(".removeControlGroup").click(function() {
            $(this).closest("div").remove();
        }).end().find("select.aggStage").change(function() {
            $(this).parent().append(varDropDown);
        });
    });
});

答案 1 :(得分:0)

要防止多次显示[新字段],您可以添加以下条件:

 $("select").change(function() {
    if ($(this).siblings("select").length) return;
    $(this).parent().append(varDropDown); 

    console.log($(this).parent());
});

答案 2 :(得分:0)

你有

//add drop down next to control
$("select").change(function() {
    $(this).parent().append(varDropDown); 

    console.log($(this).parent());
});

您可以更改为

// add drop down next to control
$("select").change(function() {
    if($(this).parent().find('select').length === 1){
        $(this).parent().append(varDropDown); 
    }

    console.log($(this).parent());
});

这说明每次选择更改时,都会添加一个新的下拉列表。如果你只想要一个

<select>
    <option value='var1'>var1</option>
    <option value='var2'>var2</option>
    <option value='var3'>var3</option>
</select>

然后你需要说你只想添加一个选择,如果它已经没有了。

此外,您的代码正在创建您不想要的重复ID。我认为你想要的最终解决方案是(并且我使得id是唯一的)

$(document).ready(function() {

aggStageDropDown = function(counter) {
    return "<select id='aggStage-operation" + counter + "'>\
        <option value='unselected'>(Select One)</option>\
        <option value='group'>Group</option>\
        <option value='match'>Match</option>\
        <option value='unwind'>Unwind</option>\
        <option value='sort'>Sort</option>\
    </select>\
    "; 

}

varDropDown = function(counter) {
    return "<select>\
        <option value='var1'>var1</option>\
        <option value='var2'>var2</option>\
        <option value='var3'>var3</option>\
    </select>\
    ";
}

// First elements in HTML
$("body").append("<div class='container'></div>")
$(".container").append("<button class='addGroup'>Add More Fields</button>");

var counter = 1;

$(".addGroup").click(function() {

    // Add a <div>, this will contain each group of form elements.
    $(".container").append(function(){
        return "<div class='controlGroup' id='aggStage" + counter + "'></div>";
    });

    // For each .controlGroup, add removeControlGroup button and add drop-down menu.
    $("#aggStage" + counter).html(function(){
        return "<button class='removeControlGroup'>X</button> " + aggStageDropDown(counter);
    });

    counter = counter + 1;

    // Function to delete control group.
    $(".removeControlGroup").click(function() {
        $(this).closest("div").remove();
    });

    // add drop down next to control
    $("select").change(function() {
        if($(this).parent().find('select').length === 1){
            $(this).parent().append(varDropDown); 
        }

        console.log($(this).parent());
    });
});
});