Twitter bootstrap typeahead selection does not update model

5,951 views
Skip to first unread message

mcarl....@googlemail.com

unread,
Jun 19, 2012, 9:40:21 AM6/19/12
to ang...@googlegroups.com
Hello,

I'm a newbie at angularJS and so far I like it. But actually I'm spending plenty of time getting an autocomplete / typeahead input field based on twitter bootstrap to work.

The problem I have is that the model did not get updated automatically. See http://jsfiddle.net/NjF8E/ - I had to add that nasty listener on 'blur' including the 'setTimeout' function to get it work. I believe that this is NOT the way to go. So I would be thankful if one of you can point me to the right path.


Thanks

MC

mcarl....@googlemail.com

unread,
Jun 20, 2012, 4:34:52 AM6/20/12
to ang...@googlegroups.com
@Eddie: Can you provide some more details - e.g. posting a code snippet. Would be great! Thanks!

Am Dienstag, 19. Juni 2012 18:50:09 UTC+2 schrieb Eddie Huang:
I had to subclass typeahead to fire a onSelect method, which then accepts a callback and then calls $scope.$apply()

Max Martinsson

unread,
Sep 13, 2012, 4:49:12 AM9/13/12
to ang...@googlegroups.com, mcarl....@googlemail.com
From what I can see, this is due to AngularJS listening for the 'input' event instead of 'change'. If you modify typeahead to trigger the input event ( .trigger('input') ) it will work.

Not sure how to solve best it without modifying bootstrap or angular though..

Roy Choo

unread,
Sep 17, 2012, 4:40:24 AM9/17/12
to ang...@googlegroups.com
Hmmm.. created this in one of the threads

http://jsfiddle.net/roychoo/kEKhT/3/

Can't really find the port over typeahead plugin in the angular-ui

or did i miss it?

Regards
Roy

On Thursday, 13 September 2012 17:38:52 UTC+8, ProLoser wrote:

Have you tried select2 yet? This sort of problem has already been addressed in it. Also, ui-jq has a fix for this behavior.

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en.
 
 

Roy Choo

unread,
Sep 17, 2012, 5:18:07 AM9/17/12
to ang...@googlegroups.com
Sorry about it.

It is actually a combobox with a autocomplete feature.

nice!

http://angular-ui.github.com/

Michael Borisov

unread,
Oct 4, 2012, 11:44:54 AM10/4/12
to ang...@googlegroups.com, mcarl....@googlemail.com
This is actually a common problem, the same behavior you have when use jQuery.datepicker or any other jQuery plugin.
This is my implementation for typeahead:

    directive('inputTypeahead', function () {
        return {
            require: 'ngModel',
            restrict: 'E',
            replace: true,
            transclude: false,
            template: '<input type="text" maxlength="20" ng:maxlength="20" />',
            link: function ($scope, iElement, iAttrs, controller) {
                iElement.typeahead({
                    source: function (query, process) {
                        process(['item1', 'item2']);
                    }
                });
                iElement.on('change', function () {
                    $scope.$apply(function() {
                        controller.$setViewValue(iElement.val());
                    });
                });
            }
        };
    })

As a bonus datepicker directive implementation:

    directive('inputDate', function () {
        return {
            require: 'ngModel',
            restrict: 'E',
            replace: true,
            transclude: false,
            template: '<span></span>',
            link: function ($scope, iElement, iAttrs, controller) {
                controller.$render = function () {
                    if (controller.$viewValue === undefined) {
                        controller.$setViewValue(new Date());
                    }
                    iElement.datepicker("setDate", new Date(controller.$viewValue));
                };
                $(iElement).datepicker({
                    onSelect: function () {
                        $scope.$apply(function () {
                            controller.$setViewValue(iElement.datepicker("getDate"));
                        });
                    }
                });
            }
        };
    }).

stev...@gmail.com

unread,
Nov 7, 2012, 5:04:57 PM11/7/12
to ang...@googlegroups.com
Roy and whoever else might be interested,

I ended up using your type-ahead directive as a starting point and updated it so that the source of words for the auto-complete functionality could be changed. Thanks for sharing it!


-Steve

Mike Brennan

