La fonctionnalité typeahead de l’interface utilisateur d’AngularJs semble simple et puissante, mais j’essaie de comprendre comment faire correspondre les caractères correspondants. Par exemple, si je tape "A" dans la zone de saisie, j'aimerais voir tous les états qui commencent par "A" et non tous les états qui contiennent un "A" dans le nom. Je recherche depuis deux jours sur ceci et il semble que Angular ait le concept d'un filtre personnalisé qui a un "comparateur". La documentation présente un exemple simple qui ne montre pas la syntaxe exacte pour implémenter un comparateur.
Le code HTML ressemble à ceci:
<div>Selected: <span>{{selected}}</span></div>
<div><input type="text" ng-model="selected" typeahead="name for name in states | filter:selected"></div>
Le javascript de base ressemble à ceci
angular.module('firstChar', ['ui.bootstrap']);
function TypeaheadCtrl($scope) {
$scope.selected = undefined;
$scope.states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Dakota', 'North Carolina', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'];
}
J'ai un plunker ici http://plnkr.co/edit/LT6pAnS8asnpFEd5e6Ri
Le défi consiste donc à faire en sorte que la tête de frappe AngularUI ne corresponde que sur les personnages principaux.
Toute aide ou idée à ce sujet serait extrêmement appréciée.
En fin de compte, votre question n’est pas vraiment spécifique à la directive typeahead
mais elle a plus à voir avec le fonctionnement des filtres AngularJS.
Avant de présenter une solution opérationnelle, veuillez noter que la directive typeahead
utilise beaucoup l’infrastructure AngularJS ($ http, promises) et le langage d’expression. Il est donc important de réaliser que le states | filter:selected
n’est rien de plus qu’une expression AngularJS.
En regardant l'expression ci-dessus, nous devons trouver un moyen de filtrer un tableau pour renvoyer une liste d'éléments correspondants. La seule particularité de la directive typeahead est qu’il existe une variable $viewValue
représentant une valeur entrée par un utilisateur dans la zone de saisie. Nous avons donc simplement besoin de filtrer le tableau states
pour renvoyer les éléments commençant par le $viewValue
.
Il existe de nombreuses façons de le faire, mais puisque vous avez mentionné le comparateur pour les filtres (veuillez noter que ceux-ci n'ont été introduits que dans la version 1.1.x d'AngularJS), il vous faudrait définir une fonction de comparaison qui devrait décider si un élément donné doit être ajouté. retourné dans la liste des résultats ou non. Une telle fonction pourrait ressembler à:
$scope.startsWith = function(state, viewValue) {
return state.substr(0, viewValue.length).toLowerCase() == viewValue.toLowerCase();
}
L’avoir défini l’utilisation est très simple:
typeahead="name for name in states | filter:$viewValue:startsWith"
Voici le travail de travail: http://plnkr.co/edit/WWWEwU4oPxvbN84fmAl0?p=preview
Filtre personnalisé permettant de faire correspondre les caractères principaux dans la zone de saisie semi-automatique.
(function() {
// Create global filters using angular.filter() only. Never use local filters inside
// controllers/services. This enhances testing and reusability.
function xpTypeaheadFilter() {
return function(items, props) {
var out = [];
if (angular.isArray(items)) {
items.forEach(function(item) {
var text = props.toLowerCase();
var itemLoverCase =item.toLowerCase();
var substr = itemLoverCase.substr(0, text.length);
if (substr === text ) {
out.Push(item);
}
});
} else {
// Let the output be the input untouched
out = items;
}
console.log("out lem", out.length);
return out;
};
}
// Pass functions into module methods rather than assigning a callback.
// This helps aid with readability and helps reduced the amount of code "wrapped"
// inside Angular.
angular.module('common')
.filter('xpTypeaheadFilter', xpTypeaheadFilter);
})();
<input type="text" ng-model="vesselName" placeholder="Vessel Name" typeahead="vesselName for vesselName in vesselNames | xpTypeaheadFilter:$viewValue | limitTo:8" class="form-control form-textbox" >
Je viens d'éditer le message marqué comme étant répondu et cela fonctionne lorsque la liste a un ID et un titre à la fois:
<input type="text" ng-model="ledgerstatementModel.Supplier" typeahead="supplier as supplier.Name for supplier in supplierList | filter:{Name:$viewValue}:startsWith" class="form-control">
et en js:
$scope.startsWith = function (supplier, viewValue) {
return supplier.substr(0, viewValue.length).toLowerCase() == viewValue.toLowerCase();
}