Search code examples
jqueryhtmlangularjsfocustabindex

Set focus on div with ng-click


I've got follow problem (it could be a little bit to complicate and hard to discribe, but I try it):

I'm building a input helper component with angularJS for some number fields in my web application.

Now at the moment this web application has a lot of code and logic and so I try to explain you how our components work:

Every component has their own html-template, scss (css) file, and two typescrpt files one is the directive for the component and one is the module, where we set it up for the whole application.

So our input helper component has follow files:

HTML-Template (inputHelper.html):

<div class="wscNumberInputHelperComponent">
    <div class="cInputWithButton">
        <div ng-transclude></div>

        <div class="cInputButton" ng-click="ctrl.isHelperShown = true" wsc-tooltip="{data: ctrl.currentValue, template: '<wsc-number-input-helper-tooltip></wsc-number-input-helper-tooltip>', class: 'cNumberInputHelperTooltip', pointerPosition: 'End'}">
            <wsc-icon class="cInputAddonIcon" icon="ctrl.iconName"></wsc-icon>
        </div>
    </div>
</div>

Than the directive (inputHelper.directive.ts), where we handle the bindings for the individual component tag and so on:

import {WsController} from '../../../shared/superclasses/controller';

export class WscNumberInputHelper extends WsController {
    static componentName = 'wscNumberInputHelper';
    static templateUrl = 'app/comp/wsComp/wscNumberInputHelper/wscNumberInputHelper.html';
    static componentOptions = {
        transclude: true,
        bindings: {
            iconName: '@',
            currentValue: '='
        }
    } as ng.IComponentOptions;
}

And at least the module (inputHelper.module.ts), where we set it up for our module:

import {WscNumberInputHelper} from './wscNumberInputHelper.directive';
import {WscNumberInputHelperTooltip} from './wscNumberInputHelperTooltip/wscNumberInputHelperTooltip.directive';

let ngModule = angular.module('wsComp.wscNumberInputHelper', []);

WscNumberInputHelper.register(ngModule);
WscNumberInputHelperTooltip.register(ngModule);

So this is connected with each other, and when wie put our individual component tag around of any input field, we got right of the input field a div with a icon (in the html template the div with the class cInputButton.

Now when we click on the on this div, we open another of our components (a tooltip), which contains our input helper html/logic. This happens in follow code-line (template-html):

<div class="cInputButton" ng-click="ctrl.isHelperShown = true" wsc-tooltip="{data: ctrl.currentValue, template: '<wsc-number-input-helper-tooltip></wsc-number-input-helper-tooltip>', class: 'cNumberInputHelperTooltip', pointerPosition: 'End'}">

As you can see, our tooltip component works also with a binding, where we can give the template, which has to be displayed. This template conaints a div. Now, I would like to make an ng-keypress on this div of my input helper and find out, which key is pressed. I know how this works, I have to give a tabindex to my div like this: tabindex="0" and then call a method in the controller of my input helper (it's not the same like the directive above) like this: ng-keypress="pressedKey($event)". Than I can get the key. The problem is, my tooltip is not in the same html like my input helper, which is within the tooltip, so I have to klick again on the div of my input helper to actually set the focus. How can I do this earlier, when I open the tooltip with my button?

It's very complicate and I'm sorry if the question is hard to understand but I had to try it, I'm out of ideas. Important: The inputhelper html-template, which is within the tooltip is also a own template with its own directive and scss, it only registers in the same module (inputHelper.module.ts).

Thanks and cheers.


Solution

  • Here is my solution:

    This is the template of my input helper component within the tooltip:

    <div class="cInputHelper" tabindex="0" ng-keypress="ctrl.pressedKey($event)">
        <div class="cContainer">
            <div class="cKeys">
                <div class="cKey" ng-repeat="key in ctrl.keys" ng-click="ctrl.modifyValue(key.value)">{{key.label}}</div>
            </div>
            <div class="cSideView">
                <div class="cSideViewItems">
                    <span ng-if="!ctrl.lastInputsList.length">Keine Vorschläge (HC)</span>
                    <div class="cSideViewItem cLastValue" ng-repeat="item in ctrl.lastInputsList">{{item.value}}</div>
                </div>
                <div class="cSideViewItem cSubmit">OK (HC)</div>
            </div>
        </div>
    </div>
    

    On the class cInputHelper I have the tabindex and the ng-keypress for handling key-events on my div. This only works, when my div also has a focus. So every component from angularJS has the $onInit() method, which is the constructor of the component (see this: https://docs.angularjs.org/guide/component) So there I used jQuery for setting the focus on my div like this:

    $onInit() {
        $(".cInputHelper").focus();
    }
    

    After that it works!

    By the way a good information: The ng-keypress just works on editable elements such like input, textarea etc. If you want to use in on others like me on a div, you have to give a tabindex to this element and also set focus on it. Than ng-keypress also works for not-editable elements.

    Cheers.