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

Ways to avoid caching statically generated pages without having to enable ISR in Next.js

I'm currently exploring ways to tailor the Cache-Control headers for my NextJS server when delivering pages generated at build time (SSG). The objective is straightforward: since every CDN caches server responses based on their headers, and I want sta ...

Managing Multiple Operations in Angular Firestore

For the past few weeks, I've been grappling with the theory behind this issue. Despite scouring the internet for solutions, I haven't found anything truly helpful. So, I'm turning to the SO community for the first time. In my Firestore data ...

Handling the display of divs using two select elements

I've been pondering this problem for a while now, and I'm starting to believe that there may not be a solution. Essentially, what I am trying to achieve is the ability to select options from two dropdown menus which will then show or hide specifi ...

The overflow hidden property does not seem to be effective when used in conjunction with parallax

The issue arises when I attempt to use the overflow hidden property in combination with parallax scrolling. Although everything seems to be working correctly with JavaScript for parallax scrolling, setting the overflow to hidden does not contain the image ...

The dilemma between Nuxt Js global CSS and Local CSS

Currently, I am in the process of developing a Nuxt application utilizing an admin template. While I am well-versed in Vue.js, I am finding the aspect of loading assets within Nuxt.js to be a bit perplexing. I am in the process of converting the admin temp ...

Role Based Routing in React allows for different paths and components

I am currently working on a project involving React and I need to implement different routes for admin and driver roles. I have two separate route objects for each role's claims. I am retrieving the user's role from an API and I want to display t ...

"Implementing a sorting feature in a product filtering system with JavaScript/Vue, allowing

I have a dataset structured like this: > Price : ["800000","989000","780000","349000"] If the user selects 'sort by lowest price', I want the data to be arranged from the lowest price to the highest price as follows: > Price : ["349000" ...

Checking to see if all the users mentioned in the message have been assigned a role

Hello everyone, I'm new to asking questions here so please bear with me. I am trying to retrieve all the users mentioned in a message and check if any of them have a specific role, such as the staff role. Thank you for your help! Edit: Here is the ...

Exploring Vue Slots: A guide to parsing and rendering slot components

Currently facing a challenge while developing a web page using Vue, specifically with parsing and rendering the child components inside the <slot>. I need to extract the slot content, convert it into an array of components, and display these compo ...

Automatically Populate Text Field with the URL of the Current Page

I am hoping to automatically fill a hidden text field with the URL of the current page so that I can keep track of where form submissions are coming from. This simple solution will help me streamline my inquiry responses and save time. To clarify, upon lo ...

Node.js with ejs supports the inclusion of partials, but sometimes struggles to locate the variable that has been defined in the partial file

This is the code that should be included in the main ejs file: <% const IDP_URL = "http://idp.com:8082"; const SP_ID = "testing"; const SP_SECRET = "XRRpYIoMtaJC8hFLfUN7Bw=="; const TOKEN_VERIFY_FAIL_URL ="/exsignon/sso/token_verify_fail.ejs"; const L ...

"Pressing the 'back' button on your browser takes

Is there a way to navigate back to the main page by clicking on an image? After selecting First, Picture1 will be shown. How can I go back to the selection page for further choices? <a href="picture1.jpg"> <h3>First</h3></a> <a ...

Arranging xCharts based on the weekday order

Struggling with xCharts, specifically trying to display a bar chart showing numbers with corresponding days of the week in order. Despite my efforts, I can't seem to get them to appear in the correct sequence. Refer to the image below for reference: ...

Navigate through a JSON data structure containing nested arrays

Does anyone know an effective way to loop through a JSON object that contains two or more nested arrays? The goal is to extract the values from each array without including key-value pairs in the output. {"Obj": ["array 0", ["nested array 1"], ...

An issue arises when attempting to utilize the 'push()' method to append a string to a JSON array

I am looking to append strings to my JSON file structure shown below: { "items": [] } To achieve this, I have the requirement of using the following code: var items = require("../../config/item.json"); The approach I am taking is ...

When React object state remains unchanged, the page does not update automatically

i have a state object with checkboxes: const [checkboxarray_final, setCheckboxarray_final] = useState({ 2: ",4,,5,", 9: ",1,", }); i'm working on enabling check/uncheck functionality for multiple checkboxes: these are ...

Tips for extracting tables from a document using Node.js

When converting an XML document to JSON using the xml-js library, one of the attributes includes HTML markup. After parsing, I end up with JSON that contains HTML within the "description":"_text": field. { "name": { ...

How to verify that the user is using the most up-to-date version of the application in React Native

Currently, I am focused on the application and have implemented API endpoints that return the latest version along with information on whether the update is mandatory. Within the application flow, a GET request is sent to these API endpoints to check the ...

The function onClick does not function properly when used with the <p> element, but it works flawlessly with the <button> element

export function SignoutButton() { return ( <p onClick={() => signOut({ callbackUrl: "/" })}> <IoIosLogOut /> Logout </p> ); } I was struggling with a function in my next.js project that wasn't wo ...

Jade incorporates a template that is dependent on a variable

Is there a way to incorporate a template that is dynamically named based on a variable? For example: include= variableTemplateName ...