Execute the validation directive using the digest cycle

This particular directive is designed to determine whether a given value exists within the associated datalist or not. It functions flawlessly when I input text into the field, but it fails to work properly if the datalist undergoes changes as a result of the $digest cycle (such as adding new values). However, if I then make an update to the input, it starts working correctly.

app.directive('list', function (){
    return {
        restrict: "A",
        require: "ngModel",
        priority: 100,
        link: function(scope, elem, attr, ngModel){
            var list;

            //For DOM -> model validation
            ngModel.$validators.list = function(value){
                if(!list){
                    var options = document.getElementById(attr.list).options;
                    var list = [];
                    for(var i=options.length-1; i>=0; i--){
                        if(isString(options[i].getAttribute("valid"))){
                            if(options[i].label){list.push(options[i].label.toLowerCase())}
                            if(options[i].value){list.push(options[i].value.toLowerCase())}
                        }
                    };
                }
                var valid = (value||!value==""?list.indexOf(value.toLowerCase()) !== -1:true);
                return (!list.length)||valid;
            };
        }
    };
});

Answer №1

To activate the validation pipeline, you must monitor the list and then execute ngModel.$validate();...

app.directive('list', function (){
    return {
        restrict: "A",
        require: "ngModel",
        priority: 100,
        link: function(scope, elem, attr, ngModel){
            var list;
           
            scope.$watch(function () {
                return $parse(attrs.list)(scope);
            }, function () {
                ngModel.$validate();
            });

            //For DOM -> model validation
            ngModel.$validators.list = function(value){
                if(!list){
                    var options = document.getElementById(attr.list).options;
                    var list = [];
                    for(var i=options.length-1; i>=0; i--){
                        if(isString(options[i].getAttribute("valid"))){
                            if(options[i].label){list.push(options[i].label.toLowerCase())}
                            if(options[i].value){list.push(options[i].value.toLowerCase())}
                        }
                    };
                }
                var valid = (value||!value==""?list.indexOf(value.toLowerCase()) !== -1:true);
                return (!list.length)||valid;
            };
        }
    };
});

Answer №2

It's essential to check out this insightful Stack Overflow discussion on mastering the thought process behind Angular development.

If you find yourself working with a <datalist> element and passing its id through the list attribute in your directive, the following code snippet might resemble what you're dealing with:

<datalist id="myDatalist">
  <options ng-repeat="item in items" value="{{item.value}}">{{item.label}}</options>
</datalist>

<input ng-model="foo" list="myDatalist">

Avoid attempting to extract values directly from the DOM elements like <options>. Leveraging the existing $scope.items (or any other suitable variable) is a cleaner approach when passing data to your list directive, as illustrated below:

.directive("list", function(){
  return {
    // other directive properties,
    scope: {
       list: "="
    },
    require: "ngModel",
    link: function(scope, element, attrs, ngModel){
       scope.$watchCollection("list", function(){
          ngModel.$validate();
          // additional actions upon list change
       });
       // implement validators, etc...
    }
  }
});

The directive can then be implemented as shown:

<input ng-model="foo" list="items">

This method not only utilizes Angular's data-watching capabilities but also enhances decoupling of logic from the DOM structure. Consequently, modifications such as changing element IDs or using different element types won't necessitate altering the directive itself.

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

Oops! An issue has occurred where I am unable to access certain properties (specifically 'Symbol(__APOLLO_CONTEXT__)') while utilizing the Apollo provider

