How to deal with cloning rows

Hi all,
I’ve two issues

  • the first one:
    as you can see in the next image (when cloning select input with select2 plugin, the cloned input appears with (the first disabled item append next to the main input)).
  • the second issue :
    I’ve ajax code to append “unit menu” based on “product menu” selection
    when I create a new row, and select an item from “product menu” I expected that the “unit menu” of the same row must affect and append the “unit list” belongs the product in the same row.
    But the behavior according to the next code is very different (after clone the main row the new cloned rows append the “unit menu” in all unit inputs)
$(document).ready(function() {

        var purchase = $('.purchase-row').last().clone();
        let purchaseCount = 0;
        
        $(document).on('click', '.add_item', function() {
            
            var clone = purchase.clone().prop('id', 'product_' + purchaseCount);
            // var clone = purchase.clone().prop('class', 'product_' + purchaseCount);
            console.log('clone: ', clone);
            $(this).prevAll('.purchase-row').first().after(clone.hide());
            clone.slideDown('fast');
            $('#product_'+ purchaseCount).find('#id_pro-product').removeClass('product').addClass('newProduct');
            $('#product_'+  purchaseCount).find('#id_pro-unit').removeClass('unit').addClass('newUnit');
            purchaseCount++;
            console.log('PURCHASE-COUNT: ', purchaseCount);// $(this).parent().slideUp('fast');
                        
            // The next code for reinitialize select2 
            var $example = $(".js-programmatic-init").select2();
            $example.select2();
            
        });

        $(document).on('click', '.purchase-minus', function() {
            if (purchaseCount == 0) {
                // Do nothing.
                alert('You can not delete this row' );
            } else {
                $(this).closest('.purchase-row').remove();
                purchaseCount--;
                console.log('PURCHASE-COUNT2: ', purchaseCount);

            }
        });

        $(document).on('click', '.purchase-broom', function() {
            $(this).closest('.purchase-row').find('input').val('');
        });


        $(document).on('change', '.product', function(e){
            var id = $(this).val();
            console.log('CHANGED-PRODUCT: ', id);
            $.ajax({
                type: 'POST',
                url: '{% url "purchases:get_product_unit" %}',
                // dataType: 'json',
                // async: true,
                // cache: false,
                data: {
                    'pro-product': $('.purchase-row select').closest('.product').val(), // this is right
                    // find('#id_pro-product')
                },
                success: function (data) { 
                    console.log(
                        'FROM SUCCESS: ', data['unit'],
                    );
                    var values_3 = data['unit'];
                    // $('#id_pro-unit').text('');
                    // $('select').closest('.unit').find('select').text('');
                    $('select').closest('.unit').text('');
                    if (values_3.length > 0) {
                        
                        for (var i = 0; i < values_3.length; i++) {
                            // $('#id_pro-unit').append('<option>' + values_3[i] + '</option>');
                            $('select').closest('.unit').append('<option>' + values_3[i] + '</option>');
                        }
                    }
        
                },
                error: function (){
                    console.log('ERROR with ajax request in Adding Purchase !!!');
                },
            });
            e.preventDefault();
        });
//

$(document).on('change', '.newProduct', function(e){
            var id = $(this).val();
            console.log('SUCCESS-CHANGE-PRODUCT-FROM-NEW-CLASS: ', id);
            $.ajax({
                type: 'POST',
                url: '{% url "purchases:get_new_row_unit" %}',
                // dataType: 'json',
                // async: true,
                // cache: false,
                data: {
                    'pro-product': id,
                    // $('#product_'+purchaseCount).closest('.newProduct select').val(),
                    // find('#id_pro-product')
                },
                success: function (data) { 
                    console.log(
                        'FROM SUCCESS-NEW-CLASS: ', data['unit'],
                        'PRODUCT-FROM-NEW-CLASS: ', data['product'],
                    );
                    var values_3 = data['unit'];
                    // $('#id_pro-unit').text('');
                    // $('select').closest('.newUnit').text('');
                    if (values_3.length > 0) {
                        
                        for (var i = 0; i < values_3.length; i++) {
                            // $('#id_pro-unit').append('<option>' + values_3[i] + '</option>');
                            // $('.newUnit select').closest('#product_'+ purchaseCount).append('<option>' + values_3[i] + '</option>');
                            // $('select').closest('#product_'+ purchaseCount).find('.newUnit').append('<option>' + values_3[i] + '</option>');
                            $('select').closest('.newUnit').append('<option>' + values_3[i] + '</option>');
                        }
                    }
        
                },
                error: function (){
                    console.log('ERROR with ajax request in Adding Purchase-New Class !!!');
                },
            });
            e.preventDefault();
        });

    });

