Core points
- Create reusable form components using AngularJS directives. The components have independent scopes, enhancing the modularity and maintainability of web applications.
- Implement custom verification methods in directives to handle complex input verification, ensuring data integrity before being submitted to the server.
- Use AngularJS built-in form verification technologies (such as
ng-required
andng-pattern
) to quickly establish client input verification. - Use
FormController
in AngularJS to manage form status and verification to provide users with instant feedback and improve user experience. - Use the
ng-submit
directive to handle form submissions in AngularJS, blocking the default submission behavior, and enabling custom verification logic before sending data to the server.
Many developers face unique challenges when executing complex business constraints on user-submitted data. Recently, my team faced this challenge when I was writing an application at GiftCards.com. We need to find a way to allow our customers to edit multiple products in one view, each with its own unique verification rules.
This proves challenging because it requires us to use multiple <form></form>
tags in the HTML source code and maintain a validation model for each form instance. Before we find the solution, we tried many methods, such as using ngRepeat
to display subforms. Finally, we create a directive for each product type (each directive has a <form></form>
in its view) and have the directive bind to its parent controller. This allows us to leverage Angular's parent-child form inheritance to ensure that the parent form is valid only if all child forms are valid. In this tutorial, we will build a simple product review screen (highlighting the key components of our current application). We will have two products, each with its own instructions and each product has unique verification rules. There will be a simple checkout button, which will ensure both forms are valid.
If you are anxious to see how it actually works, you can jump directly to our demo or download the code from our GitHub repository.
About the command
The directive is a piece of HTML code that runs through AngularJS's HTML compiler ($compile
) and is attached to the DOM. The compiler is responsible for traversing the DOM and finding components that it can convert into objects using other registered directives. Directives work within an isolated scope and maintain their own views. They are powerful tools that facilitate reusable components that can be shared throughout the application. For a quick review, check out this article or AngularJS documentation.
directive solves our fundamental problem in two ways: first, each instance has an isolated scope; second, the directive is passed using the compiler, which uses the Angular ngForm
directive to recognize the Form element. This built-in directive allows multiple nested form elements to accept an optional name
attribute to instantiate FormController
and will return the form object.
About FormController
When the compiler recognizes any form object in the DOM, it will instantiate a ngForm
object using the FormController
directive. This controller will scan all input, selection, and text area elements and create corresponding controls. The control requires a model property to set up two-way data binding and allows instant user feedback through various pre-built verification methods. Provide instant feedback to consumers, allowing them to know what information is valid before making HTTP requests.
Prebuilt verification method
Angular packages 14 standard verification methods. These include min
, max
, required
and other validators. They are built to understand and manipulate almost all HTML5 input types and are cross-browser-compatible.
<input type="text" ng-model="size" ng-required="true" novalidate> <span ng-show="myForm.size.$error.required"> Size: The value is required! </span>
The above example shows how to use the ngRequired
directive validator in Angular. This verification ensures that the field is filled in before it is considered valid. It does not verify any data, it just does the user enter something. Having the novalidate
attribute means that the browser should not verify when submitting.
Pro tip: Do not set
action
attributes on any Angular form. This will prevent Angular from trying to make sure the form is not submitted in a round trip manner.
Custom verification method
Angular provides an extensive API to help create custom validation rules. With this API, you can create and extend your own validation rules for complex inputs not covered in standard validation. My team relies on some custom validation methods to run the complex regular expression patterns our server uses. Without the ability to run a complex regular expression matcher, we may send incorrect data to the backend server. This will show errors to the user, resulting in a bad user experience. Custom validators use directive syntax and need to be injected ngModel
. More information can be found by consulting the AngularJS documentation.
Create the controller
Now, we can start our application. You can find an overview of the controller code here.
The controller will be at the heart of things. It has only a few responsibilities - its view will have a form element named parentForm
, it has only one attribute, and its methods will include registerFormScope
, validateChildForm
and checkout
.
Controller properties
We need a property in the controller:
<input type="text" ng-model="size" ng-required="true" novalidate> <span ng-show="myForm.size.$error.required"> Size: The value is required! </span>
This property is used to maintain the Boolean state of the overall validity of the form. We use this property to disable its status after clicking the Checkout button.
Method: registerFormScope
$scope.formsValid = false;When
is called, a registerFormScope
and a unique directive ID created in the instruction instantiation are passed to it. This method then appends the form scope to the parent FormController
. FormController
Method: validateChildForm
This method will be used to coordinate with the backend server that performs the verification. It is called when the user is editing the content and needs additional verification. Conceptually, we do not allow instructions to perform any external communication.Please note that for the purposes of this tutorial, I omitted the backend components. Instead, I reject or parse promises based on whether the amount entered by the user is within a specific range (product A is 10-50 and product B is 25-500).
$scope.registerFormScope = function (form, id) { $scope.parentForm['childForm'+id] = form; };Using the
service allows instructions to comply with interfaces with success and failure status. The nature of the application interface between "Edit" and "Save" depends on the editing of the model data. It should be noted that the model data is updated immediately when the user starts typing. $q
Method: Checkout
Click "Checkout" to indicate that the user has completed editing and wants to checkout. This actionable item requires verification that all forms loaded in the directive are validated before the model data can be sent to the server. The scope of this article does not include methods for sending data to a server. I encourage you to explore using the service for all client-to-server communication. $http
$scope.validateChildForm = function (form, data, product) { // 重置表单,使其不再有效 $scope.formsValid = false; var deferred = $q.defer(); // 验证表单和数据的逻辑 // 必须在promise上返回resolve()或reject()。 $timeout(function () { if (angular.isUndefined(data.amount)) { return deferred.reject(['amount']); } if ((data.amount < product.minAmount) || (data.amount > product.maxAmount)) { return deferred.reject(['amount']); } deferred.resolve(); }); return deferred.promise; }This method uses Angular's ability, and child forms can invalidate the parent form. The parent form is named
to clearly illustrate its relationship with the child form. When the child form uses its parentForm
method, it will automatically rise to the parent form to set validity there. All forms in $setValidity
must be valid, and their internal parentForm
attributes must be true. $valid
Create our directive
Our instructions must follow a common interface that allows for full interoperability and scalability. The name of our directives depends on the product they contain.You can find an overview of the instruction code here (product A) and here (product B).
Scope of the isolation instruction
Each instantiated directive will get an isolated scope that is localized to the directive and has no external properties known. However, AngularJS allows the creation of directives that use parent scope methods and properties. When passing external properties to the local scope, you can indicate that you want to set up a two-way data binding.Our application will require some external two-way data binding methods and properties:
$scope.checkout = function () { if($scope.parentForm.$valid) { // 连接服务器以发布数据 } $scope.formsValid = $scope.parentForm.$valid; };Method: registerFormScope
The first property in the directive local scope is the method to register the local scope.form to the controller. The instruction requires a pipeline to pass the local
object to the main controller. FormController
Object: giftData
This is the centralized model data that will be used in the instruction view. This information will be bidirectional data binding to ensure that updates occurring in FormController
will propagate to the main controller.
Method: validateChildForm
This method is the same as the one defined in the controller. This method is called when the user updates information in the instruction view.
Object: product
This object contains information about the product being purchased. Our demonstration uses a relatively small object with only a few properties. My team's real-world application has a lot of information to make decisions in the application. It is passed into validateChildForm
to provide the context of the content being verified.
Instruction link
Our directive will use the postLink
function and pass it a scope object. In addition, the postLink
function also accepts several other parameters. They are as follows:
-
scope
– Used to access the isolation scope created for each directive instance. -
iElement
– Used to access element items. It is safe to update and modify the element from thepostLink
function within the element it is allocated to. -
iAttrs
– Used to access properties on the same tag of the instantiation directive. -
controller
– If an external controller dependency exists, it can be used in a link function. These must correspond to therequire
attribute of the directive object. -
transcludeFn
– This function is the same as the function listed in the$transclude
parameter of the instruction object.
link
Responsible for attaching all DOM listeners and updating the DOM with view elements.
<input type="text" ng-model="size" ng-required="true" novalidate> <span ng-show="myForm.size.$error.required"> Size: The value is required! </span>
Register form scope
$scope.formsValid = false;
Wrapping method registerFormScope
in $timeout
will delay its execution until the end of the execution stack. This provides the compiler with enough time to complete all the necessary links between the controller and the instructions. scope.form.fields
is an array, the name of the property found in FormController
, which is very important for setting up server-side verification errors. The purpose of registerFormScope
is to send FormController
to the parent controller, allowing the newly created form to be set to a child form of parentForm
.
When verification information changes
$scope.registerFormScope = function (form, id) { $scope.parentForm['childForm'+id] = form; };
When the form changes and the user is ready to verify it, the saveForm
method in the directive is called. This method will invoke the controller's validateChildForm
method in turn and pass in FormController
, scope.giftData
and scope.product
. The controller returns a promise that will be parsed or rejected according to other validation rules.
When promise is rejected, the controller will return an invalid field. This is used to invalidate the form (and parentForm
) and set other field level errors. In our demo, we use simple post-verification on the amount
field and we do not return the cause of failure. Rejections from validateChildForm
can be as complex or simple as your application needs to.
When promise returns successfully, the command needs to set the validity of the fields in the form. The code must also clear any previously identified server errors. This ensures that the directive does not provide errors to the user incorrectly. Setting all fields with $setValidity
will be linked to parentForm
in the controller to set their validity, provided that all subforms are valid.
Set our view
The view is not very complicated, and for our demonstration we simplified the product to the following fields: name and amount. In the next step, we will explore the views you need to complete this application.
You can find an overview of the view code here (Product A) and here (Product B).
Route View
<input type="text" ng-model="size" ng-required="true" novalidate> <span ng-show="myForm.size.$error.required"> Size: The value is required! </span>
This view is important because it sets up the parent form, which will be used to wrap all child forms loaded from the product directive. Using ng-repeat
in ng-if
ensures that the DOM is not filled incorrectly with an unused FormController
.
Instruction View
$scope.formsValid = false;
Note: The above view on the demo layout has been truncated in some places and has nothing to do with this article.
The above amountInput
sets a verification mode which will be enforced by Angular's ngPattern
validator. The above field will use the ngDisabled
directive built by Angular, which evaluates the expression, and if true, the field will be disabled.
At the bottom of the view, we display all errors to provide feedback to the user when the user clicks the "Save" button. This will set the $submitted
property on the subform.
Summary
Put all the pieces together and we end up with the following: (CodePen link or code snippet should be inserted here)
You can also find all the code on GitHub.
Conclusion
My team learned a lot when building our latest apps. Understanding the father-son form relationship allows us to simplify our comment screen. Using directives allows us to develop a form that can be used in any context and promotes good reusable code. The directive also enables us to unit test the code to ensure our form works as expected. Our application is in production and has contributed to over 100,000 orders.
I hope you enjoyed reading this article. If you have any questions or comments, I'd love to hear them in the comments below.
FAQ for Form-Based Directives in AngularJS
What is the role of form-based directives in AngularJS?
Form-based directives in AngularJS play a crucial role in managing and validating user input in forms. They provide a way to create custom HTML tags that act as new custom widgets. They can also manipulate DOMs in a way that adds functionality to our applications. These instructions are especially useful when you want to encapsulate and reuse common features throughout your application.
How to create custom form-based directives in AngularJS?
Creating a custom form-based directive in AngularJS involves defining a new directive using the .directive
function. You need to provide your directive with a name and a factory function that will generate the option object of the directive. This object can define multiple properties, including restrict
, template
, scope
, link
, and so on. The restrict
option is used to specify how directives are called in HTML.
How to verify form input using AngularJS directive?
AngularJS provides some built-in instructions for form validation, including ng-required
, ng-pattern
, ng-minlength
, ng-maxlength
, and more. These instructions add validation to your form input, ensuring that user input meets certain criteria before the form is submitted. You can also create custom verification directives for more complex verification requirements.
What is the purpose of FormController in AngularJS?
FormController
in AngularJS provides methods for tracking the status of forms and their controls, checking validity, and resetting forms. It is automatically available within the form directive and can be injected into the controller, other directives, or services.
How to use ng-submit directive in AngularJS?
The directive in AngularJS allows you to specify custom behavior when submitting a form. Instead of writing JavaScript code to handle the form's submission event using ng-submit
. This is especially useful when preventing the default form submission behavior when the form is invalid. ng-submit
The main difference between
and in form
in ng-form
is that ng-form
can be nested in other forms. This allows you to group relevant inputs together and validate them as a subform. On the other hand, the standard form
directives do not support nesting.
How to set the validity of a form field in AngularJS?
You can set the validity of form fields in AngularJS using the ngModelController
method provided by $setValidity
. This method accepts two parameters: the validation key and the boolean value. If the boolean value is false, the key is added to the field's $error
object.
How to use ng-model directive in AngularJS form?
The ng-model
directive in AngularJS binds input, selection, text area, or custom form control to properties on scope. It provides two-way data binding between the model and the view. This means that any changes to the input field will automatically update the model and vice versa.
What is the role of the ng-change directive in AngularJS form?
The directive in AngularJS allows you to specify custom behavior when the user changes input. This directive is useful when you want to perform something immediately after the user has finished typing or making a selection instead of waiting for the form to be submitted. ng-change
Creating a custom verification directive in AngularJS involves defining a new directive that needs
. In the ngModel
function of the directive, you can use the link
or ngModelController
pipeline to add custom validation logic. $validators
The above is the detailed content of How to Create Form-Based Directives in AngularJS. For more information, please follow other related articles on the PHP Chinese website!

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

JavaScript is the core language of modern web development and is widely used for its diversity and flexibility. 1) Front-end development: build dynamic web pages and single-page applications through DOM operations and modern frameworks (such as React, Vue.js, Angular). 2) Server-side development: Node.js uses a non-blocking I/O model to handle high concurrency and real-time applications. 3) Mobile and desktop application development: cross-platform development is realized through ReactNative and Electron to improve development efficiency.

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

Python is more suitable for data science and machine learning, while JavaScript is more suitable for front-end and full-stack development. 1. Python is known for its concise syntax and rich library ecosystem, and is suitable for data analysis and web development. 2. JavaScript is the core of front-end development. Node.js supports server-side programming and is suitable for full-stack development.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Zend Studio 13.0.1
Powerful PHP integrated development environment

SublimeText3 Linux new version
SublimeText3 Linux latest version

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Notepad++7.3.1
Easy-to-use and free code editor

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.