AngularJS ng-model not refreshing

One of the features in my application is a Font Awesome icon picker that allows employees to easily access different icons without having to search for their codes online.

However, I am facing an issue where clicking on an icon does not update the ng-model. To trigger the update, I have to enter another character or space for AngularJS to recognize the changes made in the input field.

You can see the problem in action in this gif: .

The code snippet I am using for the icon picker is:

editCellTemplate: function (container, options) {
    container.html('<input class="icon-picker-input edit icp icp-auto" type="text" ng-model="iconInput" /><script>$(".icp-auto").iconpicker();</script>');
    options.setValue($scope.iconInput);
    $compile(container)($scope);
}

I am utilizing a gridview from DevExtreme with a custom editCellTemplate.

If anyone has any insights on how to resolve this issue, your help would be greatly appreciated. Thank you in advance!

Answer №1

The primary issue causing your code to not function as expected is that Angular only monitors user interaction events to update the model. The icon picker you are using bypasses Angular by directly setting the input value.

To update the model, it's necessary to create a hook in the icon picker update process: when an icon is selected, either update the iconInput scope variable manually (enclosed within a $scope.$apply call) or simply trigger the 'input' event on the input element to allow Angular to capture the new value (refer to this reference).

You can try implementing something like this:

editCellTemplate: function (container, options) {
    container.html('<input class="icon-picker-input edit icp icp-auto" type="text" ng-model="iconInput" />');
    options.setValue($scope.iconInput);        
    $compile(container)($scope);

    // Avoid inline script tags, initialize the iconpicker here
    $(".icp-auto").iconpicker();

    // Listen for icon picker selections
    $(".icp-auto").on('iconpickerSelected', function(e) {
        // Trigger the "input changed" event
        $(e.currentTarget).trigger('input');
    });
}

Note that I removed the script tag from the compiled HTML as the icon picker initialization should be done in your main code. Script tags execute in the global context, which may not always be desirable.

Update : The error during compilation mentioned in your comment could be due to JQuery not recognizing the iconPicker() method, possibly because of a missing definition in your Typescript setup. At runtime, the contents of the <script> tag interpreted by Angular are treated as regular Javascript, bypassing Typescript type checking.

Refer to this solution for enabling additional methods on the JQuery interface. It is advisable to avoid placing logic inside compiled <script> elements to prevent potential issues down the line.

Answer №2

The issue you're facing is that iconpicker() updates the input without Angular recognizing the change. To resolve this, simply insert $scope.$apply() right after the function call. The problem lies in the unconventional method of including your script. The jQuery syntax you're using will only trigger the iconpicker() for the first matched element, so modifying the second row in your demo might not have the desired effect.

Instead, create a unique ID and implement the following approach:

editCellTemplate: function (container, options) {
    container.html('<input class="icon-picker-input edit icp icp-auto"' +
      ' type="text" ng-model="iconInput" id="uniqueID"/>' +
      '<script>$("#uniqueID").iconpicker();$scope.$apply();</script>');
    options.setValue($scope.iconInput);
    $compile(container)($scope);
}

...where uniqueID should be replaced with an actual unique identifier. That task is left for you to tackle.

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

URL not passing on variable

Here is the code I have for a basic 'change email' script. I'm currently struggling to get it working and can't figure out what's wrong. <?php if (isset($_GET['u'])) { $u = $_GET['u']; } if (isset($_POS ...

Enhancing an existing Angular1 project to Angular4 while incorporating CSS, Bootstrap, and HTML enhancements

Facing CSS Issues in AngularJs to Angular4 MigrationCurrently in the process of upgrading an AngularJS project to Angular 4, specifically focusing on updating views. However, encountering issues with certain views not displaying the custom CSS from the the ...

What are the available events offered by Express websockets?

I am interested in learning about the different websocket events available. Currently, I have only used the ws.on('message') event, but I would like to find out how to detect when the connection is established and closed. I attempted to add the w ...

What is the best way to maintain a Tampermonkey script within Selenium?

I'm trying to execute a JavaScript script before the page loads, so I've placed it in Tampermonkey. However, the script doesn't persist after closing the driver. Whenever I run the code again, the saved script is no longer there. This code u ...

