Linking an element's class to the focus of another element in Angular

In my Angular application, I have multiple rows of elements that are wrapped with the myelement directive (which is a wrapper for the input tag). To highlight or focus on one of these elements at a time, I apply the .selected class in the styles.

Everything in my application is working smoothly except for focusing on the input tag, which should be bound by the CSS class selected. In other words, whenever an element has the class selected, the corresponding input tag should receive focus. How can I achieve this?

<!doctype html>
<html>
  ...
</html>

Answer №1

Take a look at the following example showcasing the use of the recommended component feature in AngularJS (from version 1.5 onwards). This example is straightforward and provides a clear understanding of how to implement it in your own 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>

Answer №2

 var customElement = {
bindings:{
     chosen:'<'
  },
  controller:function($element){
     this.$onChanges = function(changes) {
       if(changes.chosen.currentValue){
         $element[0].getElementsByClassName('textName')[0].focus()
       }
    }
  },
  template:'<input type="text" class="textName"  style="margin:4px">'
};

var dataController = function(){
   this.items = [1];
   this.chosen = 1
   this.addItem = function(){
     var length = this.items.length ;
      this.items.push(length + 1);
      this.chosen = length + 1;
   }
};


angular.module('app', [])
       .component('customComponent', customElement)
       .controller('mainCtrl', dataController);
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
</head>
<body ng-app="app" ng-controller="mainCtrl as ctrl" >
<script src="https://rawgit.com/angular/bower-angular/master/angular.min.js"></script>
  <button ng-click="ctrl.addItem()">Add New Item</button>
  <div ng-repeat="item in ctrl.items"  >
    <custom-component chosen="item == ctrl.chosen"  ng-click="ctrl.chosen = item"></custom-component>
  </div>
  Selected Element : {{ctrl.chosen}}
</body>
</html>

This code snippet may fulfill your needs.

Answer №3

When a key is pressed or the input is updated, the script checks the class and utilizes focus() and blur() to modify the input states. If the tab key is pressed, it will prevent the default behavior.

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.com/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>

Answer №4

It is recommended to utilize CSS instead of adding unnecessary JavaScript code for simple functionalities. This will ensure better efficiency and cleaner code structure.

Learn more about the :focus selector on W3C's website.

For example, you can use the following CSS code:

.myelement input:focus {
  border-style: solid;
  border-color: green;
  border-width: 1px;
  border-left-width: 5px;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The pagination feature in ui-bootstrap-tpls 1.0.0 or later versions is not showing up as expected

I am currently using the "pagination" directive from ui-bootstrap-tpls <pagination total-items="totalItems" ng-model="currentPage" ng-change="pageChanged()"></pagination> If you want to see a plunker Demo of version 0.14.3 of ui-bootstrap-tpl ...

The browser is not displaying the results from Mongodb, yet they are appearing in the console

I am currently using the following code for my router: let mongoose = require('mongoose'); // connecting with our model let ByProduct = require('../models/Byproduct') router.get('/',(req,res,next)=>{ ByProduct.find().th ...

Tips for utilizing the Toggle Slider JS functionality

I'm attempting to change a value using a slider in HTML, here is my approach: html file : <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script scr="./scripts.js" ...

What is the most creative way you can think of to create a CSS/JS animated

Is using an animated SVG the best way to create these wavy blobs for mobile compatibility? What approach would you take? Here is a similar example I found var wave = document.createElement("div"); wave.className += " wave"; docFrag.appendChil ...

React onClick event image attribute is unique because it allows for interactive

Is there a way to dynamically add the onClick attribute to an image, but have the click event not working? //Code const parser = new DOMParser(); const doc = parser.parseFromString(htmlContent, "text/html" ); const imageDa ...

Accessing form data within Mongoose schema hooks via JavaScript

I have a form where I've split the content into two separate MongoDB schemas. I want to access variables that are within node.js/express.js directly in mongoose schema hooks, whether through pre or post hooks of the schema. Here are my files: expres ...

What is the process for inserting HTML content into the body of an iframe?

Is there a way to insert HTML content into the body of an iframe instead of using the src attribute to call a page's URL? I am looking for a code that is compatible with all browsers and works perfectly. ...

FormController instance cannot be found within the parent scope

Issue I am facing a challenge in accessing an AngularJS FormController instance, which was created by setting a name property on a form directive, from its parent controller scope. The result returned is undefined. Curiosity However, I am able to view t ...

Does turning off javascript in a browser impact ajax requests and javascript functions?

My mind is troubled I've been thinking of options like turning off JavaScript in the browser. If I do that, then AJAX and JavaScript functions won't work, right? If so, is there a solution? ...

When FullCalendar eventRender is called, it can cause the browser tab to become

I'm working with the FullCalendar plugin within AngularJs. Everything is functioning properly. However, when I add background color, image, tooltip, and label for each event in the eventRender event, it causes the browser tab to freeze for a few seco ...

Issue with strange symbols appearing in Safari on Mac

Hey there! I have this website built with asp.net and I have a text-box for filling in quantities. Sometimes, I notice this strange icon that looks like a human appearing on the text box. It only seems to show up when using Mac Safari browser. Check out th ...

Utilizing dispatch sequentially within ngrx StateManagement

I have been working on a project that utilizes ngrx for state management. Although I am still fairly new to ngrx, I understand the basics such as using this.store.select to subscribe to any state changes. However, I have a question regarding the following ...

What is the reason behind a PHP page refresh causing a session variable to be released

In an attempt to unset a session variable after 2 minutes using unsetsession.php, I have the following code: <?php session_start(); if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 120 ...

Having trouble scrolling with Selenium WebDriver and JavaScript Executor

Can you help me locate and click on the 5th element in this list? The following is a list of all the rooms stored: @FindBy(xpath="//p[@class='css-6v9gpl-Text eczcs4p0']") List<WebElement> placeListings; Code to click on t ...

Printing Strings in JavaScript IF Conditional Block

Hello there! I am looking for assistance with a JavaScript concept. Recently, I created some code where in the HTML file, there is a div element with an id of "GetID" where the string outputs are meant to be displayed. The JavaScript code looks something ...

The integration of VueJS with Axios and the Google Maps API

Currently following [this][1] guide to develop a Google Map and now I am looking to execute a GET request with Axios: axios.get("http://localhost:8080/mapjson").then(function(response) { }) in order to integrate the information from my JSON file into the ...

Is it possible to trigger an event each time an Ajax request is made within AngularJS?

I am looking for a way to automatically display a spinner with a dark overlay every time a call is made to the backend. While I know I can manually implement this by triggering the spinner before each call, I prefer a solution that does not require addit ...

The ng-repeat track by function is not functioning as expected, displaying slow performance and continuing to create $$hashKey

In my code, I have an ng-repeat setup like this: ng-repeat="article in main[main.mode].primary | orderBy: main[main.mode].primary.filter.order track by article.url" The main[main.mode].primary array contains the data and the .filter.order string is used ...

Paging in Ext JS does not function properly when using local data sources

I am facing an issue with enabling paging in ExtJs4 grid. The paging toolbar appears to be functioning correctly, however, the paging feature does not seem to work within the grid itself. Can anyone provide guidance on what might be missing? Ext.onReady(f ...

Struggling to create a BMI Calculator using JS, the result is consistently displaying as 'NaN'

Having trouble creating a BMI Calculator using JavaScript. The issue I'm facing is that the calculation always returns 'NaN'. I've tried using parseInt(), parseFloat(), and Number() but couldn't solve the problem. It seems that the ...