Xác thực biểu mẫu AngularJS khi gửi: $dirty, $valid & $invalid

⚡ Tóm tắt thông minh

Trong AngularJS, việc kiểm tra tính hợp lệ của biểu mẫu đảm bảo dữ liệu được nhập vào là chính xác và đầy đủ trước khi gửi đến máy chủ. Bài viết này sẽ đề cập đến bốn phương pháp, từ các thuộc tính HTML5 đơn giản, thuộc tính phạm vi cho đến các mô-đun kiểm tra tính hợp lệ tự động.

  • 🧩 Thuộc tính HTML5: Thuộc tính bắt buộc và các kiểu nhập liệu email, mật khẩu và số điện thoại cung cấp các kiểm tra gốc của trình duyệt mà không cần lập trình.
  • 🔍 Thuộc tính của tiểu bang: AngularJS hiển thị các biến `$dirty`, `$pristine`, `$valid` và `$invalid` trên mọi điều khiển được đặt tên bên trong một biểu mẫu được đặt tên.
  • 🏷️ Yêu cầu đặt tên: Cả biểu mẫu và mỗi điều khiển đều cần thuộc tính tên, vì trạng thái xác thực được truy cập dưới dạng formName.controlName.
  • 🚫 Ẩn cửa sổ bật lên tự nhiên: Việc thêm novalidate vào biểu mẫu sẽ ngăn trình duyệt chặn việc gửi dữ liệu, nhờ đó AngularJS có thể xử lý việc này.
  • 💬 Hiển thị tin nhắn: Mô-đun ngMessages thay thế các chỉ thị ng-show xếp chồng lên nhau và hiển thị từng lỗi một theo thứ tự ưu tiên.
  • ⚙️ Xác thực tự động: Mô-đun jcs-autoValidate tạo ra thông báo lỗi cho mọi thành phần điều khiển mà không cần bất kỳ mã đánh dấu tùy chỉnh nào.
  • 🔘 Phản hồi về bài nộp: Nút Ladda sẽ hiển thị biểu tượng xoay tròn trong khi quá trình gửi đang diễn ra, báo hiệu tiến trình cho người dùng.

Xác thực mẫu trong AngularJS

Xác thực biểu mẫu Trong AngularJS, xác thực là quá trình đảm bảo dữ liệu được nhập vào biểu mẫu là chính xác và đầy đủ. Khi người dùng gửi biểu mẫu, quá trình xác thực diễn ra trước khi thông tin được gửi đến máy chủ. Quá trình xác thực đảm bảo, ở mức độ tốt nhất có thể, rằng các trường nhập liệu đã được điền đúng cách.

Ví dụ thực tế, giả sử một trang web yêu cầu người dùng điền vào mẫu đăng ký trước khi được cấp quyền truy cập đầy đủ. Trang đăng ký sẽ có các trường nhập liệu cho tên người dùng, mật khẩu, địa chỉ email, v.v.

Ví dụ, địa chỉ email luôn cần phải có định dạng như sau: tên người dùng@site.domainNếu người dùng chỉ nhập tên người dùng, quá trình xác thực sẽ thất bại. Quá trình xác thực thực hiện các kiểm tra cơ bản này trước khi thông tin được gửi đến máy chủ để xử lý tiếp.

⚠️ Lưu ý về phiên bản: AngularJS (phiên bản 1.x) đã hết hạn hỗ trợ vào ngày 31 tháng 12 năm 2021 và sẽ không nhận được bất kỳ bản vá bảo mật nào nữa. Các kỹ thuật dưới đây vẫn chính xác đối với các ứng dụng cũ; Angular hiện đại xử lý cùng một công việc với các biểu mẫu dựa trên mẫu hoặc biểu mẫu phản ứng.

Xác thực biểu mẫu bằng HTML5

Xác thực biểu mẫu là quá trình kiểm tra trước thông tin được nhập vào biểu mẫu trực tuyến trước khi gửi đến máy chủ. Việc xác thực ở phía máy khách được ưu tiên hơn, vì nó làm giảm đáng kể chi phí so với việc phải hiển thị lại biểu mẫu sau mỗi lần gửi và nhận dữ liệu.

