Monitoring the validity or errors in AngularJS input fields

I'm attempting to observe the $error or $valid status of a control. Here is the control in question:

<form id="myForm" name="myForm"> 
  <input name="myInput" ng-model="myInputMdl" business-validation/>
</form>

The business-validation directive customizes the validity of the control. I have tried various methods (using either $valid or $error) based on suggestions from this source:

  1. This method does not work as there is no $valid property on myForm.myInput.

    $scope.$watch('myForm.myInput.$valid', function(isValid) {
      $scope.usefulVariable = step3.CreditCardNumber.$valid;
    }, true);
    
  2. This approach fails because validity.valid cannot be watched.

    $scope.$watch('myForm.myInput.validity.valid', function(isValid) {
      $scope.usefulVariable = step3.CreditCardNumber.$valid;
    }, true);
    
  3. This strategy doesn't work as $scope.myInputMdl is not being monitored for changes.

    $scope.$watch('$scope.myInputMdl', function(isValid) {
      $scope.usefulVariable = step3.CreditCardNumber.$valid;
    }, true);
    

Is it possible to watch the validity from a controller?

EDIT

I am not seeking to modify the business-validation directive. My goal is to monitor $valid or $error from the form's controller.

EDIT 2

The code for the controller is as follows:

app.controller('WizardBusinessActionCtrl',
   function($scope, $http, $parse, $filter, wizardBusinessActionService, $timeout) {
     //controller code
   }
);

Answer №1

There is no reason why the initial variant should not be effective.

HTML:

<div ng-app="myApp">
    <div data-ng-controller="MainController">
        <form name="myForm"> 
            <input name="myInput" ng-model="myInputMdl" business-validation />
        </form>
    </div>
</div>

Controller and directive:

var myApp = angular.module('myApp', []);

myApp.controller('MainController', function ($scope) {
    $scope.$watch('myForm.myInput.$valid', function (validity) {
        console.log('valid', validity);
    });
});

myApp.directive('businessValidation', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, elem, attr, ctrl) {
            function validate (input) {
                return input === 'hello';
            }

            ctrl.$parsers.unshift(function (value) {
                var valid = validate(value);
                ctrl.$setValidity('businessValidation', valid);
                return valid ? value : undefined;
            });

            ctrl.$formatters.unshift(function (value) {
                ctrl.$setValidity('businessValidation', validate(value));
                return value;
            });
        }
    };
});

$valid property value will change when myInput validity changes, and $watch callback will be triggered.

View example: http://jsfiddle.net/Lzgts/287/

Answer №2

Give this code a try: View Plunker

Here's the HTML snippet:

<div ng-controller="ExampleController">
  <form name="userForm" novalidate >
    Name:
    <input type="text" name="userName" ng-model="firstName" required />
  </form>
  <div>{{firstName}}</div>
  <input type='button' value='Submit' ng-click='validateInput()'/>
</div>

And here is the JavaScript part:

angular.module('getterSetterExample', [])
  .controller('ExampleController', ['$scope', function($scope) {
    $scope.validateInput = function(){
      $scope.$watch($scope.userForm.userName.$valid, function() {
       if($scope.userForm.userName.$valid){
         alert('Value is True');
       }
       else{
         alert('Value is False');
       }
      });

    }

  }]);

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

Tips for preventing a span from disappearing when a hidden div is displayed during onmouseover

, there is a concern about the disappearing behavior of the span with ID "topnavbar" when the display property changes from none to block on a hidden div using onmouseover event. The query is how to ensure that the span remains visible at all times. Additi ...

Employing buttons and state to eliminate an item from a roster

