search
HomeWeb Front-endJS TutorialHow to Create Form-Based Directives in AngularJS

How to Create Form-Based Directives in AngularJS

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 and ng-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.

The

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:

  1. scope – Used to access the isolation scope created for each directive instance.
  2. iElement – Used to access element items. It is safe to update and modify the element from the postLink function within the element it is allocated to.
  3. iAttrs – Used to access properties on the same tag of the instantiation directive.
  4. controller – If an external controller dependency exists, it can be used in a link function. These must correspond to the require attribute of the directive object.
  5. 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

What is the difference between form and ng-form in AngularJS?

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

How to create custom verification directives in AngularJS?

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!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
JavaScript Engines: Comparing ImplementationsJavaScript Engines: Comparing ImplementationsApr 13, 2025 am 12:05 AM

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.

Beyond the Browser: JavaScript in the Real WorldBeyond the Browser: JavaScript in the Real WorldApr 12, 2025 am 12:06 AM

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.

Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Apr 11, 2025 am 08:23 AM

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

How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)Apr 11, 2025 am 08:22 AM

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: Exploring the Versatility of a Web LanguageJavaScript: Exploring the Versatility of a Web LanguageApr 11, 2025 am 12:01 AM

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 Evolution of JavaScript: Current Trends and Future ProspectsThe Evolution of JavaScript: Current Trends and Future ProspectsApr 10, 2025 am 09:33 AM

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.

Demystifying JavaScript: What It Does and Why It MattersDemystifying JavaScript: What It Does and Why It MattersApr 09, 2025 am 12:07 AM

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.

Is Python or JavaScript better?Is Python or JavaScript better?Apr 06, 2025 am 12:14 AM

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.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

DVWA

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

Notepad++7.3.1

Easy-to-use and free code editor

MantisBT

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.