Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't my ng-model update with Typeahead in Firefox?

In a website I'm building with AngularJS I've got an input with a typeahead below for which I use angular-typeahead. It works fine in Chrome, Opera and Safari but not in Firefox. The problem seems to be that in Firefox the model isn't updating when I click the typeahead suggestion.

My html looks like this:

<input class="typeahead" sf-typeahead type="text" datasets="userDataset" ng-model="searchUser" >
<button ng-click="sendToUser(searchUser.id)" class="btn">Send</button>

and in my controller I have this simple function:

$scope.sendToUser = function(userId){
    console.log(userId);
    // More code here..
}

In Chrome, Opera and Safari it logs an int for the userId, but in Firefox it just logs undefined.

I made a plunker for it here to show what I mean (search for "one", or "two").

It works in Chrome, Opera and Safari, but in Firefox it somehow shows undefined in the console. The extra weird thing is that it only shows undefined the first time. If you select something a second time it does work.

Does anybody know why this doesn't work in Firefox, and most importantly, how I can solve it? All tips are welcome!

like image 242
kramer65 Avatar asked Sep 28 '22 14:09

kramer65


1 Answers

This was an interesting Dilemma.

  • the TypeAhead sets the ng-model value to an object once selected

  • Upon any event (like click) that runs the digest cycle, the framework enforces the ng-model binding,assigning the model value a string bound to the input.

  • FireFox, unlike Chrome seems to enforce this behavior. Chrome inputs probably allow for object value setting (just a guess).


The work around is to change your output binding:

<input class="typeahead" sf-typeahead type="text"  datasets="userDataset" 
outputval="searchUser" ng-model="a" options="exampleOptions">

The outputval is our expected value. I bound to a random scope variable a because the directive expects and uses a model binding.

Inside the directive, I changed the updateScope function to set the selected value to scope.outputval and commented out the assignment to Model.

    function updateScope (object, suggestion, dataset) {
      scope.$apply(function () {
        var newViewValue = (angular.isDefined(scope.suggestionKey)) ?
            suggestion[scope.suggestionKey] : suggestion;
        console.log(newViewValue);    
        //ngModel.$setViewValue(newViewValue);
        scope.outputval = newViewValue;
      });
    }

Try my Plunker!

like image 190
Dave Alperovich Avatar answered Oct 06 '22 22:10

Dave Alperovich