javascriptjqueryhtmljquery-traversing

how to set onchange function to each append div element


I have a button that adds a new div with a select tag, every option has custom attributes. my problem is when I create a several divs the function only refers to the last div I have created when I am trying to change the first select tag the function not responding.

I have tried to give all of the divs and the input a different id's but that doesn't work.

 <button type="button" class="cam_field_button btn waves-effect waves-light btn-outline-info" >הוסף צלם</button>


var max_fields = 25; //maximum input boxes allowed
var wrapper = $(".camera_men"); //Fields wrapper
var add_button = $(".cam_field_button"); //Add button ID

var x = 0; //initlal text box count
$(add_button).click(function (e) { //on add input button click
    e.preventDefault();
    if (x < max_fields) { //max input box allowed
        x++; //text box increment
        $(wrapper).append('<div>   <br> <select name="cam[]"  id="cam_select'+x+'"  class="form-control" >\n' +
            '                                            <option email="email" phone="phone"  value="צלם 1">צלם 1</option>\n' +
            '                                            <option email="email2" phone="phone2" value="צלם 2">צלם 2</option>\n' +
            '                                            <option email="email3" phone="phone3" value="צלם 3">צלם 3</option>\n' +
            '                                        </select><a href="#" class="remove_field">הסר צלם ' + x + '</a><div>  <input type="hidden" name="cam_email[]" id="cm_email' + x + '">\n' +
            '                                        <input type="hidden" name="cam_phone[]" id="cm_phone' + x + '">'); //add input box
        $('#cam_select'+x).on('change',function () {


            var email =  $('#cam_select'+x+' option:selected').attr("email");
            var phone =  $('#cam_select'+x+' option:selected').attr("phone");

            $('#cm_email'+x).val(email);
            $('#cm_phone'+x).val(phone);
        })
    }

Solution

  • So I have made some changes to your code -

    1. Use classes instead of ids - because you can't have mutliple id's.
    2. I have used template literals here because I like it :)
    3. See how I am using a dynamic jquery listener using $(document).on('change', '.cam_select' + x, function(e) { - the off('change') to ensure that there are no duplicate listeners though here there isn't any.
    4. Also we can get the clicked element using e.target where e is the event object.
    5. Note that I have added one more wrapper to the appended markup - cam and how I am using it using the closest function and then find methods to find siblings and cousins in the cam wrapper which was dynamically inserted.

    Check out the demo below illustrating these:

    $(document).ready(function() {
      var max_fields = 25;
      var wrapper = $(".camera_men"); 
      var add_button = $(".cam_field_button");
      var x = 0; 
      $(add_button).click(function(e) {
        e.preventDefault();
        if (x < max_fields) {
          x++;
          $(wrapper).append(`
            <div class="cam">
              <div>
                <select name="cam[]" class="form-control cam_select">
                  <option email="email" phone="phone" value="צלם 1">צלם 1</option>
                  <option email="email2" phone="phone2" value="צלם 2">צלם 2</option>
                  <option email="email3" phone="phone3" value="צלם 3">צלם 3</option>
                </select>
    	        <a href="#" class="remove_field">הסר צלם ${x}</a>
    		  <div>
              <input type="input" name="cam_email[]" class="cm_email">
              <input type="input" name="cam_phone[]" class="cm_phone">
            </div>`);
          $(document).off('change').on('change', '.cam_select', function(e) {
            var email = $(e.target).find('option:selected').attr("email");
            var phone = $(e.target).find('option:selected').attr("phone");
            $(e.target).closest('.cam').find('.cm_email').val(email);
            $(e.target).closest('.cam').find('.cm_phone').val(phone);
          });
        }
      });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <button type="button" class="cam_field_button btn waves-effect waves-light btn-outline-info">הוסף צלם</button>
    
    <div class="camera_men"></div>