Ví dụ bên dưới hiển thị một biểu mẫu đăng ký đơn giản, trong đó người dùng nhập tên người dùng, mật khẩu, địa chỉ email và tuổi. Biểu mẫu có các điều khiển xác thực để đảm bảo thông tin được nhập chính xác.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
    <link rel="stylesheet" href="lib/bootstrap.css">
    <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script>
</head>
<body ng-app="sampleApp">
<h1>Guru99 Global Event</h1>

<form>
    Enter your user name:
    <input type="text" name="name" required><br><br>

    Enter your password:
    <input type="password" name="password"><br><br>

    Enter your email:
    <input type="email" name="email"><br><br>

    Enter your age:
    <input type="number" name="age"><br><br>

    <input type="submit" value="Submit">
</form>
</body>
</html>

⚠️ Mọi thông tin trên trang này đều đã được chỉnh sửa. Những người ban đầu đã tuyên bố chrset="UTF 8", vốn không phải là thuộc tính hợp lệ cũng không phải là mã hóa hợp lệ, và đã tải AngularJS ba lần — angular-route.js Đầu tiên, lỗi xảy ra vì mô-đun định tuyến đăng ký với một framework chưa được tải, sau đó angular.min.jsangular.jsCùng một thư viện được sử dụng hai lần. Họ cũng đã lấy ra. bootstrap.css thông qua một <script> thẻ, vì vậy không có kiểu dáng nào được áp dụng. Mỗi mục hiện tải một thư viện, phiên bản 1.8.3, và liên kết bảng định kiểu một cách chính xác. Khoảng đệm bố cục được xây dựng từ các lần lặp lại &nbsp; Các thực thể đã bị xóa.

Code Giải thích

  1. Đối với kiểu nhập văn bản, required Thuộc tính này có nghĩa là ô văn bản không được để trống khi biểu mẫu được gửi đi.
  2. Loại dữ liệu nhập tiếp theo là mật khẩu. Vì loại dữ liệu này được đánh dấu là mật khẩu, nên văn bản được nhập vào trường này sẽ được che giấu.
  3. Vì kiểu dữ liệu đầu vào được chỉ định là email, nên văn bản trong ô phải khớp với mẫu. tên@site.domain.
  4. Khi kiểu nhập liệu được đánh dấu là số, các ký tự được nhập từ bàn phím sẽ không được trường nhập liệu chấp nhận.

Đầu ra

Để xem quá trình xác thực diễn ra như thế nào, hãy nhấp vào nút Gửi mà không nhập bất cứ thứ gì.

Một cửa sổ bật lên thông báo rằng trường này cần được điền, vì vậy việc đánh dấu ô bắt buộc sẽ ngăn chặn việc gửi biểu mẫu nếu nó bị bỏ trống.

Khi nhập giá trị vào ô mật khẩu, ký hiệu '*' sẽ che khuất các ký tự.

Nhập địa chỉ email không đúng định dạng và nhấn nút Gửi sẽ hiện ra một cửa sổ bật lên yêu cầu ký hiệu @. Cuối cùng, các ký tự được nhập vào ô kiểm tra tuổi không bao giờ hiển thị, vì trường này chỉ chấp nhận số.

Cửa sổ bật lên trên trình duyệt rất nhanh chóng để thiết lập, nhưng nội dung và kiểu dáng của chúng không thể thay đổi. Đó là lúc các thuộc tính xác thực của AngularJS phát huy tác dụng.

Xác thực biểu mẫu bằng cách sử dụng $dirty, $valid, $invalid, $pristine

AngularJS Nó cung cấp các thuộc tính riêng để xác thực. Các thuộc tính sau được hiển thị trên mọi điều khiển được đặt tên:

  • $bẩn – Người dùng đã tương tác với điều khiển
  • $ hợp lệ – Nội dung trường hợp lệ
  • $ không hợp lệ – Nội dung trường không hợp lệ
  • $ nguyên sơ – Người dùng chưa tương tác với điều khiển

