modify the values of directive elements using a templateUrl

HTML Template:

I have an element in the template file seats.tpl.html like this:

<select  id="guest_table">
    <option tables="emptySeats"
            ng-repeat="table in emptySeats" value="{{table.tableId}}">{{table.tableNumber}}</option>
</select>

Controller:

In the controller, I use a factory to retrieve values from the database. I then load the results into the $scope.emptySeats array, which is used in the template with ng-repeat to display the data:

factP3_GetEmptyChairs.getEmptyChairs({'data': {'id': 58}})
                .then(function (result) {
                    **$scope.emptySeats = result.data;**
                    $log.info("Empty chairs list loaded.");
                },
                function (result) {
                    $('.loading').hide();
                    $log.error("Error: we could not get Empty seats list.");
                });

Directive:

In my directive, I utilize the parameter templateUrl to load the template file and display the select element. However, I am facing an issue where the values are not updating automatically when the $scope.emptySeats array changes:

.directive('emptySeats',function(){
        return {
            restrict: 'AE',
            replace: true,
            scope:{tables :'='},
            templateUrl: function(){
                return 'assets/modules/part3/templates/emptySeats.tpl.html';
            },

            link:function(scope, element, attrs) {                                                                           
                //bind change on element
                element.bind('change', function() {
                    alert("table changed");
                });

            }
        }

The problem arises when the $scope.emptySeats array values are updated and do not reflect in the select element. Is there something missing in the directive such as compile, observe, or ngmodel? Can anyone provide assistance?

UPDATE: I implemented a function to fetch new data from the database and update the select element accordingly.

 $scope.onClickHall = function (hall) {
    var tmp = [];
    //call service to load empty Seats
    factP3_GetEmptyChairs.getEmptyChairs({'data': {'id': $scope.currentHall}})
        .then(function (result) {
            //$scope.emptySeats = result.data;

A: If I use $apply here, I encounter the error: $rootScope:inprog Action Already In Progress

        $scope.$apply(function () {
                $scope.emptySeats = result.data;;
            });
            tmp = result.data; //I use a temporary array to pass it on timeout

            $log.info("Empty chairs list loaded.");
        },
        function (result) {
            $('.loading').hide();
            $log.error("Error: we could not get Empty seats list.");
        });

B. If I use $timeout function and try to change the data, nothing happens

    $timeout(function() {
        $scope.$apply(function () {
            $scope.emptySeats = tmp;
        });
    }, 10);
}

Answer №1

To enhance the capabilities of bootstrap popovers, tooltips, and more, it is recommended to use template files. There are two types of templates that can be utilized for this purpose.

  • Inline templates - The template code is defined within the same HTML file and called using an angular directive.
    Example:

    <script type="text/ng-template" id="myTemplate.html">
       <h1>Hi</h1>
    </script>
    

  • Template contents can also be placed in an external file and fetched via an ajax request. In such cases, an ajax call similar to $http.get(templateURL) may be necessary.

  • The directive should be defined as shown below in order to correctly attach the template. Note the use of $compile to ensure proper integration of contents with your directive.

    Below is an illustrative example.

    angular.module('myApp')
          .directive('myPopover', function () {
            var getTemplate = function () {
                var template = '';
                    template = $templateCache.get("myTemplate.html");
                }
                return template;
            };
    
        return {
          restrict: 'A',
          transclude: true,
          scope: {
            text: '@myPopover'
          },
          link: function(scope, element, attrs) {
                var popOverContent = getTemplate();
                popOverContent = $compile("<div>" + popOverContent+"</div>")(scope);
    
                var options = {
                    //title       : title,
                    content     : popOverContent,
                    placement   : "right",
                    html        : true,
                    date        : scope.date,
                    trigger     : "hover"
                };
                $(element).popover(options);
          }
        };
      });
    

    You can view a working demo on Plunker.

    Answer №2

    To ensure that your $http call functions properly, you must invoke $scope.$apply in order to initiate the $digest cycle and refresh the directive's view:

    $scope.$apply(function () {
       $scope.availableItems = result.data;
    });
    

    The purpose of $apply() is to run an expression within Angular from external sources (such as DOM events, setTimeout, XHR requests, or third-party libraries).

    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

    What is the best way to implement form fields that have varying validation patterns based on different conditions?

    Currently, my focus is on developing a form that prompts the user to choose between "USA" or "International" via radio buttons. The input field for telephone numbers should then adapt its requirements based on the selected country - either a 10-digit US nu ...

    The process of filtering and outputting JSON data in JavaScript or jQuery

    There is JSON data available for review. var data = [{ "gender": "male", "name": { "first": "rubween", "last": "dean" } }, { "gender": "male", "name": { "first": "rubween", "last": "dean" } }, { ...

    Encountering problem on Heroku: Bower resolver is missing

    Are you familiar with the concept of Javascript fatigue? I have recently become aware of it. Although I am not a javascript developer, I use Node and Angular for a side project on my server. All my node packages are installed using npm and my angular pa ...

    I am currently working on developing an HTML and JavaScript audio player that can play audio at specific scheduled times

    Looking to create a custom HTML/JavaScript audio player that adjusts playback based on the time of day. For instance, if it's 1:00 pm, the file will start playing from 0:00 minutes; and if it's 1:01 pm, the file will begin playing from 1:00 minut ...

    Activate the drop-down division when the search box is in focus with xoxco technology

    Currently, I am incorporating Xoxco's tag input plugin which can be found at the following link: In my customization, I have implemented JQuery's focus() function <input id="tags_1" class="tag-holder" type="text" class="tags" /></p> ...

    Is there a way to iterate through this?

    I have data that I need to loop over in JavaScript. Since it is not an array, the map function is not working. Can someone help me loop over it or convert it into an array so that I can iterate through it? { "7/15/2021": { "date": ...

    In Chrome version 69.0.3497.100, material design does not display dynamic elements off the screen

    STACK: react: 16.8.6 redux: 4.0.1 DESCRIPTION: When using $compile to dynamically add elements on a page, I encountered an issue in Firefox (76.0) where input elements that are out of the screen are not rendered. Only the labels are displayed. view image ...

    When I try to reverse the words in a string, I am not receiving the desired order

    Currently delving into TypeScript, I have set myself the task of crafting a function that takes in a string parameter and reverses each word within the string. Here is what I aim to achieve with my output: "This is an example!" ==> "sihT ...

    Utilize the skipAuthorization feature when making requests with Restangular to bypass the authorization

    Currently, I am using Satellizer to manage authentication on my application. By default, Satellizer intercepts all requests and includes the Authorization header. While I use Restangular for all API calls, I do not want the Authorization header to be inclu ...

    What steps can I take to troubleshoot the cause of my browser freezing when I try to navigate to a different webpage

    Within this div, users can click on the following code: <div id="generate2_pos" onclick="damperdesign_payload();" class="button">Generate P-Spectra</div> Upon clicking, the damperdesign_payload() function is triggered, leading to a link to an ...

    transferring information between controllers and saving it persistently in AngularJS even after refreshing the

    What is the best way to share data (Object) between controllers with different routes and prevent data loss after a page reload? I have an object that I need to use to prefill form values on my destination page based on choices made on my source page. S ...

    Issue with ng-pattern validation not functioning correctly on textarea in AngularJS

    Attempting to validate a textarea that, if valid, will enable a specific button. Utilizing ngPattern for validation but encountering issues with implementation. Referencing the example code below: <div ng-app="test"> <form name="theForm" ng-contr ...

    Tips for refreshing only a portion of a webpage using JavaScript/jQuery

    I have two distinct navigational sections on my website. The left column has its own navigation menu, while the right column (main content area) contains a separate set of links: My goal is to click on a link in the left-hand sidebar (such as "Resume", "E ...

    Leveraging server-sent events to retrieve an array from a MySQL database using PHP

    I've been attempting to implement server-sent events in order to fetch data from a database and dynamically update my HTML page whenever a new message is received. Here's the code I'm using: function update() { if(typeof(Event ...

    Refreshing express-session sessions

    My goal is to enhance the user experience by retrieving their profile from the mongodb database when they visit the page, and then updating their session with this information. Currently, I am utilizing the following packages for managing sessions: - ex ...

    Transforming functions with dependencies into asynchronous operations with the help of promises

    Can I convert both of my functions into asynchronous functions, even though one function relies on the other? Is it feasible for function b to execute only after function a? ...

    Transfering information to handlebars in node.js

    Being a beginner in node.js, I am currently working on making a get request in my router (index.js). After successfully obtaining the desired result (verified by logging it in console.log), I proceed to parse it into a JSON object and pass it to a render f ...

    Combining platform-express and platform-fastify for optimal performance

    I am currently working on a NestJS application and my goal is to upload files using the package @types/multer. However, I encountered an issue while following the guidelines from the official documentation: https://i.sstatic.net/JCX1B.png Upon starting ...

    What is the best way to group all matched objects from an array based on multiple keys?

    const data = [ { amount:10, gameId:7 , consoleId:3, id: 1 }, { amount:5, gameId:18 ,consoleId:3, id: 2 }, { amount:5, gameId:18 ,consoleId:3, id: 3 }, { amount:10, gameId:7 ,consoleId:3, id: 4 ...

    Utilizing the datepicker options function within a different function

    I'm working on a function that utilizes a promise to retrieve data from an asynchronous ajax call: $("#mySelect").on('change', function() { var mySelectValue = $('#mySelect').val(); var promise = getAvailableDates(mySe ...