Как правильно клонировать что-то в Javascript / JQuery? - PullRequest
0 голосов
/ 08 мая 2020

Я использую .clone () для дублирования формы. Я вношу небольшие изменения в клон и помещаю его после последней формы. Как видно на скриншоте, в основном он работает; они выглядят одинаково. Приложение (Django / Python) также может обработать клон, как только я нажму «Сохранить».

enter image description here

Проблема в том, что виджет календаря не открывается при нажатии (в форме клонирования). Он открывается, если я нажимаю кнопку виджета для формы, которая уже существует на странице при первой загрузке (не клон). Но на моих клонах средство выбора даты не открывается.

Как он должен выглядеть после того, как я нажимаю на него (вместо этого ничего не происходит):

enter image description here

Клонированный html кажется идентичным во всех отношениях.

Существующая форма: enter image description here

Клон: enter image description here

ИЗМЕНИТЬ прослушиватели событий: при просмотре прослушивателей событий для тега событие по щелчку кажется мне отсутствующим.

Существующая форма:

enter image description here

Клон:

enter image description here

Что-то не хватает в клонированном html? Или что-то за кулисами не работает? Я просто не понимаю, что здесь сломано.

JS / JQuery:

function cloneMore(selector, prefix,form_class) {
    var newElement = $(selector).clone(true);
    var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
    newElement.find(':input:not([type=button]):not([type=submit]):not([type=reset])').each(function() {
        var name = $(this).attr('name').replace('-' + (total-1) + '-', '-' + total + '-');
        var id = 'id_' + name;
        $(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');

    });
    newElement.find('label').each(function() {
        var forValue = $(this).attr('for');
        if (forValue) {
          forValue = forValue.replace('-' + (total-1) + '-', '-' + total + '-');
          $(this).attr({'for': forValue});
        }
    });
    total++;
    $('#id_' + prefix + '-TOTAL_FORMS').val(total);
    $(selector).after(newElement);
    return false;
}

        $(document).on('click', '.add-form-row', function(e){
            e.preventDefault();
            cloneMore('.form-row-payment:last', 'payment_invoice','form-row-payment');
            return false;
        });

HTML:

 {{ payments_formset.management_form }}
    {{ payments_formset.media }}

<h3>Payments</h3>
            {% for formpay in payments_formset %}
                <div class="form-row form-row-payment row container"  name="payment_form" style="padding:0px;" id="payment_formset">
                    {{ formpay.non_form_errors }}
                    {{ formpay.non_field_errors }}

                    {% for hidden in formpay.hidden_fields %}
                    {{ hidden }}
                {% endfor %}                            
                {% for field in formpay %}
                    {% if field.name != 'index' and field.name != 'invoice'%}

                        <div class="col-sm">
                            {{ field.errors }}
                            {{ field|as_crispy_field }}
                            {% if field.help_text %}
                            <p class="help">{{ field.help_text|safe }}</p>
                            {% endif %}                            
                        </div>
                    {% endif %}
                {% endfor %} 
            </div>                    
            {% endfor %}
        <div class="input-group-append">
                    <button class="btn btn-success add-form-row">+</button>
            </div> 

1 Ответ

0 голосов
/ 08 мая 2020

Вы делаете копию HTML объектов, но у них нет тех же обработчиков событий, что и у исходного объекта. Чтобы исправить это, я бы предложил создать функцию, которая сбрасывает обработчики событий для клонированных элементов.

Это можно сделать примерно так:

function resetCalendarClickHandler(){
    $(".input-group-addon").unbind("click") //remove current event handlers to prevent duplication when adding new one
    $(".input-group-addon").click(<yourEventHandler>);
}

Получив это, вы можете добавить вызов этой функции в конце своей функции cloneMore(), и это повторно назначит обработчики событий и включит клонированные элемент, поскольку он будет частью вашего HTML на этом этапе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...