Dưới đây là các bước để thực hiện xác thực trong AngularJS.

Bước 1) Sử dụng novalidate Thuộc tính này được khai báo khi sử dụng form. Nó cho trình duyệt biết rằng việc xác thực sẽ được xử lý bởi AngularJS.

Bước 2) Hãy đảm bảo rằng biểu mẫu có tên được định nghĩa, vì tên đó được sử dụng để chuyển đến trạng thái xác thực.

Bước 3) Đảm bảo mỗi biện pháp kiểm soát cũng có một name thuộc tính, vì lý do tương tự. Một điều khiển không có tên sẽ không bao giờ được đăng ký trên biểu mẫu.

Bước 4) Sử dụng ng-show Chỉ thị để kiểm tra các thuộc tính $dirty, $invalid và $valid.

Ví dụ bên dưới có một trường văn bản duy nhất để người dùng nhập tên Chủ đề. Nếu để trống, lỗi xác thực sẽ được kích hoạt và thông báo sẽ hiển thị.

<form ng-app="DemoApp" ng-controller="DemoController"
      name="myForm" novalidate>
    <p>Topic Name:<br>
        <input type="text" name="user" ng-model="user" required>

        <span style="color:red"
              ng-show="myForm.user.$dirty && myForm.user.$invalid">
            <span ng-show="myForm.user.$error.required">Username is required</span>
        </span>
    </p>
    <p>
        <input type="submit" ng-disabled="myForm.$invalid">
    </p>
</form>

<script>
    var app = angular.module("DemoApp", []);

    app.controller("DemoController", function($scope) {
        // Seed the textbox so the form starts in a valid state
        $scope.user = "AngularJS";
    });
</script>

⚠️ Đã sửa hai lỗi logic. Phiên bản gốc đã vô hiệu hóa nút này bằng ng-disabled="myForm.user.$dirty && myForm.user.$invalid". Bởi vì $dirty Giá trị là false cho đến khi người dùng chạm vào ô nhập liệu, nút vẫn giữ nguyên trạng thái đó. kích hoạt trên một khuôn mẫu trống chưa bị chạm vào, chính xác là trường hợp mà nó được thiết kế để chặn; myForm.$invalid bao gồm cả hai. Bản gốc cũng bao bọc giá trị mặc định trong $scope.Display = function () { $scope.user = 'Angular'; }Một hàm chưa từng được gọi, vì vậy hộp văn bản mở ra trống rỗng mặc dù văn bản hiển thị là "AngularJS". Việc gán giá trị hiện được thực hiện trực tiếp, với giá trị nằm trong dấu ngoặc kép của văn bản xung quanh.

Code Giải thích

  1. Biểu mẫu được đặt tên là “myForm”. Điều này là bắt buộc để truy cập vào các thành phần kiểm tra tính hợp lệ của biểu mẫu.
  2. novalidate Thuộc tính này ngăn trình duyệt xác thực, vì vậy AngularJS có thể thực hiện việc đó thay thế.
  3. Chỉ thị ng-show kiểm tra các thuộc tính “$dirty” và “$invalid”. Nếu hộp văn bản đã được sửa đổi, $dirty sẽ là true; nếu giá trị của nó trống, $invalid sẽ là true. Khi cả hai đều đúng, thẻ span với văn bản màu đỏ sẽ được hiển thị.
  4. Hàm kiểm tra lồng nhau đọc thuộc tính “$error.required”, thuộc tính này có giá trị true khi một điều khiển bắt buộc không có giá trị, và hiển thị “Tên người dùng là bắt buộc”.
  5. Nút gửi đã bị vô hiệu hóa. ng-disabled khi toàn bộ biểu mẫu không hợp lệ.
  6. Bộ điều khiển đặt giá trị ban đầu của hộp văn bản thành “AngularJS”, nhờ đó biểu mẫu mở ra ở trạng thái hợp lệ và việc quan sát quá trình xác thực dễ dàng hơn khi văn bản bị xóa.