When attempting to implement a query in my upcoming app, I encountered an error that reads: Error: Cannot read properties of undefined (reading 'Symbol(APOLLO_CONTEXT)') This is the setup of my Apollo client: import { ApolloClient, InMemoryCache ...

The data in AngularJS is not being successfully incorporated into the service

Utilizing angularjs and ajax, I am attempting to retrieve data from a webservice and pass it to the controller. To accomplish this, I am using a holder (a factory method or service). The setup works fine without the webservice, but when trying to fetch dat ...

Creating types for React.ComponentType<P> in Material-UI using TypeScript

I am currently working with Typescript and incorporating Material-UI into my project. I am trying to define the component type for a variable as shown below: import MoreVert from '@material-ui/icons/MoreVert' import { SvgIconProps } from '@ ...

Establishing the preset values for Material-UI toggle button group

I utilized the Material UI library to implement a button toggle widget for selecting options. Check out my codesandbox project here - https://codesandbox.io/s/50pl0jy3xk The user can interact by choosing a membership type: adult, child, or infant. Option ...

Is it possible to manage the form submission in React after being redirected by the server, along with receiving data

After the React front-end submits a form with a POST request to the backend, the server responds with a JSON object that contains HTML instead of redirecting as expected. How can I properly redirect the user to the page received from the server? For inst ...

Is it possible to adjust the color of the iOS status bar using NativeScript, Angular 2, and TypeScript?

I recently came across this npm package called NativeScript Status Bar, available at the following link: https://www.npmjs.com/package/nativescript-statusbar However, I'm facing an issue because I cannot use a Page element as I am working with Angul ...

Emphasizes the P tag by incorporating forward and backward navigation options

My goal is to enable users to navigate up and down a list by pressing the up and down arrow keys. For example, if "roma" is currently highlighted, I want it to change to "milan" when the user presses the down arrow key. Here is the HTML code I am working w ...

webpackDevMiddleware does not automatically trigger a reload

Currently, I have implemented webpack dev middleware in my project like this: const compiledWebpack = webpack(config), app = express(), devMiddleware = webpackDevMiddleware(compiledWebpack, { historyApiFallbac ...

Transformation of looks post a refresh

Initially, the CSS and appearance of the page look fine when I first open it (after clearing the cache). However, upon refreshing the page, a part of it changes (specifically, the padding direction of a div). This change occurs consistently with each refre ...

Using the fetch method to consume a RapidAPI JSON response

Currently, I am in the process of learning React Native and have initiated a project for that purpose. In this project, I have integrated RapidAPI (link: ) to fetch necessary data. Upon hitting the API, I receive a 200OK status, but unfortunately, I am fa ...

LESS: Using variable values in mixin and variable names

I am looking to simplify the process of generating icons from svg-files while also creating a png-sprite fallback for IE8 support. I am using grunt.js and less. I was inspired by the implementation on 2gis.ru: (in Russian), where they used technologies s ...

What is the best way to create a JavaScript function that can be used for multiple expandable cards in HTML and CSS?

I'm dealing with a situation where I have a list of cards, and I want to be able to expand the content individually when clicking on "more info". Can someone offer advice on how to achieve this using Javascript? Check out this CodePen for reference: ...

Is it possible to switch states in Angular UI Router without altering the URL?

The feature of multiple nested views in the ui-router is quite convenient as it allows for seamless transitions between different states within an application. Sometimes, there may be a need to modify the URL while navigating through states, while at othe ...

Clear cache folders in the cordova and ionic file systems to free up space

In a mobile app, I need to delete the cached images that are downloaded by a specific user after they log out. For example, if user1 logs in and downloads some images, and then user2 logs in and downloads other images, user2 should not see the images dow ...

Load website content in real-time

My website requires dynamic content to be loaded on user interaction. When a user clicks certain elements on the page, information should be retrieved from a file located in the same directory as the webpage and displayed in a designated <div>. My u ...

Accessing files from the local system using AngularJS

During my time working with RequireJS and Backbone, I utilized requirejs/text as well as requirejs-plugins to load local json files that were typically used for configuration purposes. With AngularJS, how can one achieve the same functionality? Many sugg ...

Issue with Alignment of Border in PDF [Example Included]

I am currently developing a straightforward react application with very minimal content. index.js: <div className="App"> <div id="printable-div"> <h1>Generate PDF</h1> <p>Capture a screenshot of ...

Only trigger the function for a single bootstrap modal out of three on the current page

I'm facing a challenge on a page where I have 3 bootstrap modals and I need to trigger a function only for one modal while excluding the other two. $("body").on("shown.bs.modal", function() { alert('modal Open'); //this alert should ...

Koa and Stripe are patiently holding off on displaying the page

My current setup involves using koa and stripe for processing a one-time payment. Although the functionality is there, I'm facing an issue where the page renders before the 'data' assignment takes place. This results in the 'id' sh ...

Is Ember CLI experiencing issues due to the latest Ember Data update?

Greetings! I am a beginner with Ember and recently encountered some warnings after upgrading to the latest version of Ember Data: Update: I have two identical versions of my app, one built without ember-cli and the other with ember cli. Both applications ...