Any suggetions.

Thanks for replying .
I’m using Django so you will see something like this
{% render_field pro_form.fieldName %} it represents an input, it’s OK the “id” for this input is (id=“id_pro-fieldNmae”) and the name is (“name=pro-fieldName”) .
I have no (CSS file) for this “Div” and (JS file) is in my original post but I copy it in the next link with HTML code .

Cloning Div

CodePen link

But I tried to remove the class and create new class with the (“purchaseCount”) like this

$('.purchase-row').find('#id_pro-product').removeClass('product').addClass('newProduct');
$('.purchase-row').find('#id_pro-unit').removeClass('unit').addClass('newUnit'); 

the new class is created successfully but when I try to use it to append the new menu to the “unit menu” it makes nothing

I appreciate your help.

I can’t edit my post, why ???

In the last post I forgot the following

$('.purchase-row').find('#id_pro-product').removeClass('product').addClass('product_'+purchaseCount);
$('.purchase-row').find('#id_pro-unit').removeClass('unit').addClass('unit_'+purchaseCount); 

Hope to get help here

My Answer To This Issue After searching and Thinking

Finally I fix my issue as usual . I want to share my solution of this issue. Really it took time to understand how it works and how to access the new row or (in other words “how to access the row inputs itself”).

$(document).on('change', '.product', function(e){
            var product_id = $(this).val();
            let $el = $(this).closest('.purchase-row');
            console.log('SUCCESS-CHANGE-PRODUCT: ', product_id,);
            $.ajax({
                type: 'POST',
                url: '{% url "purchases:get_product_unit" %}',
                data: {
                    'pro-product': product_id,
                },
                success: function (data) { 
                    if (purchaseCount == 0) {
                        console.log('purchase count equal to ZERO: ');
                        console.log(
                            'FROM SUCCESS: ', data['unit'],
                        );
                        var values_3 = data['unit'];               
                        if (values_3.length > 0) {
                        
                            for (var i = 0; i < values_3.length; i++) {
                                $el.find('.unit').append('<option>' + values_3[i] + '</option>');
                            }
                        }
                    } else {
                        let unit = $el.find('.newUnit'); // here I can access the "unit input" of the same row of the "product input"
                        var values_3 = data['unit'];
                        unit.text('');
                        console.log('COUNT IS NOT EQUAL TO ZERO:', values_3);
                        if (values_3.length > 0) {
                            for (var i = 0; i < values_3.length; i++) {
                                unit.append('<option>' + values_3[i] + '</option>');
                            }
                        }
                    }
        
                },
                error: function (){
                    console.log('ERROR with ajax request in Adding Purchase !!!');
                },
            });
            e.preventDefault();
        });

I used one ajax call and remove the second one …
Thanks for all

Thanks for replying (I was needing it before I fix my issue), but thanks any way for pay attention.

unit.text(''); It’s important to reset the drop down input for the new selection menu, If it removed it when you select another product the new menu for this new product append to the old one (i.e imagine that you select product1 the unit menu of it append to unit input.
Then you change your mind and select product4 the new unit menu of this product append to unit input that already has an old unit menu of the product1 and so on).

Briefly unit.text(''); to clean the unit input for the new product input selection.

Any way, I have the first issue still exists.

If you have any suggestion or any guide to fix this issue.
I appreciate your reply so much…

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.