Đầu ra

Khi biểu mẫu được hiển thị lần đầu, ô nhập liệu sẽ hiển thị “AngularJS” và nút gửi được kích hoạt. Ngay khi bạn xóa văn bản này, thông báo lỗi sẽ xuất hiện và nút sẽ bị vô hiệu hóa.

Ảnh chụp màn hình phía trên cho thấy hai điều:

  • Nút gửi đã bị vô hiệu hóa
  • Vì không có tên chủ đề nào được nhập vào ô văn bản Chủ đề, nên thông báo lỗi “Cần có tên người dùng” sẽ hiển thị.

Cách hiển thị lỗi xác thực bằng ngMessages

Mô hình trên hoạt động, nhưng nó không thể mở rộng. Một trường có bốn ràng buộc cần bốn ràng buộc lồng nhau. ng-show các đường truyền tín hiệu, và khi một số đường truyền bị lỗi cùng lúc, tất cả các thông báo sẽ xuất hiện đồng thời. ngMessages Module này, được nhóm AngularJS phát hành riêng, giải quyết cả hai vấn đề: nó hiển thị từng tin nhắn một, theo đúng thứ tự các tin nhắn được viết.

Tải mô-đun và thêm nó vào danh sách phụ thuộc.

<script src="https://code.angularjs.org/1.8.3/angular-messages.js"></script>
<script>
    angular.module("DemoApp", ["ngMessages"]);
</script>

Khi đó, mã đánh dấu sẽ được đọc như một danh sách các quy tắc chứ không phải là một tập hợp các điều kiện.

<input type="text" name="user" ng-model="user"
       required ng-minlength="4" ng-maxlength="20">

<div style="color:red" ng-messages="myForm.user.$error"
     ng-if="myForm.user.$dirty">
    <div ng-message="required">A topic name is required</div>
    <div ng-message="minlength">Use at least 4 characters</div>
    <div ng-message="maxlength">Use no more than 20 characters</div>
</div>

Ba chi tiết sau đây giúp điều này hoạt động tốt trong thực tế. ng-messages các điểm thuộc tính tại điều khiển $error Đây là một đối tượng chứ không phải là một giá trị boolean, vì vậy không cần phải lặp lại điều kiện nào. Chỉ cần tìm thấy kết quả khớp đầu tiên. ng-message hiển thị, có nghĩa là một trường trống sẽ báo rằng nó là bắt buộc thay vì cũng báo lỗi về độ dài của nó. Thêm vào đó ng-messages-multiple Ngược lại, hành vi đó xảy ra khi mọi thất bại thực sự cần được liệt kê.

Quấnping khối trong ng-if="myForm.user.$dirty" Giữ cho biểu mẫu ở trạng thái im lặng cho đến khi người dùng thực sự nhập nội dung. Thay thế $touched cho $dirty Việc trì hoãn thông báo sẽ tiếp tục, cho đến khi con trỏ chuột rời khỏi trường nhập liệu, đây thường là lựa chọn thân thiện hơn trên một biểu mẫu đăng ký dài.

Một caveat: ngMessages Các tệp được vận chuyển dưới dạng một tập tin riêng biệt, vì vậy việc quên thẻ script hoặc phần phụ thuộc mô-đun sẽ khiến khối lệnh không hiển thị gì cả, và không có lỗi nào trên bảng điều khiển để giải thích điều đó.

Viết tin nhắn bằng tay tuy chính xác nhưng lại lặp đi lặp lại. Phần tiếp theo sẽ giới thiệu một mô-đun giúp tạo ra các tin nhắn này một cách tự động.

Xác thực mẫu bằng cách sử dụng Xác thực tự động AngularJS

AngularJS có thể tự động xác thực tất cả các điều khiển trên một biểu mẫu mà không cần mã tùy chỉnh cho việc xác thực hoặc thông báo lỗi. Điều này được thực hiện bằng cách bao gồm một mô-đun cộng đồng có tên là “jcs-autoValidate”.

