Observing input value in Popover Template with Angular UI

I am currently working on a directive that utilizes the Angular Bootstrap Popover and includes an input field. Everything seems to be functioning properly, except for the fact that the watch function is not being triggered.

For reference, you can view the code on Plunker.

The structure of the directive is as follows:

angular.module('ngUserPopover', ['ui.bootstrap'])
.directive('userPopover', function() {
    return {
        restrict: 'E',
        scope: {
            onSearch: '&',
        },
        templateUrl: 'myPopoverTemplate.html',
        link: function (scope, element, attr) {

            scope.templateUrl = 'someTemplate.html'; // URL for popover content template
            scope.searchText = 'Type something'; // Initial value example for input

            scope.$watch(function () {
                return scope.searchText;
            }, function () {
                // Pass the new input value in the method...
                console.log(scope.searchText);
            });
        }
    }
});

The content of myPopoverTemplate.html is as follows:

<button uib-popover-template="templateUrl" popover-placement="right" popover-trigger="click" class="btn btn-default">Popover With Template</button>

<script id="someTemplate.html" type="text/ng-template">
    <div>{{dynamicPopover.content}}</div>
    <div class="form-group">
      <input type="text" ng-model="searchText" class="form-control">
    </div>
</script>

The button uses the Angular Bootstrap UI popover directive with a custom template (someTemplate.html).

An anomaly occurs where the input field inside the popover initially displays the value defined in the searchText variable of my directive's scope (which is 'Type something'). The watch function is executed once (as shown in the browser console), but it does not trigger again when the input value is modified.

Despite utilizing the angular bootstrap directive, the $watch function associated with the scope variable used for the ng-model of the input field is not functioning as expected (the console.log statement fails to execute upon editing the input value).

Any suggestions or insights would be greatly appreciated?

Answer №1

This particular issue stems from the classic JS prototype inheritance problem. A solution is to ensure that your ngModel is an object rather than a primitive, like this:

scope.model = {
  searchText: 'Type something'
};

scope.$watch(function() {
    return scope.model.searchText;
  }, 
  function () {
    // include the new input value in the method...
    console.log(scope.model.searchText);
});

Next, update your input's ng-model:

<input type="text" ng-model="model.searchText"/>

https://plnkr.co/edit/ocRBhNWLYUJ9hLE30U45?p=preview

If you're striving for cleaner code, consider using a controller instead of the link function to manage your directive's logic. This way, you won't have to worry about the object versus primitive dilemma. Additionally, utilizing ngChange instead of a watcher can be another enhancement for handling input changes:

 link: function (scope, element, attr) {
   scope.templateUrl = 'someTemplate.html';
 },
 controllerAs: '$ctrl',
 controller: function($scope) {
   var $ctrl = this;
   $ctrl.searchText = 'Type something';

   $ctrl.inputChanged = inputChanged;

   function inputChanged() {
     console.log($ctrl.searchText);
   }
}

Template:

<input type="text" 
  ng-model="$ctrl.searchText" 
  ng-change="$ctrl.inputChanged()"
  class="form-control">

https://plnkr.co/edit/OfhoxXYCbf7AFYiAd5zL?p=preview

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

Begin counting starting from 1 all the way up to 24, then feel free

I've developed a counter that increments from 0 to 24, and once it reaches 24: setInterval(function(){DayAndNight()}, 1000); var iState = 12; function DayAndNight() { //console.log('test'); switch(iState) ...

javascript calculate average based on user input array

