This validator is available from v0.6.2.
Options
* — Required option
Option | HTML attribute | Type | Description |
---|---|---|---|
message |
data-fv-promise-message |
String | The error message. The dynamic message is supported |
promise * |
data-fv-promise-promise |
String|Function | The callback returns promise instance |
The promise
option must be a function or the name of function which has the
following syntax:
function(value, validator, $field) {
// value is the value of field
// validator is the instance of plugin
// $field is the field element
var dfd = new $.Deferred();
// Do something ...
// Resolve when particular task is done
dfd.resolve({
valid: true, // or false, // Required
message: 'Other message', // Optional
key: value // You can attach more data to reuse later
});
// You can reject if there's error
dfd.reject({
message: 'Other message', // Optional
key: value // You can attach more data to reuse later
});
return dfd.promise();
}
The validator is ignored if it resolves { valid: null }
dfd.resolve({ valid: null });
If the validation process takes time, it's recommended to use the tips introduced in the Getting notified while field is being validated example to improve the user experience of the application.
Example
The following form asks user to upload an avatar which both width and height must be less than 300px.
They can be determined using Deferred as seen in the following snippet:
var dfd = new $.Deferred(),
img = new Image();
img.onload = function() {
// Get the width and height after the image is loaded completely
var w = this.width,
h = this.height;
dfd.resolve({
valid: (w <= 300 && h <= 300),
message: 'The avatar width and height must be less than 300 px',
source: img.src, // We will use it later to show the preview
width: w,
height: h
});
};
img.onerror = function() {
// Called when the image isn't loaded successfully
// For example, the user doesn't choose an image
dfd.reject({
message: 'Please choose an image'
});
};
<style type="text/css">
.preview {
display: none;
width: 200px;
height: 200px;
border: 1px solid #d5d5d5;
margin-top: 10px;
}
.preview img {
max-width: 100%;
height: auto;
}
</style>
<form id="profileForm" class="form-horizontal">
<div class="form-group">
<label class="col-xs-3 control-label">Avatar</label>
<div class="col-xs-6">
<input type="file" name="avatar" />
<div id="avatarPreview" class="preview"></div>
</div>
</div>
<div class="form-group">
<div class="col-xs-9 col-xs-offset-3">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
<script>
$(document).ready(function() {
$('#profileForm')
.formValidation({
framework: 'bootstrap',
icon: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
avatar: {
validators: {
notEmpty: {
message: 'The avatar is required and can\'t be empty'
},
promise: {
promise: function(value, validator, $field) {
var dfd = new $.Deferred(),
files = $field.get(0).files;
if (!files.length || typeof FileReader === 'undefined') {
dfd.resolve({ valid: true });
return dfd.promise();
}
var img = new Image();
img.onload = function() {
var w = this.width,
h = this.height;
dfd.resolve({
valid: (w <= 300 && h <= 300),
message: 'The avatar width and height must be less than 300 px',
source: img.src, // We will use it later to show the preview
width: w,
height: h
});
};
img.onerror = function() {
dfd.reject({
message: 'Please choose an image'
});
};
var reader = new FileReader();
reader.readAsDataURL(files[0]);
reader.onloadend = function(e) {
img.src = e.target.result;
};
return dfd.promise();
}
}
}
}
}
})
.on('err.validator.fv', function(e, data) {
if (data.field === 'avatar' && data.validator === 'promise') {
// Hide the preview
$('#avatarPreview').html('').hide();
}
})
.on('success.validator.fv', function(e, data) {
if (data.field === 'avatar' && data.validator === 'promise' && data.result.source) {
$('#avatarPreview')
.html('')
.append($('<img/>').attr('src', data.result.source))
.show();
}
});
});
</script>
<style type="text/css">
.preview {
display: none;
width: 200px;
height: 200px;
border: 1px solid #d5d5d5;
margin-top: 10px;
}
.preview img {
max-width: 100%;
height: auto;
}
</style>
<form id="profileForm" class="form-horizontal"
data-fv-framework="bootstrap"
data-fv-icon-valid="glyphicon glyphicon-ok"
data-fv-icon-invalid="glyphicon glyphicon-remove"
data-fv-icon-validating="glyphicon glyphicon-refresh">
<div class="form-group">
<label class="col-xs-3 control-label">Avatar</label>
<div class="col-xs-6">
<input type="file" name="avatar"
data-fv-promise="true"
data-fv-promise-promise="validateImageSize" />
<div id="avatarPreview" class="preview"></div>
</div>
</div>
<div class="form-group">
<div class="col-xs-9 col-xs-offset-3">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
<script>
function validateImageSize(value, validator, $field) {
var dfd = new $.Deferred(),
files = $field.get(0).files;
if (!files.length || typeof FileReader === 'undefined') {
dfd.resolve({ valid: true });
return dfd.promise();
}
var img = new Image();
img.onload = function() {
var w = this.width,
h = this.height;
dfd.resolve({
valid: (w <= 300 && h <= 300),
message: 'The avatar width and height must be less than 300 px',
source: img.src, // We will use it later to show the preview
width: w,
height: h
});
};
img.onerror = function() {
dfd.reject({
message: 'Please choose an image'
});
};
var reader = new FileReader();
reader.readAsDataURL(files[0]);
reader.onloadend = function(e) {
img.src = e.target.result;
};
return dfd.promise();
}
$(document).ready(function() {
$('#profileForm')
.formValidation()
.on('err.validator.fv', function(e, data) {
if (data.field === 'avatar' && data.validator === 'promise') {
// Hide the preview
$('#avatarPreview').html('').hide();
}
})
.on('success.validator.fv', function(e, data) {
if (data.field === 'avatar' && data.validator === 'promise' && data.result.source) {
$('#avatarPreview')
.html('')
.append($('<img/>').attr('src', data.result.source))
.show();
}
});
});
</script>
Related validators
The following validators might be useful to you: