Reputation: 15374
I have two functions that I would like to execute with an .on change
event using jQuery. I thought i could bind two events to the same handler (obviously wrong as the following functions do not work in conjunction with each other)
The function file_extension_check
will run but not file_size_check
, though if i swap them around then the last declared function works.. Which makes sense, I just don't understand how I can get them both to work together.
Another issue I have is that i can forsee is having them run together no matter the order in which they are run, so if file size validation fails, but then you upload an incorrect file extension but correct size, how could i get the correct error message to show.
$(document).on('change', '.document_file_field', function() {
var input = $(this);
file_size_check(input);
});
// Functions to run to check file extension
$(document).on('change', '.document_file_field', function() {
var input_field = $(this);
file_extension_check(input_field);
});
var file_extension_check = function(input_field) {
console.log("file extension function fired");
var file_name = input_field.val();
var extension = file_name.replace(/^.*\./, '');
extension.toLowerCase();
var validExtensions = ['jpg', 'jpeg', 'gif', 'png', 'docx', 'mp4', 'pdf'];
if ($.inArray(extension, validExtensions) == -1) {
input_field.prev('.custom-file-upload.btn').removeClass('btn-info').addClass('btn-danger');
input_field.parent('.upload_document').find('.js-error').text(extension + ' file formats are not allowed');
input_field.parent('.upload_document').find('.btn-success').attr('disabled', 'disabled');
} else {
input_field.prev('.custom-file-upload.btn').removeClass('btn-danger').addClass('btn-info');
input_field.parent('.upload_document').find('.js-error').empty();
input_field.parent('.upload_document').find('.btn-success').removeAttr('disabled');
}
}
var file_size_check = function(input) {
console.log("file size function fired");
var raw_file_size = input[0].files[0].size
var file_size_mb = (Math.round((raw_file_size / 1024 / 1024) * 100) / 100)
if (raw_file_size >= 1000000) {
input.prev('.custom-file-upload.btn').removeClass('btn-info').addClass('btn-danger');
input.parent('.upload_document').find('.js-error').text('File Size to large - Must be under 1mb');
input.parent('.upload_document').find('.btn-success').attr('disabled', 'disabled');
} else {
input.prev('.custom-file-upload.btn').removeClass('btn-danger').addClass('btn-info');
input.parent('.upload_document').find('.js-error').empty();
input.parent('.upload_document').find('.btn-success').removeAttr('disabled');
}
}
.custom-file-upload {
border: 1px solid #ccc;
cursor: pointer;
display: inline-block;
padding: 6px 12px;
}
.btn-info {
background: blue;
}
.btn-danger {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form class="upload_document">
<label class="custom-file-upload btn btn-info" for="document_media"></label>
<input type="file" id="document_media" class="document_file_field"></input>
</br>
<input class="btn-success" type="submit">Submit</input>
<div class="js-error"></div>
</form>
Upvotes: 1
Views: 200
Reputation: 136074
To combine these methods just wrap it all up in a single method, checking all possible failures. This should work:
$(document).on('change', '.document_file_field', function() {
var input = $(this);
file_size_extension_check(input);
});
var file_size_extension_check = function(input) {
console.log("function fired");
var file_name = input.val();
var extension = file_name.replace(/^.*\./, '').toLowerCase();
var validExtensions = ['jpg', 'jpeg', 'gif', 'png', 'docx', 'mp4', 'pdf'];
// check if the extension is valid
var extensionValid = $.inArray(extension, validExtensions) >= 0;
// check if the size is valid
var raw_file_size = input[0].files[0].size;
var sizeValid = raw_file_size < 1000000;
// create messages
var messages = [];
if(!sizeValid) messages.push("File Size to large - Must be under 1mb.");
if(!extensionValid) messages.push(extension + ' file formats are not allowed.');
// if either are invalid show the errors, otherwise dont
if (!sizeValid || !extensionValid) {
input.prev('.custom-file-upload.btn').removeClass('btn-info').addClass('btn-danger');
input.parent('.upload_document').find('.js-error').text(messages.join(' '));
input.parent('.upload_document').find('.btn-success').attr('disabled', 'disabled');
} else {
input.prev('.custom-file-upload.btn').removeClass('btn-danger').addClass('btn-info');
input.parent('.upload_document').find('.js-error').empty();
input.parent('.upload_document').find('.btn-success').removeAttr('disabled');
}
}
.custom-file-upload {
border: 1px solid #ccc;
cursor: pointer;
display: inline-block;
padding: 6px 12px;
}
.btn-info {
background: blue;
}
.btn-danger {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form class="upload_document">
<label class="custom-file-upload btn btn-info" for="document_media"></label>
<input type="file" id="document_media" class="document_file_field"></input>
</br>
<input class="btn-success" type="submit">Submit</input>
<div class="js-error"></div>
</form>
Upvotes: 2
Reputation: 413682
You've only got one error message field. If your input is invalid in both ways, then you'll only see one of the errors.
Combine them as in the above answer, but also clear out the error before starting:
$(document).on('change', '.document_file_field', function(event) {
var input = $(this);
input.parent('.upload_document').find('.js-error').empty();
file_size_check(input);
file_extension_check(input);
});
Then inside the validator functions:
if ($.inArray(extension, validExtensions) == -1) {
input_field.prev('.custom-file-upload.btn').removeClass('btn-info').addClass('btn-danger');
var errorMsg = input_field.parent('.upload_document').find('.js-error');
errorMsg.append($("<div/>", {
text: extension + ' file formats are not allowed');
}));
input_field.parent('.upload_document').find('.btn-success').attr('disabled', 'disabled');
}
(and similarly for the other one.) Changes along those lines will mean that each check adds its message to the error box, in my example inside <div>
elements. (You might want to make the error box a <ul>
and add <li>
elements; it's up to your design.)
Upvotes: 1
Reputation: 131
It looks like your upload button should only be enabled if both validations are true, so you could return "true" for each and enable the button if both are true, like so:
$(document).on('change', '.document_file_field', function(event){
var input = $(this);
var size = file_size_check(input); // returns true if valid
var extension = file_extension_check(input); // returns true if valid
if(size && extension){ $('.btn-success').removeAttr('disabled'); }
});
Upvotes: 0
Reputation: 6793
Each function is overridding the results of the other so no matter what happens the last to run will win and you'll never see the result of the first. By changing each function to return a boolean you can make sure you only call the second if the first has passed.
$(document).on('change', '.document_file_field', function() {
var input = $(this);
if(file_size_check(input)) {
file_extension_check(input_field);
}
});
var file_extension_check = function(input_field) {
var file_name = input_field.val();
var extension = file_name.replace(/^.*\./, '');
extension.toLowerCase();
var validExtensions = ['jpg', 'jpeg', 'gif', 'png', 'docx', 'mp4', 'pdf'];
if ($.inArray(extension, validExtensions) == -1) {
input_field.prev('.custom-file-upload.btn').removeClass('btn-info').addClass('btn-danger');
input_field.parent('.upload_document').find('.js-error').text(extension + ' file formats are not allowed');
input_field.parent('.upload_document').find('.btn-success').attr('disabled', 'disabled');
return false;
} else {
input_field.prev('.custom-file-upload.btn').removeClass('btn-danger').addClass('btn-info');
input_field.parent('.upload_document').find('.js-error').empty();
input_field.parent('.upload_document').find('.btn-success').removeAttr('disabled');
return true;
}
}
var file_size_check = function(input) {
var raw_file_size = input[0].files[0].size
var file_size_mb = (Math.round((raw_file_size / 1024 / 1024) * 100) / 100)
if (raw_file_size >= 1000000) {
input.prev('.custom-file-upload.btn').removeClass('btn-info').addClass('btn-danger');
input.parent('.upload_document').find('.js-error').text('File Size to large - Must be under 1mb');
input.parent('.upload_document').find('.btn-success').attr('disabled', 'disabled');
return false;
} else {
input.prev('.custom-file-upload.btn').removeClass('btn-danger').addClass('btn-info');
input.parent('.upload_document').find('.js-error').empty();
input.parent('.upload_document').find('.btn-success').removeAttr('disabled');
return true;
}
}
Upvotes: 1