简体   繁体   English

jQuery-克隆datepicker和select2

[英]JQuery - cloning datepicker and select2

I asked a similar question yesterday, but after a few additions, things seem to have gone pear shaped. 昨天我问了一个类似的问题,但是添加了几句之后,事情似乎变得像梨子了。 I have some HTML which takes the following form 我有一些采用以下形式的HTML

<div class="form-group">
    <div class="row">
        <div class="col-md-12">
            <div class="col-md-12">
                <table class="table table-bordered" id="actionTable">
                    <tbody>
                    <tr id='actionRow1'>
                        <td>
                          <input type="text" name='actionInput[0][action]' id="actionInput"  placeholder='Action' class="form-control"/>
                        </td>
                        <td>
                          <select class="responsibility" name='actionInput[0][responsibility]' id="responsibilityInput">
                                <option value="One">One</option>
                                <option value="Two">Two</option>
                                <option value="Three">Three</option>
                            </select>
                        </td>
                        <td>
                          <input type="text" name='actionInput[0][deliveryDate]' id="dateInput" placeholder='Completion Date' class="form-control dateControl"/>
                        </td>
                      </tr>
                    </tbody>
                </table>
                <a id="add_row" class="btn btn-default pull-right">Add Row</a>
                <a id='delete_row' class="pull-right btn btn-default">Delete Row</a>
            </div>
        </div>
    </div>
</div>

So it has a text input, a select, and another text for the date. 因此,它具有文本输入,选择和日期的其他文本。 The names for the input are a 2D array because I need to handle this data in a specific way later. 输入的名称是2D数组,因为稍后我需要以特定方式处理此数据。

Anyways, when an Add Row button is clicked, it should clone the whole tr. 无论如何,当单击“添加行”按钮时,它应该克隆整个tr。 This includes destroying the select2 and datepicker, as well as updating the names and id's of the new inputs. 这包括销毁select2和datepicker,以及更新新输入的名称和ID。 To do this, I have the following JS 为此,我有以下JS

$(function() {
    $('#add_row').on('click', function(evt){addRow();});
    $('#delete_row').on('click', function(evt){deleteRow();});
});

function addRow() {

    $("table tr#actionRow1").eq(0).clone().each(function(tr_idx, tr_elem) {

        $(".dateControl").datepicker("destroy");

        $(".responsibility").select2("destroy");

        var
            $tr = $(tr_elem),
            newRowIdx = $("table tr").length;

        $tr.attr('id', 'actionRow' + newRowIdx);

        $tr.find("input, select").each(function(i_idx, i_elem) {

            var $input = $(i_elem);

            if($input.attr('id') == 'actionInput') {
                $(this).val("");
            }

            if ($input.hasClass('dateControl')) {
                $(this).val("");
            }

            $input.attr({
                'id': function(_, id) {
                    return id + newRowIdx;
                },
                'name': function(_, id) {
                    return id.replace('[0]', '['+ newRowIdx +']');
                },
                'value': ''
            });
        });

        $(".dateControl").datepicker({
            dateFormat: "dd-mm-yy"
        });

        $(".responsibility").select2({
            tags: true
        });

    }).appendTo("table");
}

function deleteRow() {
    curRowIdx = $("table tr").length;
    if (curRowIdx > 1) {
        $("#actionRow" + (curRowIdx - 1)).remove();
        curRowIdx--;
    }
}

I have set up the following JSFiddle to demonstrate. 我设置了以下JSFiddle进行演示。

In the Fiddle, I have had to comment out the destroy methods otherwise it throws an error. 在小提琴中,我不得不注释掉destroy方法,否则会引发错误。 First problem, on first visit, the datepicker and select2 are not working. 第一个问题,第一次访问时,datepicker和select2不起作用。 When you click Add Row, the previous rows datepicker and select2 then works, but the new one does not. 当您单击添加行时,先前的行datepicker和select2将起作用,但是新行无效。 So it is sort of delayed. 因此,这有点延迟。 Once you start adding multiple rows, it decides to add multiple select boxes in some of the rows. 一旦开始添加多行,它将决定在某些行中添加多个选择框。 Not too sure why this is happening. 不太清楚为什么会这样。

Any advice in sorting this out much appreciated. 任何意见,以解决这一点非常赞赏。

Thanks 谢谢

Calling $(".dateControl").datepicker(); 调用$(".dateControl").datepicker(); will attempt to initialise a datepicker widget on all elements matching ".dateControl" currently in the DOM. 会尝试在DOM中当前与".dateControl"匹配的所有元素上初始化日期选择器小部件。 Thus on the first click you'd initialise it on the first row (but NOT on the one you're cloning, since it hasn't been appended yet!). 因此,在第一次单击时,您要在第一行上对其进行初始化(但不要在要克隆的行上进行初始化,因为尚未附加它!)。 The third row added then re-initialises the datepicker on the first row and initialises it on the second, etc. Same for the other widget. 添加的第三行然后在第一行中重新初始化日期选择器,并在第二行中将其初始化,依此类推。其他小部件相同。 You should restrict the matcher to only the row you're currently working on: 您应该将匹配器限制为当前正在处理的行:

$(".dateControl", $tr).datepicker({
  dateFormat: "dd-mm-yy"
});

$(".responsibility", $tr).select2({
  tags: true
});

You don't need the destroy calls at all if you do this. 如果执行此操作,则根本不需要destroy调用。 Also, make sure you call these for the first row explicitly (see NicolasR's comment) 另外,请确保您明确地为第一行调用这些名称(请参阅NicolasR的注释)


Also, the datepicker creates a new table element, so you need to target your own table everywhere you use the table selector. 此外,日期选择器还会创建一个新的table元素,因此您需要在使用表格选择器的任何地方定位自己的表格。 Otherwise the addRow function will stop working correctly after the first time you open a datepicker (which is when the new table is appended to the DOM, and the "table" selector in the appendTo line starts matching it): https://jsfiddle.net/r94pkLLb/3/ 否则addRow功能将停止第一次打开一个datepicker后正常工作(这是当新的表被附加到DOM和"table"中选择appendTo行开始匹配吧): https://开头的jsfiddle。净/ r94pkLLb / 3 /

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM