Reputation: 789
So I have this code but I tought it was too repetitive, anyone has an idea how I could do that? When a upload a new image, I want a new image box to show up. My solution works, but what if I would like to have 1000 new images? I can't just type one at the time. What could I do to optimise this problem?
HTML:
<div class="wrapper">
<div class="box box_image" id="box_image_1">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" id="image1" data-show='box_image_2' name="IgniteFormObject.Image1" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
<div class="box box_image" id="box_image_2">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" id="image2" data-show='box_image_3' name="IgniteFormObject.Image2" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
<div class="box box_image" id="box_image_3">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" id="image3" data-show='box_image_4' name="IgniteFormObject.Image3" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
<div class="box box_image" id="box_image_4">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" id="image4" data-show='box_image_5' name="IgniteFormObject.Image4" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
<div class="box box_image" id="box_image_5">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" id="image5" name="IgniteFormObject.Image5" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
</div>
Javascript:
When an image is uploaded, this JQuery is called.
$('#image1').change(function (ev) {
$("#box_image_2").show();
});
$('#image2').change(function (ev) {
$("#box_image_3").show();
});
$('#image3').change(function (ev) {
$("#box_image_4").show();
});
$('#image4').change(function (ev) {
$("#box_image_5").show();
});
Upvotes: 1
Views: 130
Reputation: 33933
Strictly based on your markup and how you had unique ids for each elements...
The key is to retreive that id
from the parent container and increment by one to show the next.
// Hide all containers except the first, on load (possibly already achieved via CSS)
$("[id^='box_image_']").not(":first").hide();
// Change handler
$("[id^='image']").change(function(ev) {
// Retreive the index part of the container's id
var parent_box_image_id = $(this).closest("[id^='box_image_']").attr("id").split("box_image_")[1];
console.log(parent_box_image_id);
// Increment by one
parent_box_image_id++;
// Show the next one!
$("#box_image_"+parent_box_image_id).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class="box box_image" id="box_image_1">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" id="image1" data-show='box_image_2' name="IgniteFormObject.Image1" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
<div class="box box_image" id="box_image_2">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" id="image2" data-show='box_image_3' name="IgniteFormObject.Image2" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
<div class="box box_image" id="box_image_3">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" id="image3" data-show='box_image_4' name="IgniteFormObject.Image3" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
<div class="box box_image" id="box_image_4">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" id="image4" data-show='box_image_5' name="IgniteFormObject.Image4" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
<div class="box box_image" id="box_image_5">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" id="image5" name="IgniteFormObject.Image5" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
</div>
But there could be another way to do the same more efficiently... Like squarely forgetting about the ids and use classes... Have a look at this other snippet below. ;)
// Hide all containers except the first, on load (possibly already achieved via CSS)
$(".box_image").not(":first").hide();
// Change handler
$(".image-upload").change(function(ev) {
$(this).closest(".box_image").next().show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class="box box_image" class="box_image">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" name="IgniteFormObject[]" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
<div class="box box_image" class="box_image">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" name="IgniteFormObject[]" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
<div class="box box_image" class="box_image">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" name="IgniteFormObject[]" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
<div class="box box_image" class="box_image">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" name="IgniteFormObject[]" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
<div class="box box_image" class="box_image">
<div class="js--image-preview"></div>
<div class="upload-options">
<label>
<input type="file" class="image-upload" name="IgniteFormObject[]" accept="image/*" enctype="multipart/form-data" />
</label>
</div>
</div>
</div>
Upvotes: 0
Reputation: 36574
You can try this method using for loop.
for
loopchange
function to image${i}
.change
function call show()
on box_image_${i+1}
I also used Template Literals in my code
for(let i = 1;i<=4;i++){
$(`#image${i}`).change(function (ev) {
$(`#box_image_${i+1}`).show();
})
}
Upvotes: 1
Reputation: 462
You can simply use classes like this:
$('.image').change(function (ev) {
$(this).next(".box_image").show();
});
Upvotes: 1
Reputation: 50291
You can use data
attribute and multiple selector. In the data attribute pass the id
of the element which you want to show & on change get that attribute
$('#image1,#image2,#image3,#image4').on('change', function(ev) {
let toShow = $(this).data('show');
console.log(toShow);
// $('#'+toShow).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id='image1' type='checkbox' data-show='box_image_2'>
<input id='image2' type='checkbox' data-show='box_image_3'>
<input id='image3' type='checkbox' data-show='box_image_4'>
<input id='image4' type='checkbox' data-show='box_image_5'>
You can also use wildcard selector where id
begins with image
$('input[id^="image"]').on('change', function(ev) {
let toShow = $(this).data('show');
console.log(toShow);
// $('#'+toShow).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id='image1' type='checkbox' data-show='box_image_2'>
<input id='image2' type='checkbox' data-show='box_image_3'>
<input id='image3' type='checkbox' data-show='box_image_4'>
<input id='image4' type='checkbox' data-show='box_image_5'>
Upvotes: 3
Reputation: 1967
Stick it in a loop?
for(var i = 1; i <= 4; i++){
$('#image'+i).change(function (ev) {
$("#box_image_"+(i+1)).show();
});
}
Upvotes: 0