Displaying angular ng-messages only when the field has been touched

Nothing too out of the ordinary here.

I need my input to be validated with each keystroke. If the validation fails, I want the error message to display right away, without waiting for the blur event to trigger the $touched function.

I assumed this was the default behavior, but it turns out it's not. I'm using Angular Materials in conjunction with Angular Messages for this, specifically for caps lock detection.

Here's the code snippet:

<form name="primaryLogin" novalidate>
    <md-content layout-padding layout="column">
        <md-input-container flex>
            <label>Login ID</label>
            <input type="text" required="" name="login" ng-model="primary.loginID" capslock>

            <div ng-messages="primaryLogin.$error">
                <div ng-message="required">
                    Please enter a Login ID.
                </div>

                <div ng-message="capslock">
                    Caps Lock is ON!
                </div>
            </div>

            <pre>{{ primaryLogin | json }}</pre>

        </md-input-container>

    </md-content>
</form>

Upon first accessing the page, turning on caps lock, and starting to type, the error message looks like this:

{
  "$error": {
    "capslock": [
      {
        "$viewValue": "Q",
        "$validators": {},
        "$asyncValidators": {},
        "$parsers": [
          null
        ],
        "$formatters": [
          null,
          null
        ],
        "$viewChangeListeners": [],
        "$untouched": false,
        "$touched": true,
        "$pristine": false,
        "$dirty": true,
        "$valid": false,
        "$invalid": true,
        "$error": {
          "capslock": true
        },
        "$name": "login",
        "$options": {
          "debounce": 100,
          "updateOnDefault": true
        }
      }
    ]
  },
  "$name": "primaryLogin",
  "$dirty": true,
  "$pristine": false,
  "$valid": false,
  "$invalid": true,
  "$submitted": false,
  "login": {
    "$viewValue": "Q",
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [
      null
    ],
    "$formatters": [
      null,
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": false,
    "$dirty": true,
    "$valid": false,
    "$invalid": true,
    "$error": {
      "capslock": true
    },
    "$name": "login",
    "$options": {
      "debounce": 100,
      "updateOnDefault": true
    }
  }
}

It seems to be functioning as expected, but the error message does not actually display until the blur event is triggered on that specific input. So even if I turn on caps lock, type in 10 characters, and see that the caps lock error is present in the object, it won't show up since $touched is not true.

Once $touched becomes true, everything works as intended when re-entering the input.

Any suggestions? Thanks in advance!

Answer №1

Make a modification

<div ng-messages="primaryLogin.$error">

into

<div ng-messages="primaryLogin.$error" ng-show="primaryLogin.login.$dirty">

Another option is

<div ng-messages="primaryLogin.$error" ng-show="primaryLogin.login.$touched">

OR

<div ng-messages="primaryLogin.$error" ng-show="primaryLogin.login.$pristine">

You can also combine them for conditional AND checking like this:

<div ng-messages="primaryLogin.$error" ng-show="primaryLogin.login.$dirty && primaryLogin.login.$touched && primaryLogin.login.$pristine"> 

or for conditional OR checking:

<div ng-messages="primaryLogin.$error" ng-show="primaryLogin.login.$dirty || primaryLogin.login.$touched || primaryLogin.login.$pristine">

Test each option to determine which one best fits your situation.

Answer №2

Previously, in versions before Angular Material Pre 1.0 (v0.11.4), the ng-message would be displayed automatically.

However, according to the material design guidelines:

Display error messages only after user interaction with a field. If the user enters incorrect data, helper text can change into an error message.

If you wish to display messages before the user interacts, you can include "md-auto-hide='false'" in your ng-messages directive.

<div ng-messages="primaryLogin.$error" md-auto-hide='false'></div>

I discovered this solution from: here

Answer №3

Make sure to verify using

ng-show="primaryLogin.login.$invalid && primaryLogin.login.$touched"
. It worked like a charm for my situation.

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

Show the MySQL query results in a pop-up alert box

I need assistance with querying a MySQL database for certain results using PHP and then displaying the result in an alert dialog box through JavaScript. I am able to connect to the database, query the data successfully, and display it on a PHP page. Howeve ...

The code functions perfectly on JSfiddle, but for some reason it halts when implemented on

Unfortunately, the code that was working perfectly on JSfiddle seems to be encountering issues when implemented on a regular HTML site. The content loads fine but there seems to be an error with the preview function after selecting an image. We have colla ...

I encountered an issue while attempting to utilize a JavaScript script - I received an error message stating "Uncaught ReferenceError: jQuery is not defined."

Currently, I am utilizing a template with multiple pages and I need to use one of them. I followed all the necessary steps correctly, but I encountered an error in the console that says Uncaught ReferenceError: jQuery is not defined. Below is my HTML scrip ...

A guide on converting array values to objects in AngularJS HTML

Here is my collection of objects: MyCart = { cartID: "cart101", listProducts : [ {pid:101, pname:"apple", price: 200, qty:3}, {pid:102, pname:"banana", price: 100, qty:12} ] } I have incorporated a form in ...

Issues arise while utilizing the execute method in PHPUnit-Selenium2

When creating Acceptance tests with PhpUnit and its Selenium2 extension, I am attempting to utilize the execute method within the PHPUnit_Extensions_Selenium2TestCase class to run Javascript code that checks if the document is fully loaded. Here is an exa ...

Manipulating global state properties within a reducer function in React: How to do it efficiently

I am looking to implement a single loader (backdrop and spinner) within my app component that can be displayed based on the value of a property in the Redux state called showLoader. This loader should be accessible throughout my entire React application. T ...

How can I prevent opening duplicate tabs of the same website simultaneously?

Is there a way to prevent users from accessing the same website page from multiple tabs? Could this be accomplished using JavaScript? ...

Unexpected behavior occurs when ajax is added to an array for jQuery promise results

In my code, I have an each loop that makes individual AJAX requests and stores them in an array like this: var promises = []; $items.each(function(k, v) { promises.push( $.ajax({ url: ..., .... }) ); }); $.when.app ...

Tips for determining if a cookie has been set in a controller during an Angular unit test

A scenario involves a controller that transmits a username and password to a REST service, receiving a token in return: .controller('Login', ['$scope', '$cookieStore', '$http', function($scope, $cookieStore, $http) ...

Finding compatibility between two arrays with flexibility

I am currently working on an Ionic app that involves an array of ingredients and a service with recipes. You can find the structure of the recipe service here. My goal is to match the ingredients with the recipes. Currently, I have implemented the followi ...

Changing the location of an ArcGIS map with a click event in a Vue application

I am attempting to dynamically update a map to display my current location using Vue. I have created an onClick event that updates the props and sends them to my map component. To trigger a re-render of the map component when the data changes, I am utilizi ...

Is there a method in CSS animations that allows for endlessly repeating successive animations in a specified sequence?

While working with CSS animations, I encountered a challenge of making two animations occur successively and repeat infinitely without merging keyframes. Is there a way to achieve this using only CSS? If not, how can I accomplish it using JavaScript? I a ...

Utilize the $slots property when working with v-slot in your Vue application

When dealing with a specific use-case, it becomes necessary to retrieve the rendered width and height of a DOM element inside a slot. Typically, this can be achieved by accessing this.$slots.default[0].elm. However, complications arise when introducing sc ...

What is the best way to capture the output of a script from an external website using Javascript when it is returning simple text?

Recently, I decided to incorporate an external script into my project. The script in question is as follows: <script type="application/javascript" src="https://api.ipify.org"> </script> This script is designed to provide the client's IP ...

AngularJS: Modifying directive according to service value update

In my current application, I have a basic sidebar that displays a list of names fetched from a JSON call to the server. When a user clicks on a name in the sidebar, it updates the 'nameService' with the selected name. Once the 'nameService& ...

Embarking on the GSAP journey

I'm attempting my first animation using GSAP, but no matter what I try, nothing seems to be working. I've even tried using example code without success. Within my PHP file, I have the following code snippet: <head> <script src="https:/ ...

JavaScript Deviance

I am facing an issue with my JS code while trying to send form data to a .php file via AJAX. The problem occurs when the input fields are filled - for some reason, my client-side page refreshes and the php file does not get executed. However, everything wo ...

Error: The function SomeFunction is not recognized as a valid function (Mongoose library)

Help needed! I'm encountering an error stating "TypeError: User.getUserByUsername is not a function at Strategy._verify (.../routes/users.js:65:10) var User = require('../models/user'); passport.use(new LocalStrategy( function(username, ...

displaying a confirmation using jQuery in CodeIgniter

Hello everyone, I am a beginner in CodeIgniter and I am seeking assistance. I am attempting to create a confirmation message (div id="delmsg") using jQuery when deleting a record from MySQL database. The delete operation is functioning properly, but the me ...

When using VueJs, the input value may not clear upon pressing the ESC key for the first time

When I press the ESC key, my input should clear. However, I am experiencing a bug where the input is not cleared after the first press of the ESC key; it only clears after the second press. Even though the console displays an empty value for the input aft ...