Saturday, May 3, 2014

AngularJs form validation with Twitter Bootstrap

Hi there, it has been a long time that I dont write a post on this blog but I have been really busy in the last months. In those months I have been having a look at new technologies, and between these I was studying really hard AngularJs. It is a powerful MVC framework for spa (Single Page Application) you can find more documntation on the official website if you are new and interested in learning (http://angularjs.org). I was writing with AngularJs a form validator that allows you to simply validate form. I just needed few lines of code to create a powerful validator that validates single field and the entire form. Dependencies are:
  • Twitter Bootstrap css
  • angular-growl
  • angular-strap
'use strict';
angular.module('vcrudSign', ['vcrudSignService', 'vcrudSignDirective', 'angular-growl'])
.controller('registerFormCtrl', ['$scope', 'growl', function($scope, growl) {
$scope.submit = function() {
if (!$scope.registerForm.$valid){
growl.addErrorMessage('Error in form',{ttl: 5000});
}
$scope.$broadcast('validateFormEvent');
};
}]);
view raw vcrudSign.js hosted with ❤ by GitHub
<form role="form" name='registerForm' class="register-form" ng-controller="registerFormCtrl">
<div growl></div>
<div class="form-group col-md-6">
<input
type="text"
id="firstname"
name="firstname"
class="form-control"
placeholder="{{ 'sign.placeHolderFirstname' | translate }}"
ng-model="register.firstname"
label="{{ 'sign.inputFirstname' | translate }} "
feedback-type=""
ng-required=true
form-validation="{{registerForm.firstname.$valid}}"
tooltip-message=""
validated-input>
</div>
<div class="form-group col-md-6">
<input
type="text"
id="lastname"
name="lastname"
class="form-control"
placeholder="{{ 'sign.placeHolderLastname' | translate }}"
ng-model="register.lastname"
label="{{ 'sign.inputLastname' | translate }} "
feedback-type=""
ng-required=true
form-validation="{{registerForm.lastname.$valid}}"
tooltip-message="{{ 'sign.inputLastnameTooltip' | translate }}"
validated-input>
</div>
<div class="form-group col-md-12">
<input
type="email"
id="email"
name="email"
class="form-control"
placeholder="{{ 'sign.placeHolderEmail' | translate }}"
ng-model="register.lastname"
label="{{ 'sign.inputEmail' | translate }}"
feedback-type=""
ng-required=true
form-validation="{{registerForm.email.$valid}}"
tooltip-message="{{ 'sign.inputEmailTooltip' | translate }}"
validated-input>
</div>
<div class="form-group col-md-12">
<input
type="password"
id="password"
name="password"
class="form-control"
placeholder="{{ 'sign.placeHolderPassword' | translate }}"
ng-model="register.password"
ng-required=true
ng-minlength="8"
label="{{ 'sign.inputPassword' | translate }}"
feedback-type=""
form-validation="{{registerForm.password.$valid}}"
tooltip-message="here goes the message"
validated-input>
</div>
<div class="form-group col-md-12">
<input
type="password"
id="password2"
name="password2"
class="form-control"
placeholder="{{ 'sign.placeHolderPassword' | translate }}"
ng-model="register.password2"
ng-required=true
ng-minlength="8"
label="{{ 'sign.inputPassword' | translate }}"
feedback-type=""
form-validation="{{registerForm.password2.$valid}}"
tooltip-message="here goes the message"
validated-input>
</div>
<div class="register-button-group">
<div class="col-md-12">
<button type="submit" class="btn btn-block btn-default" ng-click="submit()">{{ 'sign.buttonRegister' | translate }}</button>
</div>
<div class="col-md-6 register-button-group-social">
<button class="btn btn-block btn-social btn-facebook">
<i class="fa fa-facebook"></i> {{ 'sign.buttonRegisterFB' | translate }}
</button>
</div>
<div class="col-md-6">
<button class="btn btn-block btn-social btn-google-plus">
<i class="fa fa-google-plus"></i> {{ 'sign.buttonRegisterGO' | translate }}
</button>
</div>
</div>
<div class="col-md-12">
<div class="pull-right">
<a href="#/login" class="btn btn-link">{{ 'sign.buttonAlreadyRegistered' | translate }}</a>
</div>
</div>
</form>
'use strict';
angular.module('vcrudValidatedInputDirective', [])
.directive('validatedInput', function($tooltip, $interval) {
return {
restrict: 'A',
scope:{
feedbackType: '@',
label:'@',
formValidation:'@',
tooltipMessage:'@'
},
link: function(scope, element, attrs){
var inputElement = element;
inputElement.wrap('<div class="form-group"></div>');
var formGroup = inputElement.parent();
inputElement.before('<label class="control-label"></label>');
var formLabel = inputElement.prev();
formLabel.attr('for',attrs.id);
formLabel.html(scope.label);
var myTooltip = $tooltip(inputElement, {
title: scope.tooltipMessage,
trigger: 'manual',
animation: 'am-flip-x',
delay: {
show: 500,
hide: 100
}
});
function calculateFeedback(feedbackType){
function removeAllFeedbackClasses(){
formGroup.removeClass('has-feedback');
formGroup.removeClass('has-success');
formGroup.removeClass('has-warning');
formGroup.removeClass('has-error');
formGroup.find('.form-control-feedback').remove();
}
removeAllFeedbackClasses();
if (feedbackType === 'SUCCESS'){
formGroup.addClass('has-feedback');
formGroup.addClass('has-success');
inputElement.after('<span class="glyphicon glyphicon-ok form-control-feedback"></span>');
}else if (feedbackType === 'WARNING'){
formGroup.addClass('has-feedback');
formGroup.addClass('has-warning');
inputElement.after('<span class="glyphicon glyphicon-warning-sign form-control-feedback"></span>');
}else if (feedbackType === 'ERROR'){
formGroup.addClass('has-feedback');
formGroup.addClass('has-error');
inputElement.after('<span class="glyphicon glyphicon-remove form-control-feedback"></span>');
myTooltip.$scope.$show();
$interval(function() {
myTooltip.$scope.$hide();
},10000);
}
}
calculateFeedback(scope.feedbackType);
scope.internalControl = scope.formControl || {};
scope.$on('validateFormEvent', function(event, msg) {
if(scope.formValidation==='true'){
calculateFeedback('SUCCESS');
} else{
calculateFeedback('ERROR');
}
});
}
};
});