There is a problem that I am trying to solve, but as a beginner it seems quite challenging. Here is the code I have written so far, however, when I run it only one window appears. Any advice or guidance would be greatly appreciated. var years = prompt(" ...

Using Symfony2 to send AJAX request data to a form rendering controller

I am facing an issue with a Symfony Form that I need to prefill based on the previously viewed record. The goal is to provide a way to modify the record data. I reach the form page through javascript and send an ajax request to the controller responsible f ...

Oops! We encountered an issue trying to find the "list" view in the views directory

Here are the images I have: This is the code for my app.js file And this is the code for list.ejs located in the views directory Unfortunately, my index.html file is empty. Below is the full error log: Error: Failed to lookup view "list" in the views di ...

Unlocking the TypeScript UMD global type definition: A step-by-step guide

I have incorporated three@^0.103.0 into my project, along with its own type definitions. Within my project's src/global.d.ts, I have the following: import * as _THREE from 'three' declare global { const THREE: typeof _THREE } Additio ...

Instructions on converting a SQL expression to Sequelize

Could someone assist with converting this to sequelize? CREATE TABLE "fundraiserUpdates" ( "updateId" SERIAL, "updateFundraiserId" INTEGER NOT NULL, "updateTitle" TEXT NOT NULL, "updateDescription" TEXT NOT NULL, CONSTRAINT "pk_fundraiser ...

Tally up identical words without considering differences in capitalization or extra spaces

Let's take an example with different variations of the word "themselves" like "themselves", "Themselves", or " THEMSelveS " (notice the leading and trailing spaces), all should be considered as one count for themselves: 3 ...

"Encountered a Chrome RangeError: The call stack size limit was exceeded while utilizing jQuery's $

As part of my job, I am currently evaluating a web application that involves fetching a substantial amount of data from the server. The data is received as a JSON object using the $.ajax function. It contains numerous sub-objects which I convert into array ...

JQuery is unable to validate a form that is being loaded from an external HTML file

I'm encountering an issue where my form imported into a separate HTML file is not validating using JQuery's $(form).validate() plugin. After following the guidance provided in this question, I successfully managed to get the form working. Howeve ...

The javascript function ceases to operate once the div is refreshed

$(function() { $(".reqdeb").click(function() { console.log("Functioning properly"); var req_id = $(this).attr("id"); var info = 'id=' + req_id; if (confirm("Confirm deletion of request?")) { $.ajax({ cache : false, ...

What is the most efficient way to save a document in mongoose based on a specific user's

Is there a way to ensure that when saving a template, it is associated with the user id? I have added a reference to the templateSchema for the User. User.model.js var UserSchema = new mongoose.Schema({ _id: { type: String, required: true, index: {uniq ...

What advantages do constant variables offer when selecting DOM elements?

What is the significance of declaring variables as constant when selecting elements from the DOM? Many developers and tutorials often use const form = document.querySelector('form'); ...

"Access denied" error when using Internet Explorer and jQuery

Attempting to make an AJAX call using jQuery's $.post in Internet Explorer is resulting in an error message stating "Permission denied." This peculiar issue only seems to occur when accessing a page after having visited another page. For example, if ...

The React Functional Component undergoes exponential re-renders when there is a change in the array

I'm encountering a problem with one of my functional components. Essentially, it maintains an array of messages in the state; when a new message is received from the server, the state should update by adding that new message to the array. The issue ar ...

Creating multiple nested ng-repeats in an AngularJS table

Managing a large amount of data on users' availability by hour for multiple days can be challenging. The data is structured as follows: availData = { "date1":arrayOfUsers, "date2":arrayOfUsers, ... } arrayOfUsers= [ userArray, userArray, ... ] user ...

Displaying geoJSON data from a variable instead of a file is a feature implemented by

Let's say I have a geoJSON data stored in a variable or parsed as an object: // GeoJSON stored as an object var segment = segment; // GeoJSON saved as a JSON string var json = JSON.stringify(segment); Now, the challenge is to display this geoJSON o ...

javascript identify dissimilarities within arrays

Working on an Angular 2 application and attempting to identify the difference between two arrays (last seven days and missing dates within the last seven days). Everything works fine when initializing the array through a string, like in example code 1. How ...

Can you retrieve data or HTML content from the main Vue 3 component?

I have experience using Vue in previous projects but I'm currently facing some challenges on how to pass information/arguments to a root Vue 3 component. My goal is to set up something like this in my HTML: <div class="nav-app" nav=&quo ...

Incorporate various Vue.js components into the main parent component

I am currently utilizing Vue.js to create a user interface for my HTML5 game. I have a scenario where I want to define UI containers that essentially group other UI components and position them on the screen. Here's an example of what I'd like to ...

Exploring the creation of a dynamic graph with d3.js

I'm new to d3 and attempting to create a graph layout. var w = 1000; var h = 500; var dataset = { nodes: [{ name: 'Alice' }, { name: 'David' ...