7

Ich habe Probleme in folgenden Anwendungsfall in typeahead wieder öffnen:AngularJS [typeahead] Ergebnis Drop-Down auf onFocus

Problem:

  • Benutzer startet die Eingabe, Drop-Down-öffnet und zeigt die Ergebnisse
  • Benutzer klickt aus dem Eingabefeld (nichts aus dem Eingabefeld gelöscht wird), schließt Dropdown
  • Benutzer klickt zurück in das typeahead Eingabefeld (und nicht startet, alles zu geben) und nichts passiert. → das gewünschte Verhalten ist: Dropdown öffnet sich wieder und zeigt das gleiche Ergebnis Liste wie beim letzten Mal (natürlich, dass nur geschieht, wenn es irgendetwas in das Eingabefeld ist)
  • Wenn alles Benutzer suchen und, wenn das Ergebnis gefunden und den Fokus verloren auftritt und String erhält nicht wieder gelöscht konzentriert nichts passieren, keine Hinweise
  • wenn Benutzer Suchanfrage alles und wenn das Ergebnis nicht gefunden und den Fokus verloren auftritt Zeichenfolge erhalten gelöscht und es gibt auch Nachricht von nicht gefundenen Daten.

So Moral der Geschichte ist, dass sollte in ersten Fall Zeichenfolge gelöscht erhalten, wenn sie nicht aus der Liste ausgewählt ist, und es ist Teilzeichenfolge der Liste String ...

Also, vielleicht ein typeahead- Such-Fokus-Einstellung?

HTML:

<input type="text" focus-me="opened" ng-focus="onFocus($event)" ng-show="opened" ng-trim="false" ng-model="selected" empty-typeahead typeahead="state for state in states | filter:$viewValue:stateComparator" class="form-control" /> 

JS:

(function() { 
var secretEmptyKey = '[$empty$]' 

angular.module('plunker', ['ui.bootstrap']) 
.directive('focusMe', function($timeout, $parse) { 
    return { 
     //scope: true, // optionally create a child scope 
     link: function(scope, element, attrs) { 
      var model = $parse(attrs.focusMe); 
      scope.$watch(model, function(value) { 
       if(value === true) { 
        $timeout(function() { 
         element[0].focus(); 
        }); 
       } 
      }); 
     } 
    }; 
}) 
.directive('emptyTypeahead', function() { 
    return { 
    require: 'ngModel', 
    link: function (scope, element, attrs, modelCtrl) { 
     // this parser run before typeahead's parser 
     modelCtrl.$parsers.unshift(function (inputValue) { 
     var value = (inputValue ? inputValue : secretEmptyKey); // replace empty string with secretEmptyKey to bypass typeahead-min-length check 
     modelCtrl.$viewValue = value; // this $viewValue must match the inputValue pass to typehead directive 
     return value; 
     }); 

     // this parser run after typeahead's parser 
     modelCtrl.$parsers.push(function (inputValue) { 
     return inputValue === secretEmptyKey ? '' : inputValue; // set the secretEmptyKey back to empty string 
     }); 
    } 
    } 
}) 
.controller('TypeaheadCtrl', function($scope, $http, $timeout) { 
    $scope.selected = undefined; 
    $scope.states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Wyoming']; 
    $scope.opened = true; 

    $scope.stateComparator = function (state, viewValue) { 
    return viewValue === secretEmptyKey || (''+state).toLowerCase().indexOf((''+viewValue).toLowerCase()) > -1; 
    }; 

    $scope.onFocus = function (e) { 
    $timeout(function() { 
     $(e.target).trigger('input'); 
     $(e.target).trigger('change'); // for IE 
    }); 
    }; 
}); 
}()); 

Ich habe diese Plunker zu zeigen, wie mein Code aussieht.

Es gibt auch GitHub Issue.

Antwort

0

Hallo an alle,

Nach einigen Anstrengungen ich die richtige Lösung. ..

Es gibt einige Richtlinien, die für die Lösung nützlich sein kann,

obigen Bedingung hinzufügen in typeaheadFocus Richtlinie

if ((e.type == "focus" && viewValue != ' ') && (e.type == "focus" && viewValue != '')){ 
     return; 
    } 

Add folgende Funktion in typeaheadFocus Richtlinie und typeaheadOnDownArrow Richtlinie

//compare function that treats the empty space as a match 
    scope.$emptyOrView = function(actual) { 
     if(ngModel.$viewValue.trim()) { 
      return actual ? actual.value.toString().toLowerCase().indexOf(ngModel.$viewValue.toLowerCase()) > -1 : false; 
     } 
     return true; 
    };    

ändern diese Bedingung in ui-bootstrap.js,

if (inputFormatter) { 
    locals.$model = modelValue; 
    if(modelValue){ 
    locals.$label = view_value; 
    } else { 
    locals.$label = ''; 
    } 

Add event in ui-Bootstrap-js folgende,

element.bind('blur', function(evt) { 
    hasFocus = false; 
    if (!isEditable && modelCtrl.$error.editable) { 
     element.val(''); 
     modelCtrl.$viewValue = ' '; 
    } 
    if(!isEditable && scope.no_data_found) { 
     //ngModel.$viewValue = ''; 
     modelCtrl.$viewValue = ' '; 
     scope.no_data_found = false; 
     popUpEl.find('.typeaheadNoData').remove(); 
     resetMatches(); 
     scope.$digest(); 
     element.val(""); 
    } 
}); 

Fügen Sie diese in ui-bootstrap.js,

 // I listen for emptyTypeAhead events from the parent scope chain. 
    originalScope.$on(
     "emptyTypeAhead", 
     function handlePingEvent(event, newVal1) { 
      var scope = originalScope.$new(); 
      modelCtrl.$setViewValue(newVal1); 
      return newVal1; 
     } 
    ); 

Fügen Sie die obige Funktion mit ui-bootstrap.js in allen Richtlinie

.directive('shouldFocus', function($parse) { 
    return { 
     restrict: 'A', 
     link: function(scope, element, attrs) { 
      scope.$watch(attrs.shouldFocus, function(newVal, oldVal) { 
       var isActive = scope.$eval(attrs.shouldFocus); 
       if(isActive) { 
        var ele = element[0]; 
        var parent = ele.parentNode 

        if(ele.offsetTop + ele.offsetHeight > parent.offsetHeight + parent.scrollTop){ 
         parent.scrollTop = ele.offsetTop; 
        } else if(parent.scrollTop > ele.offsetTop) { 
         parent.scrollTop = ele.offsetTop; 
        } 
       } 
      }); 
     } 
    } 
}); 

Beispiel:

<input type="text" ng-model="inquiry.account" 
placeholder="Select Account" 
typeahead="account.id as account.text for account in account_typeahead_json" 
typeahead-input-formatter="formatModel($model,$label)" 
typeahead-editable="false" typeahead-on-down-arrow typeahead-focus /> 

Hoffnung diese Antwort wird für Sie hilfreich sein.

Here Ich habe hinzugefügt ui-bootstrap.js

0

Sie müssen überprüfen, ob der Eingabewert in der Liste vorhanden ist oder nicht. Dafür haben folgende Möglichkeiten:

Attribut hinzufügen ng-blur="onBlur($event)" in Eingabe

und definieren in Ihrem Controller folgende Methode:

$scope.onBlur = function (e) { 
    $timeout(function() { 
    var val = $(e.target).val(); 
    if(val && $scope.states.indexOf(val) == -1) { 
     $(e.target).val("") 
    } 
    }); 
};