Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular bind class of element to element focus

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.com/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>
like image 371
Jayendra Parmar Avatar asked Oct 06 '17 09:10

Jayendra Parmar


People also ask

Does focus scroll to Element?

An element can be focused by either using the autofocus="true" attribute or calling the element. focus() method. In both cases, the browser will automatically scroll the element into the viewport.

How do you know if an element is focused in angular?

hasFocus() : whether the document or any element inside the document has focus. document. activeElement : Property containing which element currently has focus.

Which of the following method removes focus from an element?

Use the blur() method to remove the focus from an element, e.g. input.


Video Answer


1 Answers

Consider the following example. It uses the now recommended component 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)
    .component('myElement', myElementComponent);

HTML

<body ng-app="app" ng-controller="MainController as vm">
    <my-element focused="vm.focused"></my-element>
</body>
like image 98
Vladimir Zdenek Avatar answered Sep 20 '22 23:09

Vladimir Zdenek