$(document).ready(function(){
// let's encapsulate the code to prevent its exposeness in the window scope that is accessible from console developer tools
// soe let's make a autoexec function, and let's declare all our login inside
// the ($) code will get the object injected at the bottom of the function
(function($){
// our counter images uploaded
var imagesUploaded = [];
// our limit to be reached
var limitToBeReachedToEnableTheForm = 0;
// reference to our btnSubmit
var btnSubmit = $("#myBtnSender");
// reference to our form
var form = $("#MyForm");
// let's save reference for each input file
var picker = $(".file-picker");
var blockWrapper = $(".wrap-block");
var addBlockBtn = $("#add-picker-block");
var blockId = "block-id-";
// let's listen for picker (change) event for each input file
function onHandleFile(event) {
// get the file
var file = event.target.files;
// get the only file inside of the collection files
file = file[0];
var fileId = $(this).attr("id");
// let's make sure file is actually an image, so we need to define what format of images we will allow
var allowImagesTypes = ["image/jpg","image/gif", "image/png", "image/jpeg"];
var imageType = file.type;
// if the current image type is not supported, just abort the process and notify to user
if (allowImagesTypes.indexOf(imageType) === -1) {
var messageAllowedTypes = allowImagesTypes.join(", ");
alert("Error, we only support these types of images : " + messageAllowedTypes);
return false;
}
// if the current type image is allowed so let's get the title, caption and let's upload the image
var currentPicker = $(this);
var parentPickerBlock = currentPicker.parent(".block-image-picker");
var title = parentPickerBlock.find('.image-title');
title = title.length > 0 ? $.trim(title.val()) : "";
var caption = parentPickerBlock.find('.image-caption');
caption = caption.length > 0 ? $.trim(caption.val()) : "";
uploadImage(title, caption, file, parentPickerBlock, fileId);
};
form.submit(function(){
// if imagesUploaded is less than limitToBeReachedToEnableTheForm, so there are images to be upload and not allow the submittion of the form
if (imagesUploaded.length < limitToBeReachedToEnableTheForm) {
return false;
}
alert("Your form will send :D");
return true;
});
addBlockBtn.on("click", addNewBlock);
function checkTotalImagesUploaded(fileId) {
if (fileId) {
imagesUploaded.push(fileId);
}
// if the 5 images were uploaded so enabled the submit button
checkUploadsToEnableSubmitButton();
}
function checkUploadsToEnableSubmitButton() {
if (imagesUploaded.length === limitToBeReachedToEnableTheForm) {
btnSubmit.removeAttr("disabled");
} else {
btnSubmit.attr("disabled", "disabled");
}
}
function removeImageUploadedCounterIfExists(fileId) {
var index = imagesUploaded.indexOf(fileId)
if (index > -1) {
imagesUploaded.splice(index, 1);
}
}
function addNewBlock() {
// Create the block inputs elements
var blockImagePicker = $("<div class='block-image-picker'>");
var inputTitle = $("<input type='text' name='imageTitle[]' class='image-title' placeholder='Your image title' />");
var inputFile = $("<input type='file' name='images[]' class='file-picker' />");
// generate timestamp of creation
var fileId = new Date() * 1;
inputFile.attr("id", fileId);
// put into the blockImagePicker
blockImagePicker.append(inputTitle);
blockImagePicker.append(inputFile);
// add to block wrapper
blockWrapper.append(blockImagePicker);
// increment our limit counter
limitToBeReachedToEnableTheForm++;
// add data-id attribute
blockImagePicker.attr("id", blockId + limitToBeReachedToEnableTheForm);
if (limitToBeReachedToEnableTheForm > 1) {
var removeBtn = $("<button>Remove</button>");
blockImagePicker.append(removeBtn);
removeBtn.data("container-id", blockId + limitToBeReachedToEnableTheForm);
removeBtn.on("click", onRemoveBlockPicker);
}
// add event listener to file picker
inputFile.on("change", onHandleFile);
checkUploadsToEnableSubmitButton();
}
function onRemoveBlockPicker(event) {
event.preventDefault();
// get input file to remove eventListener
var filePickerReference = $(this).prev();
var fileId = filePickerReference.attr("id");
// remove event listener
filePickerReference.off("change");
// get block id for current block
var containerId = $(this).data("container-id");
var containerBlock = $("#"+containerId);
containerBlock.remove();
limitToBeReachedToEnableTheForm--;
removeImageUploadedCounterIfExists(fileId);
checkUploadsToEnableSubmitButton();
}
function uploadImage(title, caption, file, parent, fileId) {
var formData = new FormData();
formData.append("title", title);
formData.append("caption", caption);
formData.append("image", file);
var loader = $("<div>");
$.ajax({
url: 'http://my-url-endpoint-rest',
data: formData,
type: 'POST',
contentType: false,
processData: false,
beforeSend: function() {
//beforeSend the image to upload, let's show the user what is happening
loader.text("Uploading " + file.name + " ...");
parent.append(loader);
},
success: function(response) {
// if the image was uploaded so increment our counter imagesUploaded
checkTotalImagesUploaded(fileId);
},
error: function(jqXHR, textStatus, errorMessage) {
// show some error if something was wrong
console.log("error", errorMessage); // Optional
alert("Error uploading the image " + file.name);
},
complete: function() {
// remove the loader, not matter if the response was wrong or good
loader.remove();
}
});
}
// create our first block when page is loaded
addNewBlock();
})($);
// the ($) code above will inject the jQuery object into the closure
});
.block-image-picker {
border: 1px solid blue;
margin-bottom: 5px;
padding: 5px;
}
.block-image-picker input {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form id="MyForm">
<div class="file-pickers-wrapper">
<div class="wrap-block">
</div>
<div class="controls">
<button id="add-picker-block">
add new field
</button>
</div>
</div>
<button type="submit" id="myBtnSender" disabled="disabled">
Send data
</button>
</form>