Here are some steps for generating a non-integer random number that is not in the format of 1.2321312312

I am looking to create random numbers that are not integers, for example 2.45, 2.69, 4.52, with a maximum of two decimal places. Currently, the generated number includes many decimal places like 2.213123123123 but I would like it to be displayed as 2.21. ...

Error: AngularJS form validation is not working properly

I've been following the AngularJS documentation, but I'm having trouble with my validations. The error messages are not showing up and the minimum length restrictions for the form fields are not working: <form name="callbackForm" ng-submit="r ...

An unexpected error occurred while attempting to retrieve data from Firebase and display it in another component

An error occurred: Unhandled Runtime Error Error: Element type is invalid - expected a string (for built-in components) or a class/function (for composite components) but got undefined. This could be due to forgetting to export your component from the defi ...

Issue with Socket.io connection event failing to trigger

Having recently delved into the world of socket.io, I followed the provided documentation and watched several tutorials on YouTube to set up a basic functionality. My goal was to see "New socket connection" logged in the console when I visit the index page ...

Utilizing Cowboy as the HTTP web server for Express JS

Many websites are utilizing Cowboy as the HTTP Web server and Express JS as the Web application server. They typically have their HTTP header set to Cowboy for the server, with the X-Powered-By HTTP header indicating Express. One example is This setup rai ...

Send the DOM element to a processing function within AngularJS

In this code snippet, there is an attempt to pass a table cell (as a DOM object) to a function. However, it seems that the reference of 'this' does not point to the DOM object for the table cell, but rather to '$scope'. Any suggestions ...

What is the best way to use multiple encoding types when sending data via a POST method in Node.js?

My current challenge involves sending a combination of name and description text data alongside a video file. Unfortunately, I've encountered an issue where I can only send either the video or the text, but not both simultaneously. Below is the code ...

Using npm-installed cesium for the web browser is a straightforward process that involves importing

Exciting news - Cesium is now available on npm! Once I've run npm install cesium in my project, all the codes are placed inside the node_modules folder. In the introductory hello world example of Cesium, it imports cesium similar to this: <script ...

What is the best way to create a timer using JavaScript?

I'm looking for a reverse timer to track session timeout. I found a code on codepen that works as a clockwise timer, but my attempts to make it counterclockwise have failed. Can someone please suggest a solution? I want the timeout to be either 1 hour ...

Having difficulty generating dynamic rows and tree dropdowns in AngularJS

Struggling to implement dynamic row functionality with Angular JS. The rows are working well, but I also need to incorporate a tree dropdown within each row. Unfortunately, clicking the "add row" button populates the same data in all rows. I have shared m ...

Differentiate the items within a list containing identical divs using JavaScript

Currently, I am expanding my knowledge in HTML, CSS, and JS by incorporating Angular and JQuery. In one of my projects, there is a div labeled "eventBoxes" where multiple divs known as "eventBox" can be added. I have created a template for the eventBox i ...

Conceal an element if the angular attribute does not contain any value

Currently, I am facing an issue with an image element in my project. The path for this image is being fetched from an attribute present on my angular object. However, if this imagePath attribute is empty, a broken image is displayed. I want to avoid rend ...

combine and refresh identical items within an array

Currently, I am in the process of creating a prototype for an item-list and a shopping-cart. Both components function as standalone entities but are connected through a vuex-store. The item-list contains various elements that can be added to the shopping-c ...

"An error message stating 'Express: The body is not defined when

I'm encountering an issue while trying to extract data from a post request using express. Despite creating the request in Postman, the req.body appears empty (console.log displays 'req {}'). I have attempted various solutions and consulted s ...

Tips for assigning unique names to each radio input groupNeed to assign unique names to radio

Currently, I am seeking a dynamic solution to alter the name associated with a set of radio input buttons. The situation involves creating a travel itinerary where users can choose between "domestic" and "international." Based on this selection, the corre ...

Assign an array value to the input based on the selection made in Javascript

After finding a lot of useful information in previous questions, I am struggling to get the last piece that I need. My PHP code helps me loop through form fields and assign unique names to each field using a variable. One of these fields is for "expense ty ...