Với mô-đun này, không cần viết mã đặc biệt nào để chạy quá trình xác thực hoặc hiển thị thông báo; mọi thứ đều được xử lý bên trong jcs-autoValidate.

Ví dụ dưới đây có một biểu mẫu đơn giản với một ô nhập liệu bắt buộc duy nhất. Một thông báo lỗi sẽ được hiển thị nếu ô nhập liệu này không được điền đầy đủ.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
    <link rel="stylesheet" href="lib/bootstrap.css">
    <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script>
    <script src="lib/jcs-auto-validate.min.js"></script>
</head>
<body>
<h1>Guru99 Event</h1>

<div ng-app="DemoApp">
    <form name="myForm" novalidate>
        <div class="form-group">
            <label for="user">Topic Name:</label>
            <input class="form-control" type="text"
                   id="user" name="user" ng-model="user" required>
        </div>
        <div class="form-group">
            <input type="submit">
        </div>
    </form>
</div>

<script>
    var app = angular.module('DemoApp', ['jcs-autoValidate']);
</script>
</body>
</html>

⚠️ Đính chính: Bản gốc đã xác định bộ điều khiển với id="user" Chỉ vậy thôi. jcs-autoValidate truy cập vào điều khiển thông qua biểu mẫu, vì vậy name Thuộc tính này là bắt buộc và thông báo sẽ không bao giờ xuất hiện nếu thiếu nó. Phiên bản gốc cũng đã tải hai phiên bản AngularJS khác nhau, 1.6.4 từ... Google CDN cùng với phiên bản 1.6.9, và chưa bao giờ được liên kết. Bootstrap mặc dù ví dụ phụ thuộc vào nó form-groupform-control các lớp để định vị văn bản báo lỗi.

💡 Lưu ý: jcs-autoValidate là một dự án cộng đồng và hiện không còn được duy trì tích cực. Nó vẫn có thể sử dụng được trên các ứng dụng AngularJS hiện có, nhưng chức năng tích hợp sẵn đã bị loại bỏ. ngMessages Cách tiếp cận được trình bày trước đó là lựa chọn an toàn hơn cho bất kỳ điều gì mới mẻ.

Code Giải thích

  1. Tệp kịch bản “jcs-auto-validate.js”, chứa toàn bộ chức năng tự động kiểm tra tính hợp lệ, đã được bao gồm.
  2. Mỗi điều khiển và thẻ div bao quanh nó được đặt bên trong một lớp “form-group”, đây là nơi mô-đun chèn thông báo của nó.
  3. Bộ điều khiển mang cả ID và... namevà Bootstrap cung cấp form-control kiểu dáng.
  4. Mô-đun “jcs-autoValidate” được liệt kê là một phần phụ thuộc của mô-đun AngularJS.

Đầu ra

Mặc định, biểu mẫu được hiển thị chính xác như những gì đã nhập.

Khi gửi biểu mẫu trống, thông báo “Trường này là bắt buộc” sẽ được hiển thị, hoàn toàn do jcs-autoValidate tạo ra. Sau khi biểu mẫu được xác thực, câu hỏi còn lại là người dùng sẽ thấy gì trong quá trình gửi đi.

Phản hồi của người dùng với các nút Ladda

Các nút “Ladda” là một khung cấu trúc được xây dựng dựa trên… JavaScript Điều đó tạo ra hiệu ứng hình ảnh cho các nút khi chúng được nhấn.

Nếu một nút được gán thuộc tính “ladda” và được nhấn, hiệu ứng xoay sẽ hiển thị. Có nhiều kiểu dữ liệu khác nhau để tạo thêm hiệu ứng hình ảnh.

Ví dụ bên dưới hiển thị một biểu mẫu đơn giản với nút gửi. Khi nhấn nút, hiệu ứng xoay tròn sẽ xuất hiện trên nút đó.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
    <link rel="stylesheet" href="lib/bootstrap.css">
    <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script>
    <script src="lib/angular-ladda.min.js"></script>
