각도 JS - 자동으로 입력에 초점을 맞추고 자동 검색 드롭다운을 표시합니다 - ui.bootstrap.autoahead
Angular JS - ui.bootstrap.typeahead를 사용하고 있습니다.
버튼을 클릭하여 입력 필드에 초점을 맞추고 자동 검색 제안 드롭다운을 자동으로 표시합니다.버튼을 클릭하면 자동으로 입력 필드에 초점을 맞추는 지침이 있습니다.드롭다운을 자동으로 표시하여 사용자가 아래쪽 화살표를 사용하거나 클릭하여 사용자를 빠르게 선택할 수 있도록 하려면 어떻게 해야 합니까?
팅크용으로 편집 가능한 ui-bootstrap JS 파일을 사용하여 Plunker를 만들었습니다.
http://plnkr.co/edit/Z79LY0OYlwFc3wirjxol?p=preview
이것이 저의 전체 스크립트입니다.
<!doctype html>
<html ng-app="plunker">
<head>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script>
<script src="ui-bootstrap-tpls-0.10.0.js"></script>
</head>
<body>
<script>
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();
});
}
});
}
};
});
function TypeaheadCtrl($scope, $http) {
$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'];
$scope.opened = false;
$scope.open = function() {
$scope.opened = true;
}
$scope.close = function() {
$scope.opened = false;
}
}
</script>
<div class='container-fluid' ng-controller="TypeaheadCtrl">
<h4>How can I open the typeahead dropdown automatically when button is pressed?</h4>
<p>I have a directive that automatically focuses on the field but I can't seem to automatically show the typeahead. Even adding down arrow key click support would be great.
<br/><br/>
<button class="btn btn-default" ng-show="!opened" ng-click="open()">Open Input and show typeahead!</button>
<button class="btn btn-default" ng-show="opened" ng-click="close()">Close Input</button>
<br/><br/>
<input type="text"
focus-me="opened"
ng-show="opened"
ng-model="selected"
typeahead="state for state in states | filter:$viewValue | limitTo:8"
class="form-control">
<br/>
<pre ng-show="opened">Model: {{selected | json}}</pre>
</div>
</body>
</html>
갱신일 :
업데이트와 접근을 용이하게 하기 위해 github에 명령어를 추가했습니다.이제 bower를 통해 의존관계로 설치할 수 있습니다.
원본 투고:
저는 ui-bootstrap-tpls를 변경할 필요가 없는 깔끔한 해킹을 생각해냈습니다.아이디어에서는 $setViewValue()를 사용하여 특수 필터 비교 함수를 조합하여 팝업을 트리거합니다.
minLength 체크를 생략하려면 $setViewValue()를 1보다 긴 값으로 설정해야 합니다.따라서 공백 문자열을 1개 사용합니다.비교기 함수의 역할은 빈 입력을 클릭하면 모든 항목이 표시되도록 공백 하나를 모든 항목과 일치하도록 처리하는 것입니다.
간단한 지시문을 작성했습니다.
angular.module('app')
.directive('typeaheadFocus', function () {
return {
require: 'ngModel',
link: function (scope, element, attr, ngModel) {
//trigger the popup on 'click' because 'focus'
//is also triggered after the item selection
element.bind('click', function () {
var viewValue = ngModel.$viewValue;
//restore to null value so that the typeahead can detect a change
if (ngModel.$viewValue == ' ') {
ngModel.$setViewValue(null);
}
//force trigger the popup
ngModel.$setViewValue(' ');
//set the actual value in case there was already a value in the input
ngModel.$setViewValue(viewValue || ' ');
});
//compare function that treats the empty space as a match
scope.emptyOrMatch = function (actual, expected) {
if (expected == ' ') {
return true;
}
return actual.indexOf(expected) > -1;
};
}
};
});
사용방법:
<input type="text" ng-model="selected" typeahead="item for item in items | filter:$viewValue:emptyOrMatch | limitTo:8" typeahead-focus >
HarishR이 코멘트에서 언급했듯이 이 기능은 아직 지원되지 않습니다.
하지만 저는 그냥 해킹을 시도해보려고 합니다.그 결과는 다음과 같습니다.http://plnkr.co/edit/Qrnat8yTvISuM1qHHDlA?p=preview
기능하기 위한 많은 해킹이 포함되어 있습니다.
- .trigger()를 사용하기 위해 include jQuery를 네이티브 JS로 대체할 수 있지만 저는 게으릅니다.
- ng-timeout을 사용하여 .trigger 'input')를 호출하여 타입헤드 팝업을 트리거합니다.
- 입력의 값 자동 트리밍을 비활성화하려면 ng-syslog="false"를 사용합니다.
secretEmptyKey 로직을 적용하여 자동 검색 최소 길이 검사를 바이패스하기 위한 ngModel의 컨트롤러와 상호 작용하는 사용자 지정 빈 자동 검색 지시:
.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 }); } } })
하나의 인수가 secret EmptyKey일 경우 항상 true를 반환하는 커스텀필터 비교 함수:
$scope.stateComparator = function (state, viewValue) { return viewValue === secretEmptyKey || (''+state).toLowerCase().indexOf((''+viewValue).toLowerCase()) > -1; };
제한 제거모든 결과를 표시하는 필터
- 콘텐츠가 너무 긴 경우 스크롤바를 표시하도록 max-height 및 overflow css 속성을 설정합니다.
알았어!
ui-bootstrap-tpls-0.10.0.js의 코드를 변경하여 솔루션을 동작시켰습니다.따라서 자동 검색 html 마크업에는 차이가 없습니다.
여기 http://plnkr.co/edit/LXHDpL?p=preview에서 보실 수 있습니다.
이 수정을 사용하려면 Plunk의 ui-bootstrap-tpls-0.10.0.js를 사용합니다.변경 내용을 보려면 Plunk에서 ui-bootstrap-tpls-0.10.0.js를 열고 'anhneo'를 검색하십시오.
1. //minimal no of characters that needs to be entered before typeahead
kicks-in
// ahneo :: before
//var minSearch = originalScope.$eval(attrs.typeaheadMinLength) || 1;
// ahneo :: after (changed minimal no of characters to 0 by default)
var minSearch = originalScope.$eval(attrs.typeaheadMinLength) || 0;
2. // ahneo :: new (set input value to empty string if it contains " " string value)
if (inputValue === ' ') {
inputValue = '';
modelCtrl.$setViewValue('');
}
3. // ahneo :: before
//if (inputValue && inputValue.length >= minSearch) {
// ahneo :: after (add new condition to get matches for min search = 0)
if (minSearch === 0 || inputValue && inputValue.length >= minSearch) {
4. // ahneo :: new (bind element to focus event to trigger modelCtrl.$parsers.unshift method)
element.bind('focus', function (evt) {
if (modelCtrl.$viewValue === '') {
modelCtrl.$setViewValue(' ');
}
});
도움이 되었으면 좋겠다
현재 저는 코멘트가 부족하기 때문에 위의 runTarm의 답변을 경고하기 위해 새로운 답변을 작성해야 합니다.이는 실행 가능한 해결책이지만 다음과 같은 오류가 발생할 위험이 있습니다.
Error: [$rootScope:inprog] $apply already in progress
이는 ng-focus가 동기 이벤트이기 때문이라고 생각됩니다(여기서 설명 참조).대신 ng-click-attribute를 사용할 수 있으며 이 오류는 발생하지 않습니다.
또, 확인했습니다만,
$element.triggerHandler('input');
runTarm 응답의 jQuery-trigger와 동일하게 동작합니다.
에서 "Dr.C.C.B.B.B.C.B.B.B.C.B.B.B.B.C.B.B.B.B.C.B.B.B.C.B.B.B.B.C.B.B.B.B.C.B.B.B.B.B.B.C.B.B.B.B.B.B.B.Btypeahead-min-length
Attribute Supporting 0 0 の at 0 。
마스터 브랜치 https://github.com/angular-ui/bootstrap/commit/d859f42cc022a5d8779f1c7b358486bbdd04ed57,의 이 커밋에 실장되어 있습니다만, 아직 릴리스는 없고, 0.14.x 브랜치에도 없습니다.
새로운 릴리스가 빨리 출시되어 이러한 회피책이 더 이상 필요하지 않기를 바랍니다.
OP의 설명과 같은 것을 원했는데, 제가 찾은 유일한 해결책은 드롭다운 지시문과 자동 검색 지시문을 결합한 템플릿을 고안하는 것이었습니다. OP나 다른 사용자가 유용하게 사용할 수도 있습니다.
angular.module('app', ['ui.bootstrap'])
.controller('AppCtrl', function($scope) {
$scope.model;
$scope.options = [{label:'Option 1'}, {label:'Option 2'}, {label:'Option 3'}];
$scope.onSelect = function($item, $model, $label) {
$scope.model = angular.copy($item);
}
});
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.min.js"></script>
<div ng-app='app' style='padding:10px'>
<div ng-controller='AppCtrl'>
<div class='dropdown' dropdown style='width:200px'>
<!-- This needs UI Bootstrap 0.12 to work -->
<div class='input-group'>
<input type='text' class='form-control' ng-model='model.label' typeahead="op.label for op in options | filter:$viewValue | limitTo:8" typeahead-editable='false' />
<span class='input-group-btn'>
<button class='btn btn-default dropdown-toggle' dropdown-toggle>
<span class='caret'></span>
</button>
</span>
</div>
<ul class="dropdown-menu" role='menu' style='max-height:200px;overflow-y:scroll'>
<li ng-repeat='op in options'>
<a href ng-click='onSelect(op)'>{{op.label}}</a>
</li>
</ul>
</div>
</div>
</div>
물론 단순화할 수 있습니다.옵션을 문자열 배열로만 만들 수 있습니다.필요에 따라 오브젝트로 만들었습니다.
autoahead-min-length="0"이 효과가 있습니다(v0.4.0을 사용하고 있습니다).
나는 지시로 이 문제를 해결했다.이 디렉티브를 사용하면 필터 없이 목록이 표시됩니다.그러면 검색어를 입력하여 요소를 찾습니다.
angular.module('myapp')
.directive('typeaheadLikeSelect',
['$parse',function($parse) {
return {
require: 'ngModel',
link: function (scope, element, attr, ngModel){
var aux_modelValue, aux_viewValue,
modelGetter = $parse(attr.ngModel),
modelSetter = modelGetter.assign;
var noViewValue = function(){
return
ngModel.$$lastCommittedViewValue === undefined ||
!ngModel.$$lastCommittedViewValue.trim();
};
var forceEvent = function(){
ngModel.$setViewValue();
ngModel.$viewValue = ' ';
ngModel.$setViewValue(' ');
ngModel.$render();
scope.$apply();
element.val(element.val().trim());
};
element.on('mousedown', function(e){
e.stopPropagation();
forceEvent();
});
element.on('blur', function(e){
e.stopPropagation();
if(aux_modelValue){
modelSetter(scope, aux_modelValue);
scope.$apply();
}
});
scope.$watch(function () {
return ngModel.$modelValue;
}, function(newValue, oldValue){
if(newValue || (!newValue && !oldValue))
aux_modelValue = newValue;
});
}
};
}]);
위 코드를 테스트하기 위해 뷰 코드를 남깁니다.
<script type="text/ng-template" id="customTemplate.html">
<a>
<span ng-bind-html="match.label.description | uibTypeaheadHighlight:query"></span>
</a>
</script>
<div class="form-group has-feedback" ng-class="{'has-success':items.mymodel}">
<input
placeholder="typeahead"
ng-model="items.mymodel"
uib-typeahead="responses as responses for responses in getResponses($viewValue)"
typeahead-template-url="customTemplate.html"
typeahead-input-formatter="$model.description"
typeahead-loading="loadingResponses"
typeahead-no-results="noResponses"
typeahead-editable="false"
typeahead-on-select="changeItem($item)"
class="form-control"
required="required"
typeahead-like-select>
<div ng-show="noResponses">
<i class="glyphicon glyphicon-remove"></i> No Results Found
</div>
<span ng-show="!items.mymodel" class="glyphicon glyphicon-search form-control-feedback" aria-hidden="true"></span>
<span ng-show="items.mymodel" class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>
</div>
입력 요소가 포커스를 맞출 때마다 자동 검색을 열고 싶었습니다.Angular Bootstrap(버전 1.0.3)의 최신 버전에서는 @yohairosen의 솔루션이 작동하지 않았습니다.여기 제게 효과가 있었던 해결책이 있습니다.ui-bootstrap-typeahead에 의해 연결된 파서를 수동으로 호출하여 제안사항을 채웁니다.
angular.module('app')
.directive('typeaheadFocus', function () {
return {
require: 'ngModel',
link: function (scope, element, attr, ngModel) {
element.bind('click', function () {
ngModel.$parsers[0](ngModel.$viewValue);
});
}
};
};
});
이것은 ui-bootstrap-typeahead에 의해 추가된 파서가 유일한 것으로 간주되기 때문에 버그가 발생할 수 있습니다.
우리가 원하는 것은 초점일 때 입력 요소에 트리거('input')하는 것입니다.
Angular에서 올바른 방법은 지시어로 수행하는 것입니다.
angular.module('app')
.directive('showList', function() {
return {
restrict: 'A',
link: function(scope, iEle) {
iEle.focus(function() {
iEle.trigger('input');
});
}
};
});
자동 검색 입력 요소에 이 지시문을 사용합니다.
<input show-list uib-typeahead="state for state in states | filter:$viewValue" typeahead-min-length="0" class="form-control">
이 코드로 달성할 수 있습니다.
$scope.change = function() {
var e = document.getElementById("test");
var $e = angular.element(e);
$e.triggerHandler('focus');
$e.triggerHandler('input');
}
테스트를 유형 헤드 ID로 변경
언급URL : https://stackoverflow.com/questions/24764802/angular-js-automatically-focus-input-and-show-typeahead-dropdown-ui-bootstra
'it-source' 카테고리의 다른 글
Google Adwords 변환 추적 이벤트 - 한 페이지 (0) | 2023.04.01 |
---|---|
반응에서 url의 이미지를 표시합니다.JS (0) | 2023.04.01 |
jQuery .ajax()에 CSRF 토큰이 필요합니까? (0) | 2023.03.27 |
워드프레스 $wpdb->get_results 및 num_rows (0) | 2023.03.27 |
.docx, .pptx 등의 올바른 MIME 유형은 무엇입니까? (0) | 2023.03.27 |