Reputation: 10478
I've got an image upload that is created on a dynamic form. I am trying to make it so that I can validate that the file uploaded is an actual image, and do this unobtrusively. I've read about the .rules() settings and using the accept property, but that requires you to input a field name (http://docs.jquery.com/Plugins/Validation/Methods/accept). Since the forms are dynamic I won't know the field name. My view that generates the upload input looks like this:
<input type="file" size="20" name="@(Model.FormItem.Id + "-image")" id="@(Model.FormItem.Id + "-image")" />
So all my file inputs have an "-image" suffix. Is there a way to add a rule using a jquery selector for the validator rules instead of using a specific field name??
EDIT Alright it's clear that I am not explaining what the problem is well. Perhaps the solution is so simple and somehow I just missed it. I know how to use jQuery selectors, but from the examples I have seen of the rules
syntax you have to supply a static field name for the rules. How can I assign validate rules to a selector instead of a static field name??
So right now this is what I have :
var validatorData = $('#items-form').data('validator');
$.extend(validatorData.settings, {
rules: {
static_field_name: { accept: "jpg|png" }
},
messages: {
static_field_name_message: "The file must be an image."
}
});
Which won't work, nor does (obviously) if I replace static_field_name
with the proper selector $('input[name$="-image"]')
. So how do I do this?
Upvotes: 0
Views: 3667
Reputation: 3841
Of course your answer works, I'm adding this as a slightly different way to skin the same cat.
In the c# code section of the cshtml page:
//only allow these file types for upload
var allowedUploadExtensions = ".CSV|.DOC|.DOCX|.JPG|.JPEG|.PDF|.XLS|.XLSX|.TIF|.TIFF";
var acceptMessage = allowedUploadExtensions.Replace("|", ",");
In your $(document)ready function:
$.validator.addMethod('isValidFileExtension', function (value, element) {
if (value == '')
return true; //data-val-required will catch lack of value.
var extension = value.substr((value.lastIndexOf('.'))).toUpperCase();
var validFileExtensions = new String('@allowedUploadExtensions').toUpperCase().split('|');
return $.inArray(extension, validFileExtensions) > -1;
});
$('.file-upload').rules('add', { isValidFileExtension: true, messages: { isValidFileExtension: 'Invalid file extension, valid extensions are @acceptMessage'} });
and then in your markup:
<input type="file" name="UploadedFile" id="UploadedFile"
class="file-upload"
data-val="true"
data-val-required="Please select a document to upload."/>
Upvotes: 0
Reputation: 10478
I found out how to do this using .addClassRules()
like so:
$.validator.addClassRules("image-upload", {
accept: "jpg|png|gif"
});
Then just apply class image-upload
to the input. However, to also make it work unobtrusively I had to refactor the rules to get a custom message (http://docs.jquery.com/Plugins/Validation/Reference#Refactoring_rules):
$.validator.addMethod("acceptImageTypes", $.validator.methods.accept,
"Selected File must be an image.");
$.validator.addClassRules("image-upload", {
acceptImageTypes: "jpg|png|gif"
});
Then change my markup to:
<label>Image</label>
<input type="file" size="20" data-val="true" class="image-upload" name="@(Model.FormItem.Id + "-image")" id="@(Model.FormItem.Id + "-image")" />
<span class="field-validation-valid" data-valmsg-for="@(Model.FormItem.Id + "-image")" data-valmsg-replace="true">File must be an image.</span>
Upvotes: 1
Reputation: 380
I see 2 possible ways to solve this:
1) Using jQuery's .children() or $("#parent input:first") or $("input[type=file]:last") selectors so that your input doesn't require a static name.
2) Use a regex expression for your jQuery selector if you have any sort of pattern in the dynamic names given:
a) jquery way: http://api.jquery.com/attribute-ends-with-selector/
b) Or full regex way: http://james.padolsey.com/javascript/regex-selector-for-jquery/
That should be the hard part. Then you can add your rules like you would normally.
Upvotes: 0