unread,
Feb 19, 2013, 3:28:44 PM2/19/13
to ang...@googlegroups.com, mcarl....@googlemail.com
I used a combination of things from this thread to work out a solution for what I needed.  In my case, I wanted the typeahead field to have the ID value of the item stored on the model as well.  IE, I had a table and wanted people to perform application name lookups, but store the ID for that application on a different model field.  I'm only posting to help anyone else who might be looking into this type of behavior.  I didn't use the angular-ui directive as I didn't want the field to behave like a dropdown if you were tabbing across fields.

This is the HTML:

<tr ng-repeat="item in related_data.decrease" ng-class="{warning: item._action}">
<td>
<input placeholder="account..." type="text" ng-model="item.account" typeahead="accountTypeaheadFunction()"  parent="item" key-field="application_id" key-field-target="accountID" class="typeahead-query">
</td>
</tr>

This is the JS code in your controller: [note that I have a custom entity service, so you'd stick whatever you want in there to get the data...]

$scope.accountTypeaheadFunction = function() { 
return {
source: function (query, process, event) {
$q.all([
Entity['applications'].query({application_name: '%' + query + '%'}).$q
]).then(function(results) {
objects = [];
map = {};
if( results[0].data.rows ) {
$.each(results[0].data.rows, function (i, accountData) {
map[accountData.application_name] = accountData;
objects.push(accountData.application_name);
});
process(objects);
});
}
}
};


Directive:
configModule.directive('typeahead', function($q, Entity) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, model) {

// Defaults for all type aheads
var defaults = {
updater: function (item ) {
return item;
},
matcher: function (item) {
if (item.toLowerCase().indexOf(this.query.trim().toLowerCase()) != -1) {
return true;
}
},
sorter: function (items) {
   return items.sort();
},
highlighter: function (item) {
var regex = new RegExp( '(' + this.query + ')', 'gi' );
return item.replace( regex, "<strong>$1</strong>" );
}
};
// merge the defaults with the passed in source data function
var combinedData = $.extend({}, defaults, scope.$eval(attrs.typeahead));
            element.typeahead( combinedData);
            
element.on('change', function() {
if( attrs.hasOwnProperty('parent') ) {
parent = scope.$eval(attrs.parent);
if( map[element.val()] ) {
parent[ attrs.keyFieldTarget ] = map[element.val()][ attrs.keyField ];
} else {
parent[ attrs.keyFieldTarget ] = "";
}
}
// Update the model/view
scope.$apply(function() {
                    model.$setViewValue(element.val());
                });
                
            });
        }
    };
});




Lowell Bander

unread,
Dec 19, 2013, 3:48:01 AM12/19/13
to ang...@googlegroups.com, mcarl....@googlemail.com
any chance this has been u[dated? let me know! :D

Mauro Servienti

unread,
Dec 19, 2013, 4:03:58 AM12/19/13
to ang...@googlegroups.com, mcarl....@googlemail.com
We started from that and build a brand new one from scratch with support for promises and tags-input.
It is not perfect at all and misses some features I've not yet found time to add.
The source is here: http://radical.codeplex.com

There is also a small sample app

.m

Sent from my Amazing Yellow Lumia, typos are guaranteed ;-)

From: Lowell Bander
Sent: ‎19/‎12/‎2013 09.48
To: ang...@googlegroups.com
Cc: mcarl....@googlemail.com
Subject: [AngularJS] Re: Twitter bootstrap typeahead selection does not update model

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.

To post to this group, send email to ang...@googlegroups.com.

Lowell Bander

unread,
Dec 19, 2013, 4:10:29 AM12/19/13
to ang...@googlegroups.com

(Man oh man, thank you for the speedy response!)

On Dec 19, 2013 1:04 AM, "Mauro Servienti" <ma...@topics.it> wrote:
We started from that and build a brand new one from scratch with support for promises and tags-input.
It is not perfect at all and misses some features I've not yet found time to add.
The source is here: http://radical.codeplex.com

There is also a small sample app

.m

Sent from my Amazing Yellow Lumia, typos are guaranteed ;-)

From: Lowell Bander
Sent: 19/12/2013 09.48
Reply all
Reply to author
Forward
Message has been deleted
Message has been deleted
0 new messages