web-dev-qa-db-fra.com

AngularJS BootstrapUI Typeahead avec objet et fonctionnalité de sélection

J'essaie d'implémenter une tête de frappe dans Angular using http://angular-ui.github.io/bootstrap/ , où le champ typeahead affiche les adresses complètes mais une fois cliqué, un autre champ est rempli avec uniquement le code postal pour cette adresse. J'essaie d'utiliser ng-change ou ng-click pour cela, mais sans succès.

http://jsfiddle.net/UxTBB/2/

angular.module('myApp', ['ui.bootstrap'])
    .controller("mainCtrl", function ($scope) {
    $scope.selected = '';
    $scope.states = [{postcode:'B1',address:'Bull ring'},{postcode:'M1',address:'Manchester'}];
    $scope.setPcode = function(site) {
        $scope.selPcode = site.postcode;
        };
});

<div class="container">
    <div ng-controller="mainCtrl" class="row-fluid">
        <form class="row-fluid">
            <div class="container-fluid">
                postcode <input type="text" ng-model="selPcode" />
                typeahead <input type="text"  ng-change="setPcode(site)" ng-model="selected" typeahead="state.address for state in states | filter:$viewValue" />
            </div>
        </form>
    </div>
</div>

Des idées?

31
stampeder

La directive typeahead de http://angular-ui.github.io/bootstrap/ est très, très flexible et il existe de nombreuses façons d'obtenir la fonctionnalité souhaitée. J'en présente 2 ici.

Premièrement, la directive typeahead utilise une syntaxe très similaire à la directive AngularJS select . Cela vous donne un contrôle total sur une étiquette affichée et les données liées en tant que valeur de modèle. Donc, ce que vous pourriez faire, c'est simplement afficher l'adresse comme une étiquette et lier directement le code postal au selPcode:

<input type="text" ng-model="selPcode" typeahead="state.postcode as state.address for state in states | filter:$viewValue" typeahead-editable="false" />

La clé ici est la partie as est dans l'expression typeahead: typeahead="state.postcode as state.address for state in states

Veuillez également noter que j'utilise le typeahead-editable="false" attribut pour lier le modèle uniquement lorsqu'une sélection est effectuée. Un jsFiddle fonctionnel ici: http://jsfiddle.net/jLupa/

Une autre solution, si vous avez vraiment besoin d'utiliser une fonction de rappel, est d'utiliser le typeahead-on-select attribut:

<input type="text"  typeahead-on-select="setPcode($item)" ng-model="selected" typeahead="state.address for state in states | filter:$viewValue" />

Il vous permet de spécifier un rappel lorsqu'une correspondance est sélectionnée. Un violon de travail ici: http://jsfiddle.net/t8BV2/

Comme dernière note: ng-change ne fonctionnera pas ici car il réagirait à toute modification de l'entrée pendant que vous souhaitez capturer la sélection uniquement. ng-click n'est pas très utile non plus car il réagit en cliquant sur le champ de saisie et non sur le popup correspondant. En plus de cela, il ne réagirait pas aux sélections effectuées en utilisant keayboard.

100

La grande solution de @ pkozlowski-opensource a un inconvénient: vous ne pouvez pas initialiser la typeahead à partir de la propriété ng-model de cette manière, du moins si vous voulez qu'elle affiche la description de l'article et non son code.

J'ai trouvé un moyen de résoudre ce problème en configurant la frappe comme ceci:

<input type="text" ng-model="selected" typeahead="state as state.address for state in states | filter:$viewValue" />

Cela renvoie un objet d'état à la propriété du modèle qui peut être initialisé en définissant la valeur sur l'objet approprié:

    $scope.selected = {postcode:'M1',address:'Manchester'};

Violon de travail ici: https://jsfiddle.net/0y3ntj4x/3/

Je pense que ce scénario est absent de la documentation angular-bootstrap pour la typeahead.

4
Paul Taylor

Je voulais juste ajouter à la réponse fournie par @ pkozlowski.opensource - le comportement affiché dans jsfiddle.net/jLupa ne fonctionne plus avec la version 0.10.0 du UI-Bootstrap d'Angular. Voir ici: jsfiddle.net/jLupa/87/. La seule modification que j'ai apportée a été la mise à jour vers la version 0.10.0, et vous pouvez voir que les deux zones de saisie sont résolues en code postal.

2
Brian Graham

J'ai un problème similaire,

<input type="text" ng-model="select" typeahead="a as a.Value for a in countries | filter:{{ Value:$viewValue }} "class="form-control" typeahead-editable="false" >

{ Code: AL,ParentCode: null,Value: Albania,Id: 1206,Name: countries }

mais n'a pas fonctionné, avec l'utilisation d'un service de cette façon

$scope.countries = []; _services.getcountries(function(result) { $scope.countries = result; });

et a été résolu avec

$scope.countries = []; _services.getcountries(function(result) { $.each(result, function(i, o) { $scope.countries.Push(o); }); });

J'espère aider quelqu'un

2
Math

Ceci est une autre liste de valeurs de la directive angularjs qui utilise la typeahead de Twitter: https://github.com/mihaigiurgeanu/lov-typeahead . Vous pouvez l'utiliser avec bootstrap, mais aussi sans bootstrap.

Si vous utilisez bower, vous pouvez l'installer en faisant:

bower install lov-typeahead --save
0
Mihai Giurgeanu
try the following before saving / validating 

modelCtrl. $ setValidity ('editable', true);

0
Mohamed.Abdo