I want to apply a logic from which I can use give new generated class to new added element.
I want that whenever I click on Add Another
, it will add new file browse and I can select different images from that. The first image should always be primary and others will be secondary.
When I click on remove link, corresponding file browse and dropdown should be removed.
$(document).ready(function(){ $(".browse").click(function(){ $(".myfile").click(); }); $(".myfile").on('change', function() { $(".path").val(this.files[0].name); }); $(".add").click(function(){ $("form").append("<div>"+$("form div:first-child").html()+"<br>"+"</div>"); }); $(".remove").click(function(){ $("form div:last-child").remove(); }); });
.main{ width: 100%; } .sub1{ border: 2px solid #808080; padding-left: 10px; } .sub2{ display: flex; border: 1px solid #808080; } .child1{ width: 20%; padding-left: 10px; border: 1px solid #808080; } .child2{ width: 80%; padding: 10px; border: 1px solid #808080; } .add{ cursor: pointer; } .upload1{ display: none; } .browse{ display: inline-block; width: 80px; height: 18px; background-color: #d3d3d3; color: #000; border: 1px solid black; border-radius: 2px; cursor: pointer; } .browsebut{ margin-left: 16px; } .myf{ position: absolute; } /* position: absolute; opacity: 5; top: 74px; display: -webkit-box; */
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Browse</title> <!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script> --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <link rel="stylesheet" href="style.css"> </head> <body> <div class="main"> <div class="sub1"> <p>Property Image</p> </div> <div class="sub2"> <div class="child1"> <p>Property Image</p> </div> <div class="child2"> <form> <div class="upload"> <input type="text" name="path" class="path" value="no file selected"> <div id="browse" class="browse"><span class="browsebut">Browse</span></div> <div class="myf"> <label for="myfile"></label> <input type="file" class="myfile" name="myfile" accept="image/*" hidden > </div> <select id="img"> <option value="1">primary</option> <option value="1">secondaryimg</option> </select> <a href="#" class="remove">Remove</a> </div> </form> <div class="add"> <p>Add Another</p> </div> </div> </div> </div>[enter image description here][1] <script src="index.js"></script> </body> </html>
Answer
For what you’re trying to achieve, need to use event delegates. When new elements are dynamically added, the handlers added by the your original jQuery code is only aware of the first row’s elements, which is why none of the other row elements seemed to work after adding additional rows.
There were a couple of corrections applied:
- For the row elements, I removed all
id
attributes, for these need to be unique in the document. - Both select options had
value="1"
, so I set thesecondaryimg
option tovalue="2"
- Removed the unused
label
tag.
Other:
- Used
placeholder
with the first input to show theno file selected
text. - See the
.add
handler for the handling to set theselect
option tosecondaryimg
- The
remove
event handler does not allow the primary (first element) to be removed. (feel free to eliminate the condition wrappingremove()
if not needed) - Having repeated elements with the same
name
is why only the first entry is retrieved. Now that there will be one or more rows, the name attributes forpath
,myfile
and theselect
all need the array syntax, so that whenever you submit, you can easily iterate the list. Thepath
inputname
attribute changes toname="path[]"
. Themyfile
inputname
attribute changes toname="myfile[]
, and the select did not have a name attribute, so I usedname="imgOpt[]"
, feel free to rename as desired. At submit, the iteration ofpath[0]
,myfile[0]
, andimgOpt[0]
all refer to the first row. Simply increase the index for the other rows. - See the jquery code comments for the updated handling.
Try the runnable example below.
$(document).ready(function(){ // Browse button event delegate $('form').on('click', '.browse', function(){ // Fire click for myfile input on the SAME row $(this).next().find('input').click(); }); // Myfile change event delegate $('form').on('change', '.myfile', function() { // Copy the image to the path input on the SAME row. $(this).parent().siblings().first().val(this.files[0].name); }); $(".add").click(function(){ $("form").append("<div>"+$("form div:first-child").html()+"<br>"+"</div>"); // Set the added select to the 2nd (secondaryimg) option. $('select').last().val(2); }); // Anchor tag event delegate $("form").on('click', 'a.remove', function() { if (!$(this).is($('a')[0])) { // Don't remove the first primary anchor tag? $(this).parent().remove(); } }); });
.main{ width: 100%; } .sub1{ border: 2px solid #808080; padding-left: 10px; } .sub2{ display: flex; border: 1px solid #808080; } .child1{ width: 20%; padding-left: 10px; border: 1px solid #808080; } .child2{ width: 80%; padding: 10px; border: 1px solid #808080; } .add{ cursor: pointer; } .upload1{ display: none; } .browse{ display: inline-block; width: 80px; height: 18px; background-color: #d3d3d3; color: #000; border: 1px solid black; border-radius: 2px; cursor: pointer; } .browsebut{ margin-left: 16px; } .myf{ position: absolute; } /* position: absolute; opacity: 5; top: 74px; display: -webkit-box; */
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Browse</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <link rel="stylesheet" href="style.css"> </head> <body> <div class="main"> <div class="sub1"> <p>Property Image</p> </div> <div class="sub2"> <div class="child1"> <p>Property Image</p> </div> <div class="child2"> <form> <div class="upload"> <input type="text" name="path[]" class="path" placeholder="no file selected" value=""> <div class="browse"> <span class="browsebut">Browse</span> </div> <div class="myf"> <input type="file" class="myfile" name="myfile[]" accept="image/*" hidden> </div> <select name="imgOpt[]"> <option value="1">primary</option> <option value="2">secondaryimg</option> </select> <a href="#" class="remove">Remove</a> </div> </form> <div class="add"> <p>Add Another</p> </div> </div> </div> </div> <script src="index.js"></script> </body> </html>