angularjs入門-ng-submit and ngMessage(1.3之後的驗證)
前言
這一篇我還是會需要先建立一些db資料,但就是一個簡單的帳號註冊功能,在$http有帶到簡單的code first建立db的過程,這篇只會簡單的帶一下建立db的部份,不會再詳細的去帶到detail的部份,如果有疑問的話,可以去看一下angularjs入門-$http,ng-submit就是搭配了驗證功能,所以我們只要需要驗證功能,我們就需要用到這個directive,ngMessage則是1.3之後簡化了angularjs很繁雜的驗証功能的寫法,在此我還是先從db的資料建立開始做起,還是拿之前的student來做table範例,程式碼修改如下
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Migrations;
namespace WebApiDemo.Models
{
public class DefaultDataInit:DropCreateDatabaseAlways<DefaultContext>
{
public override void InitializeDatabase(DefaultContext context)
{
base.InitializeDatabase(context);
var student = new List<Student>()
{
new Student() { Name = "王小明", PhoneNumber = "0915808888", Address = "台中市",Password="1234" },
new Student() { Name = "王大明", PhoneNumber = "0915801111", Address = "台北市",Password="1234" },
new Student() { Name = "王大雄", PhoneNumber = "0915806666", Address = "台南市",Password="1234" },
new Student() { Name = "王小雄", PhoneNumber = "0915800000", Address = "新北市",Password="1234" },
new Student() { Name = "王小安", PhoneNumber = "0915807777", Address = "桃園市",Password="1234" }
};
context.Student.AddRange(student);
context.SaveChanges();
}
}
}
<connectionStrings>
<add name="DefaultConnection" connectionString="data source=(LocalDb)\MSSQL;initial catalog=NgMessage;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
其餘過程在之前已經提過,就不再多做說明
1.3之前驗證的做法
其實在1.3之前,驗證的寫法是有點麻煩的,程式碼如下圖示例
那1.3之後的寫法就變得簡潔和易讀許多,先給個1.3之後的比較圖示例,細節會留在之後再陳述
驗證的一些可用功能
我們可以看到上面的程式碼,但其實這有些問題,我們期望的是在輸入值之後,有錯誤才顯示出來,但這邊卻是會先把錯誤顯示出來了,如下圖
這時候我們必須先了解一下,有關於可使用的一些驗證功能
- 必填:<input type="text" ng-model="name" required>
- 最小長度:<input type="text" ng-model="name" ng-minlength="3">
- 最大長度:<input type="text" ng-model="name" ng-maxlength="12">
- 正規表達式:<input type="text" ng-model="name" ng-pattern="/[0-9]/">
- 數字:<input type="number" ng-model="age">
- Email:<input type="email" ng-model="email">
- Url:<input type="url" ng-model="url">
- Date:<input type="date" ng-model="date"
然後是對應的可以取得驗證狀態,也就是如果有錯誤的話,會為true
- formName.inputName.$error.required
- formName.inputName.$error.minlength
- formName.inputName.$error.maxlength
- formName.inputName.$error.pattern
- formName.inputName.$error.number
- formName.inputName.$error.email
- formName.inputName.$error.url
- formName.inputName.$error.date
再來就是驗證狀態了,比如說我們想檢查是否有通過驗證,或是否未輸入的狀態,如果符合條件的話,會為true
- 通過驗證: $valid
- 未通過驗證: $invalid
- 該欄位未曾輸入值: $pristine
- 該欄位已曾輸入值: $dirty
ngMessage部份
如何開始使用ngMessage呢?我們必須要先在頁面加入 <script src="~/Scripts/angular-messages.js"></script>,還有必須在後端加入ngMessages,因為我是用.net mvc,所以我把會共用的放在_Layout.cshtml,以下是所有的程式碼
_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>ngMessage範例</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body ng-app="MyApp">
<div class="container body-content">
@RenderBody()
</div>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-messages.js"></script>
@RenderSection("scripts", required: false)
</body>
</html>
Index.js
angular.module('MyApp', ['ngMessages']) //這邊需要加入ngMessages
.controller('FirstCtrl', function ($scope, $http) {
var url = 'http://localhost:58973/Api/Values';
$http.get(url).success(function (data) {
$scope.students = data;
});
});
Index.cshtml
<div ng-controller="FirstCtrl">
<div class="row">
@*必須得加入name的名稱,還有ng-submit跟novalidate*@
<form name="myForm" ng-submit="submit()" novalidate>
@*必須得加入name的名稱,驗証是以此名稱做依據*@
Name:<input type="text" name="name" ng-model="Add.Name" class="form-control" required ng-minlength="3" />
@*最外層加上ng-show是為了不想在未輸入值之前,就預先顯示錯誤訊息*@
<div ng-messages="myForm.name.$error" ng-show="myForm.name.$dirty">
<p ng-message="required">Name必填</p>
<p ng-message="minlength">最少三碼</p>
</div>
Password:<input type="password" name="password" ng-model="Add.Password" class="form-control" required
ng-minlength="4" ng-maxlength="10" />
<div ng-messages="myForm.password.$error" ng-show="myForm.password.$dirty">
<p ng-message="required">Password必填</p>
<p ng-message="minlength">至少輸入四碼</p>
<p ng-message="maxlength">至多輸入十碼</p>
</div>
PhoneNumber:<input type="number" name="phoneNumber" ng-model="Add.PhoneNumber" class="form-control" required
ng-minlength="7" ng-maxlength="10" />
<div ng-messages="myForm.phoneNumber.$error" ng-show="myForm.phoneNumber.$dirty">
<p ng-message="required">PhoneNumber必填</p>
<p ng-message="minlength">至少輸入七碼</p>
<p ng-message="maxlength">至多輸入十碼</p>
<p ng-message="number">只能輸入數字</p>
</div>
Address:<input type="text" name="Address" ng-model="Add.Address" class="form-control" required />
<div ng-messages="myForm.Address.$error" ng-show="myForm.Address.$dirty">
<p ng-message="required">Address必填</p>
</div>
@*ng-disabled則是如果任格一個欄位未成功,預設是不能按下送出按鈕*@
<input type="submit" value="新增" class="btn btn-primary" ng-disabled="myForm.$invalid" />
</form>
</div>
<hr />
<div class="row">
<table class="table">
<tr>
<th>姓名</th>
<th>電話</th>
<th>地址</th>
<th>密碼</th>
</tr>
<tr ng-repeat="item in students">
<td>{{item.Name}}</td>
<td>{{item.PhoneNumber}}</td>
<td>{{item.Address}}</td>
<td>{{item.Password}}</td>
</tr>
</table>
</div>
</div>
@section scripts{
<script src="~/App/Index.js"></script>
}
上面我都有在每行的上面,加上一些注解說明,所以在此就不多做說明
驗證angularjs提供css
接下來討論一下有關美化驗證的部份,其實angularjs也有提供有關驗證相關的一系列樣式,如下
ng-pristine
ng-dirty
ng-valid
ng-invalid
所以我們可以加入css,讓驗證畫面看起來更直覺
input.ng-invalid{
border-color:red;
border-width:2px;
}
input.ng-pristine{
border-color:blue;
border-width:2px;
}
.error{
color:red;
}
然後我們錯誤的div部份,需自行加入class,如下例
<div ng-messages="myForm.name.$error" class="error" ng-show="myForm.name.$dirty">
<p ng-message="required">Name必填</p>
<p ng-message="minlength">最少三碼</p>
<p ng-message="maxlength">至多輸入十碼</p>
</div>
1.3之後還有加入了,如果按下submit之後,有錯誤的話,會顯示我們自行定義的css語法,如下
form.ng-submitted .ng-invalid {
border-color: red;
border-width: 2px;
}
我們也可以在controller裡面寫驗證判斷語法,比如說我們只要確定驗證成功,我們就alert一個成功的訊息
angular.module('MyApp', ['ngMessages']) //這邊需要加入ngMessages
.controller('FirstCtrl', function ($scope, $http) {
var url = 'http://localhost:58973/Api/Values';
$http.get(url).success(function (data) {
$scope.students = data;
});
$scope.submit = function () {
if ($scope.myForm.$valid) alert('成功');
if ($scope.myForm.$invalid) alert('驗證失敗');
}
});
如果我們有很多欄位想要顯示的錯誤訊息如果一樣,我們其實還能再抽出來重覆使用,如下面程式碼是包
<script type="text/ng-template" id="commonMessage">
<p ng-message="required">此欄位必填</p>
<p ng-message="minlength">輸入太少</p>
<p ng-message="maxlength">輸入太多</p>
<p ng-message="number">只能輸入數字</p>
</script>
然後我們就可以在html裡面直接用下面的語法,就可以套用這段抽出來的驗證語法
<div class="error" ng-messages="myForm.Address.$error" ng-show="myForm.Address.$dirty" ng-messages-include="commonMessage">
</div>
其實我們也可以覆寫驗證裡面定義的字,比如像下面的html這樣
Address:<input type="text" name="Address" ng-model="Add.Address" class="form-control" required />
<div class="error" ng-messages="myForm.Address.$error" ng-show="myForm.Address.$dirty" ng-messages-include="commonMessage">
<p ng-message="required">Address必填</p> @*此行重寫了原本定義的錯誤訊息*@
</div>
下面則是完整的程式碼
<style>
form.ng-submitted .ng-invalid {
border-color: red;
border-width: 2px;
}
input.ng-pristine{
border-color:blue;
border-width:2px;
}
.error{
color:red;
}
</style>
<div ng-controller="FirstCtrl">
<div class="row">
@*必須得加入name的名稱,還有ng-submit跟novalidate*@
<form name="myForm" ng-submit="submit()" novalidate>
@*必須得加入name的名稱,驗証是以此名稱做依據*@
Name:<input type="text" name="name" ng-model="Add.Name" class="form-control" required ng-minlength="3" />
@*最外層加上ng-show是為了不想在未輸入值之前,就預先顯示錯誤訊息*@
<div ng-messages="myForm.name.$error" class="error" ng-show="myForm.name.$dirty" ng-messages-include="commonMessage">
</div>
Password:<input type="password" name="password" ng-model="Add.Password" class="form-control" required
ng-minlength="4" ng-maxlength="10" />
<div ng-messages="myForm.password.$error" class="error" ng-show="myForm.password.$dirty" ng-messages-include="commonMessage">
</div>
PhoneNumber:<input type="number" name="phoneNumber" ng-model="Add.PhoneNumber" class="form-control" required
ng-minlength="7" ng-maxlength="10" />
<div class="error" ng-messages="myForm.phoneNumber.$error" ng-messages-include="commonMessage" ng-show="myForm.phoneNumber.$dirty">
</div>
Address:<input type="text" name="Address" ng-model="Add.Address" class="form-control" required />
<div class="error" ng-messages="myForm.Address.$error" ng-show="myForm.Address.$dirty" ng-messages-include="commonMessage">
<p ng-message="required">Address必填</p> @*此行重寫了原本定義的錯誤訊息*@
</div>
@*ng-disabled則是如果任格一個欄位未成功,預設是不能按下送出按鈕*@
<input type="submit" value="新增" class="btn btn-primary" ng-disabled="myForm.$invalid" />
</form>
</div>
<hr />
<div class="row">
<table class="table">
<tr>
<th>姓名</th>
<th>電話</th>
<th>地址</th>
<th>密碼</th>
</tr>
<tr ng-repeat="item in students">
<td>{{item.Name}}</td>
<td>{{item.PhoneNumber}}</td>
<td>{{item.Address}}</td>
<td>{{item.Password}}</td>
</tr>
</table>
</div>
</div>
<script type="text/ng-template" id="commonMessage">
<p ng-message="required">此欄位必填</p>
<p ng-message="minlength">輸入太少</p>
<p ng-message="maxlength">輸入太多</p>
<p ng-message="number">只能輸入數字</p>
</script>
@section scripts{
<script src="~/App/Index.js"></script>
}
接著我們也可以把統一驗證的程式碼放在另外一支html裡面共用,我這邊因為是mvc,所以我新增的是cshtml檔,可以看看最後程式碼的樣子
Index.cshtml
<style>
input.ng-invalid {
border-color: red;
border-width: 2px;
}
input.ng-pristine{
border-color:blue;
border-width:2px;
}
.error{
color:red;
}
</style>
<div ng-controller="FirstCtrl">
<div class="row">
@*必須得加入name的名稱,還有ng-submit跟novalidate*@
<form name="myForm" ng-submit="submit()" novalidate>
@*必須得加入name的名稱,驗証是以此名稱做依據*@
Name:<input type="text" name="name" ng-model="Add.Name" class="form-control"
required ng-minlength="3" />
@*最外層加上ng-show是為了不想在未輸入值之前,就預先顯示錯誤訊息*@
<div ng-messages="myForm.name.$error" class="error" ng-show="myForm.name.$dirty" ng-messages-include="/Home/template">
</div>
Password:<input type="password" name="password" ng-model="Add.Password" class="form-control" required
ng-minlength="4" ng-maxlength="10" />
<div ng-messages="myForm.password.$error" class="error" ng-show="myForm.password.$dirty" ng-messages-include="/Home/template">
</div>
PhoneNumber:<input type="number" name="phoneNumber" ng-model="Add.PhoneNumber" class="form-control" required
ng-minlength="7" ng-maxlength="10" />
<div class="error" ng-messages="myForm.phoneNumber.$error" ng-messages-include="/Home/template" ng-show="myForm.phoneNumber.$dirty">
</div>
Address:<input type="text" name="Address" ng-model="Add.Address" class="form-control" required />
<div class="error" ng-messages="myForm.Address.$error" ng-show="myForm.Address.$dirty" ng-messages-include="/Home/template">
</div>
@*ng-disabled則是如果任格一個欄位未成功,預設是不能按下送出按鈕*@
<input type="submit" value="新增" class="btn btn-primary" ng-disabled="myForm.$invalid" />
</form>
</div>
<hr />
<div class="row">
<table class="table">
<tr>
<th>姓名</th>
<th>電話</th>
<th>地址</th>
<th>密碼</th>
</tr>
<tr ng-repeat="item in students">
<td>{{item.Name}}</td>
<td>{{item.PhoneNumber}}</td>
<td>{{item.Address}}</td>
<td>{{item.Password}}</td>
</tr>
</table>
</div>
</div>
<script type="text/ng-template" id="commonMessage">
<p ng-message="required">此欄位必填</p>
<p ng-message="minlength">輸入太少</p>
<p ng-message="maxlength">輸入太多</p>
<p ng-message="number">只能輸入數字</p>
</script>
@section scripts{
<script src="~/App/Index.js"></script>
}
template.cshtml
<p ng-message="required">此欄位必填</p>
<p ng-message="minlength">輸入太少</p>
<p ng-message="maxlength">輸入太多</p>
<p ng-message="number">只能輸入數字</p>
Index.js
angular.module('MyApp', ['ngMessages']) //這邊需要加入ngMessages
.controller('FirstCtrl', function ($scope, $http) {
var url = 'http://localhost:58973/Api/Values';
$http.get(url).success(function (data) {
$scope.students = data;
});
$scope.submit = function () {
if ($scope.myForm.$valid) alert('成功');
if ($scope.myForm.$invalid) alert('驗證失敗');
}
});
這邊我一樣會附上原始碼供參考,入門部份也差不多到此告一段落,其實angularjs還有很多議題,但我認為不會屬於入門的部份,但其實掌握這些入門的部份,要做個純ajax的小網站也夠用了,在這邊我並沒有把資料真的寫進後端,有興趣的人可以自己試試看,然後把資料寫入資料庫吧,以上再多多指教。