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);
})
}
So I have made some changes to your code -
template literals
here because I like it :)$(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.e.target
where e
is the event object.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>
You can use class selector instead of ids
Example:
...
$(wrapper).append(<select class="form-control cam_select" >...</select>...)
...
$('.cam_select').on('change',function () {
var email = $('option:selected',this).attr("email");
var phone = $('option:selected',this).attr("phone");
$(this).parent().children('.cm_email').val(email);
$(this).parent().children('.cm_email').val(phone);
})
I have not tried the code, sorry if there are errors
@Allesandro made a move in the right way.
You can detach the event handler code from the creation method (button click) and just supply the event handler logic in the script so it is available to the document and controls we are talking about.
But, you have to make this a so-called jQuery delegated event handler that will work for newly created controls on-the-fly (which is your scenario) and for controls matching the selector that were in the html already when the document was initially loaded: it looks like this:
$(document).on('change', '.cam_select', function () {
...
})
You can also be more specific off course and use wrapper
for the initial selector instead of document
.
Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.