Javascript 递归ID和复制表单元素

Javascript 递归ID和复制表单元素,javascript,jquery,html,Javascript,Jquery,Html,我有以下几把小提琴: ID会适当增加。首先。问题是当我尝试添加一项运动时,虽然它复制了,但复制不正确。要添加的按钮未正确创建自身。例如,如果我选择一项运动,然后填写一个职位,然后添加另一个职位,这一切都很好(第一次)。但当我点击添加另一项运动时,它会立即显示两个位置,并且按钮没有正确复制。我认为错误在我的HTML中,但不确定。以下是我用来复制这项运动的JS: $('#addSport').click(function(){ //increment the value of our co

我有以下几把小提琴:

ID会适当增加。首先。问题是当我尝试添加一项运动时,虽然它复制了,但复制不正确。要添加的按钮未正确创建自身。例如,如果我选择一项运动,然后填写一个职位,然后添加另一个职位,这一切都很好(第一次)。但当我点击添加另一项运动时,它会立即显示两个位置,并且按钮没有正确复制。我认为错误在我的HTML中,但不确定。以下是我用来复制这项运动的JS:

$('#addSport').click(function(){
    //increment the value of our counter
    $('#kpSport').val(Number($('#kpSport').val()) + 1);
    //clone the first .item element
    var newItem = $('div.kpSports').first().clone();
    //recursively set our id, name, and for attributes properly
    childRecursive(newItem, 
        // Remember, the recursive function expects to be able to pass in
        // one parameter, the element.
        function(e){
            setCloneAttr(e, $('#kpSport').val());
    });
    // Clear the values recursively
    childRecursive(newItem, 
        function(e){
            clearCloneValues(e);
    });

希望有人有想法,也许我只是把HTML元素的顺序弄错了?谢谢你的帮助!我希望fiddle比在消息中粘贴一堆代码更有用。

问题在于您的
clearCloneValues
函数。对于确实要清除的元素,它不会区分按钮和其他元素

将其更改为:

// Sets an element's value to ''
function clearCloneValues(element){
    if (element.attr('value') !== undefined && element.attr('type') !== 'button'){
        element.val('');
    }
}
正如@PHPglue在上面的评论中指出的,当添加新位置时,它们被错误地复制(我在这里假设)到新克隆的位置

“添加年份”功能也存在类似的问题

快速修复方法是使用原始表单字段的克隆来初始化变量:

var $template = $('div.kpSports').first().clone();
然后将
addSport
处理程序更改为:

$('#addSport').click(function () {
    //increment the value of our counter
    $('#kpSport').val(Number($('#kpSport').val()) + 1);
    //clone the first .item element
    var newItem = $template.clone();
    …
});
但是,新按钮没有事件绑定,因此任何新的表单元素集仍然缺少功能


即使使用简单、朴素的基于字符串的模板,代码也可以大大简化。Linked是一个未经测试的小提琴,它展示了如何使用这种方法

代码简化为以下内容:

function getClone(idx) {
    var $retVal = $(templates.sport.replace(/\{\{1\}\}/g, idx));

    $retVal.find('.jsPositions').append(getItemClone(idx, 0));
    $retVal.find('.advtrain').append(getTrainingClone(idx, 0));
    return $retVal;
}

function getItemClone(setIdx, itemIdx) {
    var retVal = itemTemplate.replace(/\{\{1\}\}/g, setIdx).replace(/\{\{2\}\}/g, itemIdx);
    return $(retVal);
}

function getTrainingClone(setIdx, trainingIdx) {
    var retVal = trainingTemplate.replace(/\{\{1\}\}/g, setIdx).replace(/\{\{2\}\}/g, trainingIdx);
    return $(retVal);
}

$('#kpSportPlayed').on('click', '.jsAddPosition', function() {
    var $container = $(this).closest('.kpSports');
    var containerIdx = $container.attr('data_idx');
    var itemIdx      = $container.find('.item').length;

    $container.find('.jsPositions').append(getItemClone(containerIdx, itemIdx));
});

$('#kpSportPlayed').on('click', '.jsAddTraining', function() {
    var $container = $(this).closest('.kpSports');
    var containerIdx = $container.attr('data_idx');
    var trainIdx = $container.find('.advtrain > div').length;

    $container.find('.advtrain').append(getTrainingClone(containerIdx, trainIdx));
});

$('#addSport').click(function () {
    var idx = $('.kpSports').length;
    var newItem = getClone(idx);

    newItem.appendTo($('#kpSportPlayed'));
});

为什么不使用模板而不是克隆元素?如果用户可以对要克隆的元素进行更改,并且您必须尝试将所有这些元素重置为默认状态,那么为什么不让函数从模板返回html元素呢?这不是您唯一的问题。当一个职位被添加时,你也在克隆输入。看来我有新的东西要学。你知道我在哪里可以找到关于如何做这些模板的东西吗?我试图搜索,但我似乎没有搜索正确的术语,因为我得到了更多的网站模板。谢谢你的帮助/建议!谷歌“下划线模板”用于更广泛的搜索结果尝试:。根据图书馆的不同,学习曲线可能有点陡峭。如果您当前的需求得到满足,那么从我下面的回答中所述的自建方法开始可能更有意义。然后,当您更好地了解应用程序的需求时,您可以选择最能解决这些特定问题的解决方案。谢谢!看来我做这件事的难度比我需要的要大?克隆模板是更好/更容易/不受未来影响的方法吗?是的-创建模板的方法有很多,但其中之一是使用基于字符串的方法,然后将id的数字偏移量传递给返回已实现克隆的函数。另一种方法是使用jQuery构建结果表单(.append/.appendTo等),再次传递数值偏移量。还有许多模板库也可以用于此。顺便说一句:动态子元素的ID存在另一个bug-ID被复制(以检查您的位置输入ID为例)@lobstahcrushah我添加了一个简单的基于模板的示例-我想我已经抓住了前面提到的大多数问题。YMMV:)太感谢你了,dc5!你有网站或联系方式吗?我有个问题要问你。再次感谢你!