</head>
<body>
<h1>Guru99 Event</h1>

<div ng-app="DemoApp" ng-controller="DemoController">
    <form name="myForm" novalidate ng-submit="submit()">
        <button class="btn btn-primary" type="submit"
                ladda="submitting" name="sbutton"
                data-style="expand-right">Submit</button>
    </form>
</div>

<script>
    var app = angular.module('DemoApp', ['angular-ladda']);

    app.controller('DemoController', function($scope) {
        $scope.submitting = false;

        $scope.submit = function() {
            $scope.submitting = true;
        };
    });
</script>
</body>
</html>

⚠️ Đính chính: bản gốc đã được tải angular-ladda.jsangular-ladda.min.js Cùng nhau, thao tác này đăng ký cùng một mô-đun hai lần, và lại kéo theo hai phiên bản AngularJS. Nó cũng liệt kê jcs-autoValidate Như một phần phụ thuộc mà ví dụ này không bao giờ sử dụng. Mỗi thư viện chỉ được tải một bản sao ở đây.

Code Giải thích

  1. Các "ng-gửiChỉ thị này gọi một hàm có tên là “submit”, hàm này sẽ thay đổi thuộc tính ladda của nút.
  2. Thuộc tính ladda thuộc về khung Ladda và là thứ tạo ra hiệu ứng xoay. Giá trị của nó được liên kết với... submitting biến.
  3. Thuộc tính data-style là một thuộc tính khác của Ladda dùng để chọn hiệu ứng hình ảnh khác nhau.
  4. Để framework hoạt động, cần phải thêm mô-đun 'angular-ladda' vào ứng dụng AngularJS.
  5. submitting Biến được khởi tạo thành false, do đó nút bấm ban đầu không có hiệu ứng xoay.
  6. Chức năng gửi thiết lập submitting Đặt thành true, thao tác này sẽ áp dụng hiệu ứng. Trong một ứng dụng thực tế, nó sẽ được đặt lại thành false sau khi máy chủ phản hồi, nếu không nút sẽ quay mãi không ngừng.

Đầu ra

Khi biểu mẫu được hiển thị lần đầu, nút gửi sẽ hiển thị ở dạng đơn giản.

Khi nhấn nút, thì submitting Biến được đặt thành true. Giá trị đó được truyền đến thuộc tính “ladda” của nút, tạo ra hiệu ứng xoay.

Câu Hỏi Thường Gặp

Biến `$dirty` trả về `true` khi giá trị thay đổi. Biến `$touched` trả về `true` khi trường nhập liệu mất tiêu điểm. Sử dụng `$touched` để trì hoãn lỗi cho đến khi người dùng chuyển sang thao tác khác, điều này tạo cảm giác nhẹ nhàng hơn.ping.

Thêm chỉ thị ng-pattern với biểu thức chính quy, ví dụ: ng-pattern=”/^[0-9]{6}$/”. Khi đó, lỗi sẽ hiển thị dưới dạng $error.pattern, mà ngMessages có thể báo cáo giống như bất kỳ ràng buộc tích hợp nào.

Đúng vậy. Các công cụ AI đọc mã đánh dấu và tạo ra các khối required, ng-pattern và ngMessages phù hợp. Luôn luôn xem lại các biểu thức chính quy, vì các mẫu email và số điện thoại được tạo ra thường từ chối các đầu vào hợp lệ.

Các trợ lý AI nhanh chóng kiểm tra ba nguyên nhân thường gặp: thiếu thuộc tính name trên biểu mẫu hoặc điều khiển, thiếu ng-model và novalidate bị bỏ sót nên trình duyệt chặn việc gửi dữ liệu trước.

Không. Nó cải thiện trải nghiệm và giảm số lần gửi yêu cầu, nhưng bất kỳ ai cũng có thể vượt qua nó bằng các công cụ dành cho nhà phát triển. Mọi quy tắc được thực thi trong trình duyệt đều phải được thực thi lại trên máy chủ.

Tóm tắt bài viết này với: