2015-11-15 6 views
1

Я пытаюсь создать простой пользовательский интерфейс для построителя запросов агрегации MongoDB. В основном пользователь должен нажать на раскрывающийся список (Group By, Sort, Limit и т. Д.), Затем рядом с ним появится другое поле, чтобы выбрать переменную.jQuery динамическая форма добавления виджета

Проблема в том, что поле отображается несколько раз после того, как выбрана первая выпадающая.

[Группировать] [Новое поле] [Новое поле] [New Field]

код [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()); 
    }); 
}); 

});

ответ

1

Ваше $("select") выражение будет выбрать все<select> элементы в настоящее время на странице, а не только тот, который только что был добавлен. Поэтому обработчики «change» будут накапливаться в ранее прикрепленных элементах <select> и будут давать множественный эффект, который вы наблюдали.

Вы можете закодировать все это более эффективно с выражениями общего вида:

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

Это исключает необходимость уникальных идентификаторов для элементов заново в DOM.

Попробуйте это:

$(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

Чтобы предотвратить показ [New Field] несколько раз можно добавить следующее условие:

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

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

Вы

//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> 

, то вам нужно сказать, что вы хотите добавить только отборное, если она не существует уже.

Кроме того, ваш код создает дубликаты идентификаторов, которые вы не хотите. Окончательное решение по тому, что, я считаю, вам нужно (и я сделал его уникальным)

$(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()); 
    }); 
}); 
}); 
Смежные вопросы