Search code examples
javascriptangularjsangular-ui-routerdom-eventsaddeventlistener

Attaching event listeners when using Angular UI-Router


I'm using Angular 1.4.5 with Angular Ui Router, and for text formatting reasons I'm trying to get addEventListener to perform a function when a text field is blured. The problem I'm running into, however, is that on the load state, the element I'm trying to find does not yet exist because it doesn't exist on the template that loaded, so it never attached to the element

Other than editing each and every template so that it loads initEventListeners(), or manually adding onblur to each element as needed, is there a (preferably Vanilla) way to add event listeners when changing routes or way to trigger the function when navigating between states?

Here's the relevant pieces of JS, the rest is properly strung together with UI-Router and Angular


function initEventListeners() {
'use strict'
    if (document.contains(document.getElementById('phone'))) {
       document.getElementById('phone').addEventListener('blur',  formatPhoneNumber);
    }
 }

 window.onload = function () {
    'use strict';
     runTicker();
     setTimeout(cycleFooterText, 4000);
     initEventListeners();
 }

Solution

  • Use angular directive to use dom manipulation or add listener. Your directive will init only when your state is loaded so you don't have to worry about dom selection/load, and it's a best practive anyway.

    Exemple of a directive that add test to your input value on blur :

    html part:

    <input type="text" add-test>
    

    js part:

    angular
        .module('testApp', []) // init angular
        .directive('addTest', function() {
    
            // directive options
            var directive = {
                restrict: 'A',
                compile: compile
            };
    
            return directive;
    
            // use compile instead of link because you don't need to change the listener on scope change
            function compile(elem, attr) {
    
                var input = elem[0];
    
                input.addEventListener('blur', formatPhone);
    
                function formatPhone(e) {
                    input.value += 'test';
                }
    
            }
    
    });
    

    check this fiddle: https://jsfiddle.net/kc6pofdz/1/

    And this guide if you want to learn more about directives: https://www.sitepoint.com/practical-guide-angularjs-directives/