Utilize $validators during blur/focus interactions

In my validation directive, I currently manually set the validation state like this:

$element.on('focus', function() {
    $scope.$apply(function() {
       ngModelCtrl.$setValidity('length', true);
    });
 });

 $element.on('blur', function() {
    $scope.$apply(function() {
        if (ngModelCtrl.$modelValue && ngModelCtrl.$modelValue.length === +$attrs.maxlength) {
            ngModelCtrl.$setValidity('length', true);
        }      
        else if (ngModelCtrl.$modelValue.length < +$attrs.maxlength && ngModelCtrl.$modelValue.length > 0) {
            ngModelCtrl.$setValidity('length', false);
        }
     }
 });

Now, I am looking for a way to set validation states using $validators while maintaining the same validation behavior on blur/focus events.

I cannot utilize ng-model-options with updateOn: 'blur'.

Are there any other options available for achieving this?

Answer №1

To implement a custom validator, you need to structure your directive differently by requiring the ngModel module.

Custom Validator Directive:

return {
     require: 'ngModel',
     link: function(scope, element, attrs, ngModel) {
        // Implement custom max length validation
        ngModel.$validators.customMaxLength = function(value) { 
          var status = false;
            if(value.length <= attrs.maxLengthValidator) {
              console.log(attrs.maxLengthValidator);
              status = true;
            }
              return status;
        };
    }
  }

It's important to note that if your validation depends on an attribute that can change, you must manually watch the value and run the validator function, as the model update does not trigger the validator automatically.

Add the following to the directive to handle attribute changes:

    scope.$watch(function() {
        return attrs.maxLengthValidator;    
    },function() {
        ngModel.$validate();
    });

If your validator returns false, the form will set $valid to false.

HTML Implementation:

In the example below, angular-messages is used to display the validation output. This module is optional but needs to be included.

<form name="myForm">
    <div class="form-group" ng-class="{'has-error':myForm.testField.$invalid}">
      <label class="control-label" for="testInput">Test Field</label>
      <input class="form-control" type="text" name="testField"  
        max-length-validator="3" required ng-model="testField"/>
    </div>
</form>

    <div ng-messages ng-messages-multiple class="bg-danger" for="myForm.testField.$error">
                <div ng-message when="required">Please enter a value</div>
                <div ng-message when="customMaxLength">Value too long</div>
    </div>

View Custom Validator Example


About firing the validator on blur:

Avoid updating ngModel if the model value is invalid.

I suggest using styles and a focus attribute with the field to toggle display based on field focus.

Add this to your input field:

ng-focus="myForm.testField.focus=true" ng-blur="myForm.testField.focus=false"

Then use checks with ng-class, ng-show, or ng-hide to update display accordingly.

This enhancement has been included in the Plunker demo.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The method for retrieving and entering a user's phone number into a text field upon their visit

Objective: To enhance the user experience by automatically filling in the phone number input field when a mobile user views the page, making it easier to convert them into leads. A privacy policy will, of course, be in place. This page will offer a promo ...

What assistance is available for building a JavaScript package that integrates and utilizes all necessary dependencies?

I am looking for a solution to include a third-party library in a JavaScript file that will be downloaded to our project only when we visit a specific page. This library is installed with npm and I want it to be part of the js package without includi ...

Caution: React is unable to identify the `PaperComponent` prop on a DOM element

Trying to create a draggable modal using Material UI's 'Modal' component. I want users to be able to move the modal around by dragging it, so I decided to use 'Draggable' from react-draggable library. However, I encountered this er ...

Refresh the div element's HTML and content using AJAX

I am interested in implementing a feature similar to the StackExchange link found on the top left of the Stack Overflow site. From what I gather, when the stack exchange link is clicked, the following actions take place: The hidden div container becom ...

Firefox is mistakenly interpreting a pasted image from the clipboard as a string instead of a file, causing

I am facing an issue where I am attempting to extract images from a contenteditable div using the paste event. The code works perfectly in Chrome but does not function as expected in Firefox. I have implemented the following code: $(window).on("paste& ...

Can you explain the distinction between document.body.ononline and navigator.onLine?

Can you explain the distinction between document.body.ononline and navigator.onLine? Do they utilize the same JavaScript API for checking network connectivity status (online/offline)? I have searched on Google but couldn't find a definitive answer. If ...

Exploring the outer scope within JavaScript

Currently, I am working on a JavaScript code snippet where I am attempting to set the 'obj' variable from the success and error callbacks. However, it seems like the scope of the 'toLinkInfo' function is not encompassing these callbacks ...

Limiting the length of parameters in an Angular directive

Is there a character limit for the parameter being sent to this directive? I'm encountering an issue with my code: header = JSON.stringify(header); columnObj = JSON.stringify(columnObj); $compile('<div column-filter-sort header=' + heade ...

Analyzing and refreshing the data entries in firebase database

https://i.stack.imgur.com/ZMjck.png I have been attempting to modify my Username password group name. However, the update process is not successful. I am looking for a way to compare data before updating fields, but I am unable to find a suitable method. ...

Getting Observable Centered Text in Angular with Chart.js

I have implemented ng2 charts and chart.js to create a doughnut chart. One of my requirements is to center text inside the doughnut chart, and I have tried the following approach: https://stackblitz.com/edit/ng2-charts-doughnut-centertext?file=src%2Fapp% ...

When using TypeScript with custom components as children in React, the `type` returned by React.Children is a string representing the function

It might sound a bit odd, or maybe I'm completely off track here. While going through some articles and React documentation on getting children and identifying specific child components using React.Component.map(), I ran into an issue with my custom c ...

Transferring a variable value between functions using autocomplete and AJAX communication

I am facing difficulties with implementing autocomplete jQuery along with AJAX call. The issue arises when a user enters text in the input field, triggering an AJAX POST request to the controller which retrieves values from the database and sends them back ...

Retrieve the content of the nearest 'td' element using the '.closest()' method, then locate the desired

I am struggling to assign the value from a <td> to a variable. My approach involves utilizing the closest() and find() methods in jQuery to locate the desired <td>. Interestingly, when I use alert on the <td>, it displays the correct val ...

Troubleshooting undefined results with AngularJS ng-repeat filter

My objective is to create a Letter Filter, where users can click on buttons from A to Z to filter the displayed data. When clicking on the letter 'A' button, only data starting with 'A' should be shown. However, I have encountered an i ...

Guide on sending JSON data to a server and receiving JSON/XML in response with JSP

I am new to developing web applications. I have successfully created a dynamic web project using Java EE on a Glassfish server. Now, I am trying to enable clients to send data to the server using JSON and receive data from the server in either JSON or XML ...

PHP response is blank when password_hash or password_verify functions are used

My application utilizes JavaScript to retrieve a string and send it via POST to a PHP file on the server for processing. The PHP receiver is responsible for parsing the string, performing tasks, and sending back status updates to JavaScript. However, after ...

Guide to creating fog animations in three.js

I'm attempting to adjust the fog density using tweening, but for some reason, it doesn't seem to be working. Here are my default settings: var camera, densityFog, colorFog2; colorFog2 = 0xfee2ed; densityFog ...

Node.js setInterval is a method used to repeatedly execute a function

I have a code snippet for an http request that is supposed to run every one minute. However, I am encountering an issue with the following error: "Error: listen EADDRINUSE". Here is my current code: var express = require("express"); var app = express(); v ...

A method for increasing a counter using only an instance of a class or function without accessing its methods or properties in Javascript

Looking at the task ahead, let increment = new Increment(); I have been tasked with creating a Javascript class or function called Increment in order to achieve the following: console.log(`${increment}`) // should output 1 console.log(`${increment}`); ...

Clicking on the parent page prevents the hyperlink inside the iframe from working as expected

I am having an issue with a hyperlink inside an iframe. When I click on it in the parent page, it doesn't work. Here is how it is set up: iframe.html <h1>I'm inner page!</h1> <a id="shared" class="btn" href=&q ...