Supporting Spectre framework
← ejemplos
Spectre is a lightweight, responsive and modern CSS framework for faster and extensible development. You can see more information and its usage on the official website.
This example is a step by step instruction showing how to validate the forms which uses the Spectre framework.
Downloading the files
- Create a file named
spectre.js
with the following content:
/**
* This class supports validating Spectre framework (https://picturepan2.github.io/spectre/)
*/
(function($) {
FormValidation.Framework.Spectre = function(element, options) {
options = $.extend(true, {
button: {
selector: '[type="submit"]:not([formnovalidate])',
// The class of disabled button
disabled: 'fv-button-disabled'
},
err: {
clazz: 'fv-help-block',
parent: '^(.*)col-(xs|sm|md)-[0-9]+(.*)$'
},
// Spectre doesn't support feedback icon
icon: {
valid: null,
invalid: null,
validating: null,
feedback: 'fv-control-feedback'
},
row: {
selector: '.form-group',
valid: 'has-success',
invalid: 'has-danger',
feedback: 'fv-has-feedback'
}
}, options);
FormValidation.Base.apply(this, [element, options]);
};
FormValidation.Framework.Spectre.prototype = $.extend({}, FormValidation.Base.prototype, {
/**
* Specific framework might need to adjust the icon position
*
* @param {jQuery} $field The field element
* @param {jQuery} $icon The icon element
*/
_fixIcon: function($field, $icon) {
var ns = this._namespace,
type = $field.attr('type'),
field = $field.attr('data-' + ns + '-field'),
$row = $field.closest(this.options.fields[field].row || this.options.row.selector),
$parent = $field.parent();
// Place it after the container of checkbox/radio
// so when clicking the icon, it doesn't effect to the checkbox/radio element
if ('checkbox' === type || 'radio' === type) {
if ($parent.is('label')) {
$parent.addClass('fv-' + type);
$icon.insertAfter($parent);
}
}
}
});
}(jQuery));
- Create a file named
spectre.css
with the following content:
.fv-form-spectre .fv-control-feedback {
width: 32px; /* Height of Spectre input */
height: 32px;
line-height: 32px;
}
.fv-form-spectre .fv-help-block {
margin-top: 5px;
}
.fv-form-spectre .fv-control-feedback {
top: 21px; /* Same as height of label */
}
/* Horizontal form */
.fv-form-spectre.form-horizontal .fv-control-feedback {
top: 0;
}
.fv-form-spectre:not(.form-horizontal) label.sr-only~.fv-control-feedback {
top: -4px; /* labelHeight/2 - iconHeight/2 */
}
.fv-form-spectre .has-danger label,
.fv-form-spectre .has-danger .fv-help-block,
.fv-form-spectre .has-danger .fv-control-feedback {
color: #e85600; /* Same as .has-danger */
}
.fv-form-spectre .has-success label,
.fv-form-spectre .has-success .fv-help-block,
.fv-form-spectre .has-success .fv-control-feedback {
color: #32b643; /* Same as .has-success */
}
You should place spectre.js
and spectre.css
in
formvalidation/dist/js/framework
and formvalidation/dist/css
directories respectively.
Including the library
<!-- Skeleton framework -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/spectre.css/0.1.25/spectre.min.css" rel="stylesheet">
<!-- Optional: Include the Font Awesome for using some icons -->
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" />
<!-- FormValidation CSS file -->
<link rel="stylesheet" href="/vendor/formvalidation/dist/css/formValidation.min.css">
<link rel="stylesheet" href="/vendor/formvalidation/dist/css/spectre.css">
<!-- jQuery v1.9.1 or higher -->
<script type="text/javascript" src="/vendor/jquery/jquery.min.js"></script>
<!-- FormValidation plugin and the class supports validating Skeleton form -->
<script src="/vendor/formvalidation/dist/js/formValidation.min.js"></script>
<script src="/vendor/formvalidation/dist/js/framework/spectre.js"></script>
Calling the plugin
When calling .formValidation()
, you need to set the framework option:
$(form).formValidation({
framework: 'spectre',
...
});
Some of forms use the row option to support multiple fields in the
same row container
Stacked form
<form id="signupForm" method="post">
<div class="form-group">
<label class="form-label">Full name</label>
<input name="fullName" type="text" class="form-input" />
</div>
<div class="form-group">
<label class="form-label">Username</label>
<input name="username" type="text" class="form-input" />
</div>
<div class="form-group">
<label class="form-label">Email address</label>
<input name="email" type="text" class="form-input" />
</div>
<div class="form-group">
<label class="form-label">Password</label>
<input name="password" type="password" class="form-input" />
</div>
<div class="form-group">
<label class="form-label">Gender</label>
<label class="form-radio">
<input name="gender" type="radio" value="male" />
<i class="form-icon"></i> Male
</label>
<label class="form-radio">
<input name="gender" type="radio" value="female" />
<i class="form-icon"></i> Female
</label>
<label class="form-radio">
<input name="gender" type="radio" value="other" />
<i class="form-icon"></i> Other
</label>
</div>
<div class="form-group">
<label class="form-label"><span id="captchaOperation"></span></label>
<input name="captcha" type="password" class="form-input" />
</div>
<div class="form-group">
<label class="sr-only"></label>
<label class="form-checkbox">
<input name="agree" type="checkbox" />
<i class="form-icon"></i> Agree with the terms and conditions
</label>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Sign up</button>
</div>
</form>
<script>
$(document).ready(function() {
// Generate a simple captcha
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
};
$('#captchaOperation').html([randomNumber(1, 100), '+', randomNumber(1, 200), '='].join(' '));
$('#signupForm').formValidation({
framework: 'spectre',
icon: {
valid: 'fa fa-check',
invalid: 'fa fa-times',
validating: 'fa fa-refresh',
feedback: 'fv-control-feedback'
},
fields: {
fullName: {
validators: {
notEmpty: {
message: 'The full name is required'
}
}
},
username: {
validators: {
notEmpty: {
message: 'The username is required'
},
stringLength: {
min: 6,
max: 30,
message: 'The username must be more than 6 and less than 30 characters long'
},
regexp: {
regexp: /^[a-zA-Z0-9_\.]+$/,
message: 'The username can only consist of alphabetical, number, dot and underscore'
}
}
},
email: {
validators: {
notEmpty: {
message: 'The email address is required'
},
emailAddress: {
message: 'The input is not a valid email address'
}
}
},
password: {
validators: {
notEmpty: {
message: 'The password is required'
},
different: {
field: 'username',
message: 'The password cannot be the same as username'
}
}
},
gender: {
validators: {
notEmpty: {
message: 'The gender is required'
}
}
},
captcha: {
validators: {
callback: {
message: 'Wrong answer',
callback: function(value, validator) {
var items = $('#captchaOperation').html().split(' '), sum = parseInt(items[0]) + parseInt(items[2]);
return value == sum;
}
}
}
},
agree: {
validators: {
notEmpty: {
message: 'You must agree with the terms and conditions'
}
}
}
}
});
});
</script>
Horizontal form
<form id="signupForm" class="form-horizontal" method="post">
<div class="form-group">
<label class="form-label col-sm-3">Full name</label>
<div class="col-sm-6">
<input name="fullName" type="text" class="form-input" placeholder="Full name" />
</div>
</div>
<div class="form-group">
<label class="form-label col-sm-3">Username</label>
<div class="col-sm-6">
<input name="username" type="text" class="form-input" />
</div>
</div>
<div class="form-group">
<label class="form-label col-sm-3">Email address</label>
<div class="col-sm-6">
<input name="email" type="text" class="form-input" />
</div>
</div>
<div class="form-group">
<label class="form-label col-sm-3">Password</label>
<div class="col-sm-6">
<input name="password" type="password" class="form-input" />
</div>
</div>
<div class="form-group">
<label class="form-label col-sm-3">Gender</label>
<div class="col-sm-6">
<label class="form-radio">
<input name="gender" type="radio" value="male" />
<i class="form-icon"></i> Male
</label>
<label class="form-radio">
<input name="gender" type="radio" value="female" />
<i class="form-icon"></i> Female
</label>
<label class="form-radio">
<input name="gender" type="radio" value="other" />
<i class="form-icon"></i> Other
</label>
</div>
</div>
<div class="form-group">
<label class="form-label col-sm-3">
<span id="captchaOperation"></span>
</label>
<div class="col-sm-3">
<input type="text" name="captcha" class="form-input" />
</div>
</div>
<div class="form-group">
<label class="form-label col-sm-3"></label>
<div class="col-sm-9">
<label class="form-checkbox">
<input name="agree" type="checkbox" />
<i class="form-icon"></i> Agree with the terms and conditions
</label>
</div>
</div>
<div class="form-group">
<label class="form-label col-sm-3"></label>
<div class="col-sm-9">
<button type="submit" class="btn btn-primary">Sign up</button>
</div>
</div>
</form>
<script>
$(document).ready(function() {
// Generate a simple captcha
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
};
$('#captchaOperation').html([randomNumber(1, 100), '+', randomNumber(1, 200), '='].join(' '));
$('#signupForm').formValidation({
framework: 'spectre',
icon: {
valid: 'fa fa-check',
invalid: 'fa fa-times',
validating: 'fa fa-refresh',
feedback: 'fv-control-feedback'
},
fields: {
fullName: {
validators: {
notEmpty: {
message: 'The full name is required'
}
}
},
username: {
validators: {
notEmpty: {
message: 'The username is required'
},
stringLength: {
min: 6,
max: 30,
message: 'The username must be more than 6 and less than 30 characters long'
},
regexp: {
regexp: /^[a-zA-Z0-9_\.]+$/,
message: 'The username can only consist of alphabetical, number, dot and underscore'
}
}
},
email: {
validators: {
notEmpty: {
message: 'The email address is required'
},
emailAddress: {
message: 'The input is not a valid email address'
}
}
},
password: {
validators: {
notEmpty: {
message: 'The password is required'
},
different: {
field: 'username',
message: 'The password cannot be the same as username'
}
}
},
gender: {
validators: {
notEmpty: {
message: 'The gender is required'
}
}
},
captcha: {
validators: {
callback: {
message: 'Wrong answer',
callback: function(value, validator) {
var items = $('#captchaOperation').html().split(' '), sum = parseInt(items[0]) + parseInt(items[2]);
return value == sum;
}
}
}
},
agree: {
validators: {
notEmpty: {
message: 'You must agree with the terms and conditions'
}
}
}
}
});
});
</script>