My list is generated using the following code: return (this.state.limit).fill().map((_,index) => { return ( <div key={`${index}`}> Item </div> ) ) I'm wondering how I can implement a button that allows me to remove a specific ...

how to dynamically update a button's text using Vue.js

I have a challenge where I need to dynamically change the text of a button based on whether a value is true or false. Below is the code snippet that I have been working on: <button class="btn btn-primary table-button" type="button&quo ...

Instantly see changes without having to manually refresh the screen

I need help figuring out how to update my PHP webpage or table automatically in real-time without requiring a manual refresh. The current functionality of the page is working perfectly fine. Specifically, I want the page to instantly display any new user ...

Invalid PDF File - Unable to Complete Download via $http

I'm facing an issue while attempting to download a PDF file using the $http service in AngularJS. Upon trying to open the downloaded file, I encounter an error message stating "Invalid Color Space" and the page appears blank. To troubleshoot this pr ...

What causes Spyscroll to be impacted by Collapse in Bootstrap 5?

I'm utilizing bootstrap 5 as my CSS framework and currently working on a significant section. Therefore, I chose to structure it with one row containing four columns, hiding the others using Bootstrap's collapse feature. However, because this is ...

Generating a live HTML preview using Kendo Editor within an Angular framework

Currently, I am in the process of integrating the Kendo UI Editor with Angular, following the example showcased on their demo site. The implementation has been smooth so far; explore Kendo UI demos here Although everything seems to be functioning well up ...

Modify the numerical presentation within the provided input text

Looking to format numbers in the thousands with a comma, for example changing 2000 to 2,000 and 20000 to 20,000. While I found a solution using cleave.js library, it only works for one input field. Is there another alternative that can handle multiple in ...

Deactivate the AJAX button after the specified number of clicks

Imagine I have a model called Post, and it can be associated with up to n Comments (where the number is determined by the backend). Now, let's say I have a view that allows users to add a Comment through an AJAX request. What would be the most effecti ...

Leveraging the boolean values of attributes within JSX statements

I have been working on a React.js project where I am trying to incorporate a data-picker plugin that requires a specific style of input-attributes: <input data-enable-time=true /> However, I have encountered an issue where webpack fails to compile t ...

Unpacking a props object results in an undefined value

I've been struggling to set up a data-grid in react because I'm facing issues with accessing the data from my props. Whenever I try to access or destructure the prop, it shows up as "undefined" in my console. This problem only arises when the p ...

Having trouble with playing the appended HTML5 Video?

Having trouble getting a video player to display after clicking a button. This is the code I use to add the video player in index.html: $("#videoContainer").append( "<video id=\"video-player\" width=\"100%\" height ...

What is the best way to update the content of a div on an HTML page by incorporating the content of a div from a different page using JavaScript?

I have a requirement where I need to implement a link in a Table of Contents that, upon clicking, should replace the existing content of one div on a page with the content of another div on a different page. My goal is to accomplish this using only JavaScr ...

Utilize string paths for images instead of requires when resolving img src and background-image URLs

I have successfully implemented image loading with webpack using the file loader, but only when I require or import images. I am curious about how create-react-app achieves the functionality where everything in the public folder is accessible, for example, ...

Ways to store a component in cache once its route is triggered

There are 3 components in my project: 1 parent and 2 child components with router outlet. The child component becomes active whenever its route is called, sharing data using a service. Both of these child components have complex views. When switching bet ...

Ways to send data to a popup in svelte

Hey there, I could really use some assistance with my Svelte app. I'm trying to implement a modal and pass a parameter to the modal component in order to customize its content. However, when using the open() function of Modal, we only need to provide ...

Instead of using a checkmark, consider using step numbers with Mui Stepper's Completed StepIcon

I'm currently utilizing Mui Stepper from [email protected] within a React project. Despite my efforts to search on platforms like Stackoverflow and Github, I have been unable to find a solution for displaying the step number upon completion inst ...

ReactJS with conditional closing tags

Here is a sample json response : {id: 1, name: a} {id: 2, name: b} {id: 3, name: c} {id: 4, name: d} {id: 5, name: e} {id: 6, name: f} I am looking to organize these by pairs in my React component like so : <div className="group-item"> ...

if else statement fails to work in ajax-based login form

I tried to create the code below by referencing processes.php, submit form, and ajax from various sources on the internet. However, my code doesn't seem to be working properly. proccess.php <?php session_start(); ini_set('display_errors&apos ...

Exploring how to compare time in hh:mm format using JavaScript

After switching to 24-hour format for my strings, I'm confused as to why the times are not comparing correctly. What am I doing incorrectly? function convertToTwentyFourHourTime(amPmString) { var d = new Date("1/1/2013 " + amPmString); ...