CRUD的網站中常具有登入、註冊的場景,頁面中可能會輸入一些值來做為登入與註冊的依據,但有些欄位可能需要一些智能的限制與提示,可以在前端先完成,而不用將整筆資料傳送到後端後再將驗證結果回傳,一來節省頻寬的浪費,二來可以即時將提示的樣板顯示於頁面,如email格式的檢查、密碼強度的限制等,而Angularjs也提供一些簡單的技巧來達成此功能,只要運用form搭配$valid、$error、$dirty等屬性即可,而於此也搭配ui-router來進行頁面的切換。
一、首先設計index.html搭配bootstrap.css中的panel及ui-router的ui-view呈現register.html及register.message.html
<html ng-app="registerAppModule">
<head lang="en">
<title></title>
<link href="../../includes/bootstrap/css/bootstrap.css" rel="stylesheet">
<script src="../../includes/jquery/jquery-2.1.1.min.js"></script>
<script src="../../includes/angular/angular.min.js"></script>
<script src="../../includes/angular/angular-ui-router.js"></script>
<script src="../controller/registerApp.js"></script>
<script src="../controller/registerController.js"></script>
<script src="../../services/cacheMethod.js"></script>
</head>
<body>
<div class="panel panel-primary" align="center" style="width: 50% ;margin-left: auto;margin-right: auto;">
<div class="panel-heading">Register</div>
<div class="panel-body bg-warning" align="center" ui-view></div>
</div>
</body>
</html>
二、registerApp.js,用來設定ui-router狀態的設定與切換
(function () {
angular.module('registerAppModule', ['ui.router','registerControllerModule'])
.config(function($stateProvider,$urlRouterProvider,$locationProvider){
$urlRouterProvider.otherwise("/register");
$stateProvider.state('register',{
url: '/register',
templateUrl: 'register.html',
controller: 'registerController'
}).state('message',{
url: '/message',
templateUrl: 'register.message.html',
controller: 'messageController'
})
})
})();
三、register.html,以ng-class、ng-show來切換驗證錯誤與驗證成功的樣板,而方法都置於registerController.js
<form name="registerForm" class="form-inline" ng-submit="submit(registerForm.$valid)" novalidate>
<div class="form-group" ng-class="getFormGroupClass(registerForm.idText)">
<label class="control-label" for='passwordText'>User Name:</label>
<input type="text" class="form-control" id="idText" name="idText" placeholder="Enter your User Name..." ng-model="idText" required>
<span ng-show="registerForm.idText.$dirty" ng-class="getGlyphIconClass(registerForm.idText)"></span>
<br />
<label class="control-label" ng-show="isRequired(registerForm.idText)">*Required</label>
</div>
<p />
<div class="form-group" ng-class="getFormGroupClass(registerForm.passwordText)">
<label class="control-label" for='passwordText'>Password:</label>
<input type="password" class="form-control" id="passwordText" name="passwordText" placeholder="Enter your password..." ng-model="passwordText" ng-pattern="passwordPattern" required>
<span ng-show="registerForm.passwordText.$dirty" ng-class="getGlyphIconClass(registerForm.passwordText)"></span>
<br />
<label class="control-label" ng-show="isRequired(registerForm.passwordText)">*Required</label>
<label class="control-label" ng-show="registerForm.passwordText.$error.pattern">*Required 8-12 characters with a-z and 0-9</label>
</div>
<p />
<div ng-class="getFormGroupClass(registerForm.emailText)">
<label class="control-label" for='emailText'>Email:</label>
<input type="email" class="form-control" id="emailText" name="emailText" placeholder="Enter your email..." ng-model="emailText" required/>
<span ng-show="registerForm.emailText.$dirty" ng-class="getGlyphIconClass(registerForm.emailText)"></span>
<br />
<label class="control-label left" ng-show="isRequired(registerForm.emailText)">*Required</label>
<label class="control-label left" ng-show="registerForm.emailText.$error.email">*Invalid email</label>
</div>
<p />
<button type="submit" class="btn btn-info" ng-disabled="registerForm.$invalid">Submit</button>
</form>
四、registerController.js自訂filter為密碼增加mask,裡面具有兩個controller,分別為registerController來驗證資料的限制條件及設計submit function當驗證成功就將傳參的值存入cache並跳轉頁面,另外為messageController運用$viewContentLoaded的事件監聽來載入傳參資料並顯示。
(function(){
angular.module('registerControllerModule',['ui.router','cacheMethodModule'])
.filter('passwordFilter',function(){
return function(str,symbol){//保留密碼的頭跟尾,中間字串取代成自訂符號
if (!symbol) symbol = '*';
if (!str) return;
var fixShowLength = 2;
var maskLength,replaceSourceStr,replaceTargetStr;
if (str.length <= fixShowLength){
maskLength = str.length;
replaceSourceStr = str;
}else{
maskLength = str.length - fixShowLength;
replaceSourceStr = str.substr(1,maskLength);
}
replaceTargetStr = '';
for (var i = 0;i < maskLength;i++) replaceTargetStr += symbol;
str = str.replace(replaceSourceStr,replaceTargetStr);
return str;
}
})
.controller('registerController',function($scope,$state,cacheMethodService){
$scope.passwordPattern = /(?=^.{8,12}$)(?=.*\d)(?![.\n])(?=.*[a-z]).*$/;//配對8-12個英數混和字元
$scope.submit = function(isValid){
if (!isValid) return;
cacheMethodService.saveCache('tmpParameter',{//傳參用
'username': $scope.idText,
'password': $scope.passwordText,
'email': $scope.emailText
});
$state.go('message');
};
$scope.getFormGroupClass = function(groupControls){
if (!groupControls.$dirty) return;//若該Controls未修過值則不動作
return groupControls.$invalid?'form-group has-error has-feedback':'form-group has-success has-feedback';//回傳驗證過與未驗證過的樣板
}
$scope.getGlyphIconClass = function(groupControls){
return groupControls.$valid?'glyphicon glyphicon-ok form-control-feedback':'glyphicon glyphicon-remove form-control-feedback';//回傳驗證過與未驗證過的小圖示
}
$scope.isRequired = function(groupControls){
return groupControls.$error.required && groupControls.$dirty;//判斷是否符合必填限制
}
})
.controller('messageController',function($scope,cacheMethodService){
$scope.$on('$viewContentLoaded', function () {//當頁面載入時讀取cache中傳參的值
$scope.onLoad()
});
$scope.onLoad = function () {
var cacheDatas = cacheMethodService.getCache('tmpParameter');
$scope.userNameMessage = cacheDatas['username'];
$scope.passwordMessage = cacheDatas['password'];
$scope.emailMessage = cacheDatas['email'];
}
})
})();
五、cacheMethod.js存取快取資料
(function(){
angular.module('cacheMethodModule',[])
.service('cacheMethodService',function($cacheFactory){
var cache = $cacheFactory('myCache');
var saveCache = function(key,values){
cache.put( key, values );
}
var getCache = function(key){
var result = cache.get(key);
return !result?"":result;
}
return{
saveCache: saveCache,
getCache: getCache
}
})
})();
六、register.message.html
Your name is:{{userNameMessage}}
<br />
Your password is:{{passwordMessage|passwordFilter}}
<br />
Your email is :{{emailMessage}}
<p />
<a ui-sref="register" class="btn btn-info">go back</a>
留言
張貼留言