Reputation: 15374
I have a function that will validate the file size of an attachment and add errors if the file size exceeds the limit set, but it is limited to a specific file field with an id at the moment and i would like to be able to use the function on many file fields.
If a user wants to add say two images then they can click a button to clone the file field.
// First Example with ID
$('#animal_image_file_0').bind('change', is_valid_dog_image_size);
function is_valid_dog_image_size() {
$this = $('#animal_image_file_0');
if($this[0].files[0].size < 3000000){ // valid
if ($this.closest(".form-group").hasClass("has-error"))
$this.closest(".form-group").removeClass("has-error");
$this.siblings(".help-inline, .form-inline .has-feedback .form-control-feedback, .has-feedback").css("display", "none");
return true
} else { // error
if (!$this.closest(".form-group").hasClass("has-error"))
$this.closest(".form-group").addClass("has-error");
$this.siblings(".help-inline, .form-inline .has-feedback .form-control-feedback, .has-feedback ").css("display", "block");
return false;
}
}
So I thought to apply this to many file fields I could use a class instead and then fire the function using the .on('click') method when the button to clone a field is clicked, but the assignment of $(this) in the function will not work now will it?
$('.add_nested_fields').on('click', function(){
$('.animal_file').bind('change', is_valid_dog_image_size);
});
function is_valid_dog_image_size() {
$this = $('.animal_file');
if($this[0].files[0].size < 3000000){ // valid
if ($this.closest(".form-group").hasClass("has-error"))
$this.closest(".form-group").removeClass("has-error");
$this.siblings(".help-inline, .form-inline .has-feedback .form-control-feedback, .has-feedback").css("display", "none");
return true
} else { // error
if (!$this.closest(".form-group").hasClass("has-error"))
$this.closest(".form-group").addClass("has-error");
$this.siblings(".help-inline, .form-inline .has-feedback .form-control-feedback, .has-feedback ").css("display", "block");
return false;
}
}
When i click .add_nested_fields it clones the file field so how could i go about ensuring that i could use the same function on all instances of this class in the DOM?
Thanks
Upvotes: 0
Views: 74
Reputation: 33399
Just set $this
to a jQuery wrapper of this
. jQuery sets it properly for you when running an event callback.
$('.add_nested_fields').on('click', function(){
$('.animal_file').bind('change', is_valid_dog_image_size);
});
function is_valid_dog_image_size() {
$this = $(this);
if(this.files[0].size < 3000000){ // valid
if ($this.closest(".form-group").hasClass("has-error"))
$this.closest(".form-group").removeClass("has-error");
$this.siblings(".help-inline, .form-inline .has-feedback .form-control-feedback, .has-feedback").css("display", "none");
return true
} else { // error
if (!$this.closest(".form-group").hasClass("has-error"))
$this.closest(".form-group").addClass("has-error");
$this.siblings(".help-inline, .form-inline .has-feedback .form-control-feedback, .has-feedback ").css("display", "block");
return false;
}
}
Upvotes: 1
Reputation: 13063
The main problem is that you will be attaching multiple handlers to each field:
$('.animal_file').bind
is problematic, because you want to handle only events on the new field (the other handlers stay). The best way for your situation is to use a delegate handler (JQuery version 1.4.2+ and 1.7). The idea is that you attach the event handler on the parent element and filter for the target:
$('#parent-of-animal_file').on('change', '.animal-file', is_valid_dog_image_size);
Then, in your handler, simply use the native this
and wrap it in a jQuery object:
function is_valid_dog_image_size() {
$this = $(this);
...
Upvotes: 1