克隆tr以添加新项目并替换选择框

时间:2016-06-29 14:57:03

标签: javascript jquery

我有一个代码,我必须克隆受尊重的tr并创建新的,但tr有一个列有一个选择,该选择有一个值,当选择时将选择框转换为文本框然后再我点击添加项目,它添加了另一个文本文本,我知道它是hapening,因为我只是克隆它。

我怎么能解决它,我有点困惑

这是我的代码

<table>
<tr><td><input type="text"></td></tr>
        <tr>
            <td><div id="stlineitems">
              <label for="stlineitems">Item(s)</label></td>
            <td><div class="onlyleft">
                <select name="get_Items" id="get_Items" class="selectItemsList" data-rule-required="true" data-msg-required="Choose Item">
                  <option></option>
                </select>
              </div>
              <div class="moveboxleft">
                <select name="getSelection" class="form-control getSelectedprice">
                    <optgroup label="Class Price">

                        <option value="160.0000">$160.00</option>

                    </optgroup>

                    <optgroup label="Custom Price">
                        <option value="0">$0</option>
                        <option value="-2">My Price</option>
                        <option value="-1">Custom Price</option>
                    </optgroup>
                </select>
              </div><div class="moveboxleftinput" style="display:none;">
                <input type="text" name="getSelection" value="" class="form-control">
              </div>
              <br/>
              <div class="nextitem"><a href="javascript:void(0);" class="createNewItemTag">Add Item</a></div></td>
              </div>
          </tr>
    </table>


    $('.createNewItemTag').click(function(){
        var obj = $(this).parents('tr').first();
        var clonedObj = $(obj[0].outerHTML);
        clonedObj.find(".select2-container").remove();
        clonedObj.find('.createNewItemTag').remove();
        clonedObj.find('td').last().append("<a class='removeItem' href='javascript:void(0);'>Remove</a>");
        clonedObj.find(".removeItem").click(function(){
            $(this).parents('tr').first().remove();
        }); 
        obj.before(clonedObj);
        initSelect2ForNextItem(clonedObj.find(".selectItemsList").first());
    });

    $(document).on('change','.getSelectedprice',function() {
        if ($('.getSelectedprice option:selected').text() == "Custom Price"){
            $('.moveboxleft').hide();
            $('.moveboxleftinput').show();
        }else {
            $('.moveboxleft').show();
            $('.moveboxleftinput').hide();
        }
    });

2 个答案:

答案 0 :(得分:0)

您的HTML无效。例如,您尚未关闭第一个td标记中的第一个div:

<tr>
    <td>
        <div id="stlineitems">
            <label for="stlineitems">Item(s)</label>
        <!-- Close div should go here -->
    </td>

尝试更正HTML并重新评估您的代码,然后在遇到问题时重新提交。

答案 1 :(得分:0)

你确实有一些不正确的嵌套HTML应该修复。

但至于克隆。我的建议是在使用任何事件处理程序或其他插件(如Select2)进行检测后,永远不要克隆项目。避免这种情况的方法是执行以下操作:

  1. 在页面加载时立即克隆行(在注册事件处理程序和检测之前)。
  2. 每当需要新行时,克隆原始克隆。这样你仍然可以反复克隆原始克隆。
  3. 尽可能使用事件委托来注册事件处理程序。
  4. 如果您需要检测新添加的行上的任何元素,请在将其插入页面后执行此操作。
  5. 在你的情况下,你可以这样:

    var $table = $('table');
    
    var $CLONED_ROW = $table.find('tbody>tr:first').clone();
    $CLONED_ROW.find('.createNewItemTag').replaceWith(
        '<a class="removeItem" href="#">Remove</a>');
    
    $table.on('click', '.createNewItemTag', function(e) {
        e.preventDefault();
        var $row = $(this).closest('tr'),
            $newRow = $CLONED_ROW.clone();
        $newRow.insertBefore($row);
        //initSelect2ForNextItem($newRow.find('.selectItemsList'));
    });
    
    $table.on('click', '.removeItem', function(e) {
        e.preventDefault();
        $(this).closest('tr').remove();
    }); 
    
    $table.on('change', '.getSelectedprice', function() {
        var $select = $(this),
            $row = $select.closest('tr');
        if ($select.val() == '-1') {
            $row.find('.moveboxleft').hide();
            $row.find('.moveboxleftinput').show();
        } else {
            $row.find('.moveboxleft').show();
            $row.find('.moveboxleftinput').hide();
        }
    });
    
    //initSelect2ForNextItem($table.find('.selectItemsList'));
    

    请注意将调用放置在initSelect2ForNextItem()

    jsfiddle

    还有一些事情:

    1. 您可以使用.closest()代替.parents().first()
    2. 隐藏/显示文本输入时,需要将其限制为当前行。
    3. 最好使用select元素的值,而不是文本。