Home > Back-end >  changing input value of one field when another is typed not working for multiple fields
changing input value of one field when another is typed not working for multiple fields

Time:06-30

i have a website where i have a form, the form has 3 fields which can be addedd multiple times on click, my code is like below:

$(document).ready(function() {
  var max_fields = 10;
  var wrapper = $(".container1");
  var add_button = $("#niy");

  var x = 1;
  $(add_button).click(function(e) {
    e.preventDefault();
    if (x < max_fields) {
      x  ;
      $(wrapper).append('<div ><div ><label for="client_type">Service Type</label><input type="text"  id="client_type" required name="service[]"></div></div><div ><div ><label for="client_type">Price</label><input type="text"  id="client_type" required name="price[]"></div></div><div ><div ><label for="client_type">Total</label><input type="text"  id="total" required name="total[]"></div></div>'); //add input box
    } else {
      alert('You Reached the limits')
    }
  });

  $(wrapper).on("click", ".delete", function(e) {
    e.preventDefault();
    $(this).parent('div').remove();
    x--;
  })
});



$('input[name="price[]"]').change(function() {
  $('input[name="total[]"]').val($(this).val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
  <div >
    <!-- Form -->
    <div >
      <label for="client_type">Service Type</label>
      <input type="text"  id="client_type" required name="service[]">
    </div>
  </div>
  <div >
    <!-- Form -->
    <div >
      <label for="client_type">Price</label>
      <input type="text"  id="client_type" required name="price[]">
    </div>
  </div>
  <div >
    <!-- Form -->
    <div >
      <label for="client_type">Total</label>
      <input type="text"  id="client_type" required name="total[]">
    </div>
  </div>
</div>
<a id="niy"  style="color:white">Add New Service Field &nbsp;
      <span style="font-size:16px; font-weight:bold;">  </span>
    </a>

i want the total field to show the value from its respective price field, however here only first row does that, can anyone please tell me how to fix this, thanks in advance

CodePudding user response:

The main issue in your code is because you only bind the change event which updates the value of the fields when the page first loads. This ignores all the fields which are added dynamically. To fix this use delegated event handlers - exactly as you are for the .delete button.

That being said, it's worth noting that there's several other issues which need to be addressed:

  • Don't repeat the same id attribute value in the DOM. They need to be unique. Also, don't use id at all in content which can be repeated dynamically. Use class attributes instead.
  • Don't use inline styling with the style attribute. It's bad practice to put one type of code in another, eg. CSS in your HTML, or HTML in your JS. In this case use an external stylesheet.
  • Similarly, don't put HTML in your JS. Clone existing content instead of dumping a lot of HTML in the JS. In your original, if you changed the HTML template, then you'd need to also remember to update the JS file too. Using cloning avoids this problem.
  • Don't double-wrap your jQuery objects. Eg. add_button is already a jQuery object, you don't need to use $(add_button). It's worth prefixing variable names that hold jQuery objects with $ for this reason.
  • Don't use global variables where possible. They're bad practice for a variety of reasons, not least of which is that they lead to more length and harder to maintain code. A better approach in this case is to retrieve the number of elements already existing in the DOM and compare that to the known limit.

With all that said, here's a working demo:

jQuery($ => {
  var max_fields = 10;
  var $container = $(".container");
  var $add_button = $("#niy");

  $add_button.on('click', e => {
    e.preventDefault();

    if ($('.row').length >= max_fields) {
      alert('You Reached the limits');
      return;
    }

    let $newContent = $('.row:first').clone().appendTo($container);
    $newContent.find(':input').val('');
  });

  $container.on("click", ".delete", e => {
    e.preventDefault();
    $(e.target).closest('.row').remove();
  })
  
  $container.on('change', '.price', e => {
    $(e.target).closest('.row').find('.total').val(e.target.value);
  });
});
body {
  background-color: #CCC;
}

#niy {
  color: white;
}

#niy span {
  font-size: 16px;
  font-weight: bold;
}

label {
  width: 100px;
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
  <div >
    <div >
      <div >
        <label for="client_type">Service Type</label>
        <input type="text"  required name="service[]">
      </div>
    </div>
    <div >
      <div >
        <label for="client_type">Price</label>
        <input type="text"  required name="price[]">
      </div>
    </div>
    <div >
      <div >
        <label for="client_type">Total</label>
        <input type="text"  required name="total[]">
      </div>
    </div>
  </div>
</div>
<a id="niy" >
  Add New Service Field &nbsp;
  <span>  </span>
</a>

CodePudding user response:

try below snippet once, you will find runtime oninput updating totals. That imrpoves user experience.

$(document).ready(function() {
    var max_fields = 10;
    var wrapper = $(".container1");
    var add_button = $("#niy");

    var x = 1;
    $(add_button).click(function(e) {
        e.preventDefault();
        if (x < max_fields)
        {
            x  ;
            $(wrapper).append('<div ><div ><label for="service_type' x '">Service Type</label><input type="text"  data-id="' x '" id="service_type' x '" required name="service[]"></div></div><div ><div ><label for="price_type' x '">Price</label><input type="text"  data-id="' x '" id="price_type' x '" required name="price[]"></div></div><div ><div ><label for="total_type' x '">Total</label><input type="text"  data-id="' x '" id="total_type' x '" readonly name="total[]"></div></div>'); 
        }
        else
        {
            alert('You Reached the limits')
        }
    });
    $(wrapper).on("click", ".delete", function(e) {
        e.preventDefault();
        $(this).parent('div').remove();
    })
});

$(document).on('input', '.service_type, .price_type', function(){
    var id = $(this).attr('data-id');
    if(id > 0)
    {
        var service_type = parseFloat($('#service_type' id).val()) || 0;
        var price_type = parseFloat($('#price_type' id).val()) || 0;
        var total_type = service_type   price_type;
        $('#total_type' id).val(total_type.toFixed(2));
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
    <div >
        <!-- Form -->
        <div >
            <label for="service_type1">Service Type</label>
            <input type="text"  id="service_type1" data-id="1" required name="service[]">
        </div>
    </div>
    <div >
        <!-- Form -->
        <div >
            <label for="price_type1">Price</label>
            <input type="text"  id="price_type1" data-id="1" required name="price[]">
        </div>
    </div>
    <div >
        <!-- Form -->
        <div >
            <label for="total_type1">Total</label>
            <input type="text"  id="total_type1" data-id="1" readonly name="total[]">
        </div>
    </div>
</div>
<a id="niy" >Add New Service Field &nbsp;
    <span style="font-size:16px; font-weight:bold;">  </span>
</a>

  • Related