admin管理员组文章数量:1292225
In my following angular application, I have multiple rows of myelement
(angular directive wrapper over input
tag). At a time I need to focus/select/highlight one of it, .selected
class in the styles does that.
In following application, everything works fine except focus to the input
tag, which needs to be bounded by the css class selected
. I.E. whatever element has class selected
the corresponding input
tag should be focused . How can I acieve that ?
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<script src=".6.4/angular.min.js"></script>
<style>
.container {
display: flex;
flex-direction: column;
width: 600px;
}
.notebook {
display: flex;
justify-content: center;
}
.cell {
margin: 5px;
padding: 5px;
}
.selected {
border-style: solid;
border-color: green;
border-width: 1px;
border-left-width: 5px;
}
</style>
</head>
<body ng-app="myApp">
<div ng-controller="ListController as listctrl" class="notebook">
<div class="container">
<myelement ng-repeat="i in listctrl.list"
ng-click="listctrl.selected = $index"
ng-class="{selected : listctrl.selected === $index}"
class="cell"></myelement>
</div>
</div>
<script type="text/javascript">
angular
.module('myApp',[])
.controller('ListController', function($scope) {
var listctrl = this;
listctrl.list = [];
listctrl.selected = 0;
listctrl.addCell = function() {
var x = listctrl.list.length;
listctrl.list.push(x);
listctrl.selected = listctrl.list.length - 1;
}
listctrl.addCell();
$scope.$on('add', function (event, message) {
$scope.$apply(listctrl.addCell);
});
$scope.$on('keyUp', function(event) {
$scope.$apply(function(){
listctrl.selected = listctrl.selected - 1;
});
});
$scope.$on('keyDown', function(event) {
$scope.$apply(function(){
listctrl.selected = listctrl.selected + 1;
});
});
})
.directive('myelement', function($rootScope){
return {
template: '<input style="width: 95%"></input>',
restrict: 'E',
link: function (scope, element, attrs) {
var inputTag = element[0].children[0];
inputTag.focus();
element.on('keydown', function(event) {
if (event.keyCode === 13 && event.shiftKey) {
$rootScope.$broadcast('add');
} else if (event.keyCode === 38) {
$rootScope.$broadcast('keyUp');
} else if (event.keyCode === 40) {
$rootScope.$broadcast('keyDown');
}
});
},
controller: function ($scope) {
}
};
})
</script>
</body>
</html>
In my following angular application, I have multiple rows of myelement
(angular directive wrapper over input
tag). At a time I need to focus/select/highlight one of it, .selected
class in the styles does that.
In following application, everything works fine except focus to the input
tag, which needs to be bounded by the css class selected
. I.E. whatever element has class selected
the corresponding input
tag should be focused . How can I acieve that ?
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<style>
.container {
display: flex;
flex-direction: column;
width: 600px;
}
.notebook {
display: flex;
justify-content: center;
}
.cell {
margin: 5px;
padding: 5px;
}
.selected {
border-style: solid;
border-color: green;
border-width: 1px;
border-left-width: 5px;
}
</style>
</head>
<body ng-app="myApp">
<div ng-controller="ListController as listctrl" class="notebook">
<div class="container">
<myelement ng-repeat="i in listctrl.list"
ng-click="listctrl.selected = $index"
ng-class="{selected : listctrl.selected === $index}"
class="cell"></myelement>
</div>
</div>
<script type="text/javascript">
angular
.module('myApp',[])
.controller('ListController', function($scope) {
var listctrl = this;
listctrl.list = [];
listctrl.selected = 0;
listctrl.addCell = function() {
var x = listctrl.list.length;
listctrl.list.push(x);
listctrl.selected = listctrl.list.length - 1;
}
listctrl.addCell();
$scope.$on('add', function (event, message) {
$scope.$apply(listctrl.addCell);
});
$scope.$on('keyUp', function(event) {
$scope.$apply(function(){
listctrl.selected = listctrl.selected - 1;
});
});
$scope.$on('keyDown', function(event) {
$scope.$apply(function(){
listctrl.selected = listctrl.selected + 1;
});
});
})
.directive('myelement', function($rootScope){
return {
template: '<input style="width: 95%"></input>',
restrict: 'E',
link: function (scope, element, attrs) {
var inputTag = element[0].children[0];
inputTag.focus();
element.on('keydown', function(event) {
if (event.keyCode === 13 && event.shiftKey) {
$rootScope.$broadcast('add');
} else if (event.keyCode === 38) {
$rootScope.$broadcast('keyUp');
} else if (event.keyCode === 40) {
$rootScope.$broadcast('keyDown');
}
});
},
controller: function ($scope) {
}
};
})
</script>
</body>
</html>
Share
edited Oct 6, 2017 at 11:33
Jayendra Parmar
asked Oct 6, 2017 at 9:12
Jayendra ParmarJayendra Parmar
77413 silver badges32 bronze badges
3
- Shouldn't ng-class="{selected : listctrl.selected === $index}" have a "?" in between selected and listctrl.selected since it's a ternary? Or am I reading it wrong. – Dream_Cap Commented Oct 9, 2017 at 5:04
- 1 @Dream_Cap it's not a ternary, just an object literal – Phil Commented Oct 9, 2017 at 5:04
-
Can you not use something like
element.hasClass('selected') && inputTag.focus()
? You may need to set your directive'spriority
to something greater than0
so its post-link function runs afterngClass
– Phil Commented Oct 9, 2017 at 5:08
4 Answers
Reset to default 4 +25Consider the following example. It uses the now remended ponent
feature of AngularJS (since v1.5). The example is very simple so you can easily understand what is happening and how to apply it in your project.
JavaScript
class MainController {
constructor() {
this.focused = true;
}
}
class MyElementController {
constructor($element) {
this.$element = $element;
}
$onChanges(changes) {
if (changes.focused.currentValue === true) {
this.$element[0].getElementsByTagName('input')[0].focus();
}
}
}
const myElementComponent = {
bindings: {
focused: '<'
},
controller: MyElementController,
template: `<input type="text">`
};
angular
.module('app', [])
.controller('MainController', MainController)
.ponent('myElement', myElementComponent);
HTML
<body ng-app="app" ng-controller="MainController as vm">
<my-element focused="vm.focused"></my-element>
</body>
var elementComponent = {
bindings:{
selected:'<'
},
controller:function($element){
this.$onChanges = function(changes) {
if(changes.selected.currentValue){
$element[0].getElementsByClassName('textName')[0].focus()
}
}
},
template:'<input type="text" class="textName" style="margin:4px">'
};
var controller = function(){
this.list = [1];
this.selected = 1
this.add = function(){
var length = this.list.length ;
this.list.push(length + 1);
this.selected = length + 1;
}
};
angular.module('app', [])
.ponent('element', elementComponent)
.controller('appCtrl', controller);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body ng-app="app" ng-controller="appCtrl as vm" >
<script src="https://rawgit./angular/bower-angular/master/angular.min.js"></script>
<button ng-click="vm.add()">Add New Cell</button>
<div ng-repeat="item in vm.list" >
<element selected="item == vm.selected" ng-click="vm.selected = item"></element>
</div>
Selected Element : {{vm.selected}}
</body>
</html>
This might fill your requirement.
on every key up/done, check the class, and use focus(), blur() to change input states. in case of tab press, preventDefault()
angular
.module('myApp',[])
.controller('ListController', function($scope) {
var listctrl = this;
listctrl.list = ['1','2','3'];
listctrl.selected = 0;
listctrl.addCell = function() {
var x = listctrl.list.length;
listctrl.list.push(x);
listctrl.selected = listctrl.list.length - 1;
}
listctrl.addCell();
$scope.$on('add', function (event, message) {
$scope.$apply(listctrl.addCell);
});
$scope.$on('keyUp', function(event) {
$scope.$apply(function(){
listctrl.selected = listctrl.selected - 1;
});
});
$scope.$on('keyDown', function(event) {
$scope.$apply(function(){
listctrl.selected = listctrl.selected + 1;
});
});
})
.directive('myelement', function($rootScope){
return {
template: '<input style="width: 95%"></input>',
restrict: 'E',
scope: {},
link: function (scope, element, attrs) {
var inputTag = element[0].children[0];
var updateFocues = function(element) {
if(element[0].className.indexOf('selected') !== -1) {
scope.$apply(function() {
inputTag.focus()
});
} else {
scope.$apply(function() {
inputTag.blur()
});
}
}
element.on('keydown', function(event) {
if (event.keyCode === 13 && event.shiftKey) {
$rootScope.$broadcast('add');
} else if (event.keyCode === 38) {
$rootScope.$broadcast('keyUp');
} else if (event.keyCode === 40) {
$rootScope.$broadcast('keyDown');
}else if (event.keyCode === 9) {
event.preventDefault();
}
});
scope.$on('keyUp', function() {
updateFocues(element)
})
scope.$on('keyDown', function() {
updateFocues(element)
})
},
controller: function ($scope) {
}
};
})
.container {
display: flex;
flex-direction: column;
width: 600px;
}
.notebook {
display: flex;
justify-content: center;
}
.cell {
margin: 5px;
padding: 5px;
}
.selected {
border-style: solid;
border-color: green;
border-width: 1px;
border-left-width: 5px;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.6.4/angular.min.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="ListController as listctrl" class="notebook">
<div class="container">
<myelement ng-repeat="i in listctrl.list"
ng-click="listctrl.selected = $index"
ng-class="{selected : listctrl.selected === $index}"
class="cell"></myelement>
</div>
</div>
</body>
</html>
Suggest you use css instead (most likely it will fit your needs). Adding extra JS code to support simple behaviours is not a good practice.
:focus
selector explained on W3C
E.g.
myelement input:focus {
border-style: solid;
border-color: green;
border-width: 1px;
border-left-width: 5px;
}
本文标签: javascriptAngular bind class of element to element focusStack Overflow
版权声明:本文标题:javascript - Angular bind class of element to element focus - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741551952a2384931.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论