Leverage the controller's properties and methods within the directive

My situation involves a variety of inputs, each with specific directives:

<input mask-value="ssn" validate="checkSsn"/>
<input mask-value="pin" validate="checkPin"/>

These properties are managed in the controller:

app.controller("Ctrl", ['$scope', function ($scope) {
    $scope.ssn = "";
    $scope.pin = "";

    $scope.checkSsn = function () { /* validate $scope.ssn */ };
    $scope.checkPin = function () { /* validate $scope.pin */ };
}]);

Next, we have the maskValue directive:

app.directive("maskValue", function () {
    return function (scope, element, attrs) {
        /* performs focus/blur actions and string manipulation */
        scope[attrs.maskValue] = this.value;
        scope[attrs.validate]();
    };
});

The current setup works, but it appears to be an inefficient use of Angular. It might be better to utilize an isolated scope like so:

    scope: {validate: "&"}

This way, I could call scope.validate() rather than scope[attrs.validate](). However, using an isolated scope prevents me from updating the corresponding value in the controller. Even setting {maskValue: "="} doesn't work as intended because it tries to update the parent's property instead. Using {ssn: "="} seems promising, but then I would only update a specific property of the controller, making the directive less flexible. Using $parent is also not recommended.

How can I dynamically access controller properties within an isolated scope directive?

EDIT: Using ng-model=ssn, etc. on the inputs is not viable because the actual input value changes during the focus/blur events in mask-value. For instance, it may be transformed to *****####, but the original value ######### needs to be stored somewhere for later use, preferably in the controller.

Answer №1

<div ng-app=bar>
  <div ng-controller=Controller>
  {{id}}
  <input data-mask="id" validate-input="checkId()">

app = angular.module("bar", []);

app.controller("Controller", ['$scope', function ($scope) {
    $scope.id = "";
    $scope.checkId = function () { console.log($scope.id); };
}]);

app.directive("dataMask", function () {
    return {
        scope: {
            validateInput: "&",
            maskValue: "="
        },
        link: function (scope, element, attrs) {
            element.bind("change", function () {
                scope.maskValue = this.value;
                scope.$apply();
                scope.validateInput();
            });
        },
    };
});

http://jsfiddle.net/abc123/

UPDATE:

it is recommended to pass the expression to evaluate as an argument to $apply for better error handling in AngularJS:

var val = this.value;
scope.$apply(function () {
    scope.maskValue = val;
});

Answer №2

Although you may have already found a solution for your query, I wanted to highlight the option of utilizing Angular's built-in functionalities to facilitate validation while still being able to apply ng-model. Below is an illustrative example:

app.directive("maskValue", function ($parse) {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function (scope, element, attrs, ngModel) {
      if (!ngModel) return;
      var validator = $parse(attrs.validator)(scope);

      ngModel.$render = function() {
        var hasFocus = document.activeElement == element[0];
        if (ngModel.$valid || hasFocus) element.val(ngModel.$modelValue)
        else element.val('#######');
      };

      element.bind('blur', function() {
        ngModel.$setValidity('maskValue', validator(this.value))
        ngModel.$render();
      });

      element.bind('focus', function() {
        ngModel.$render();
      });
    }
  };
});

This directive leverages NgModelController in conjunction with ng-model to regulate view updates. In the given scenario, it will display ######## when the element loses focus and the validation function returns false. Upon refocusing the control, the actual value will be displayed enabling user modification. It is important to note that the scope property linked to the control remains unchanged while the view adapts based on the element's status (valid or invalid). For a demonstration, refer to the live example here.

Answer №3

My apologies, but have you considered implementing the following code snippet:

app = angular.module("foo", []);

app.controller("Ctrl", ['$scope', function ($scope) {
    $scope.ssn = "";
    $scope.validate = function () { console.log($scope.ssn); };
}]);

app.directive("maskValue", function () {
    return {
        link: function (scope, element, attrs) {
            element.bind("change", function () {  
                scope.validate();
            });
        },
    };
});

Furthermore, use this HTML structure:

<div ng-app=foo>
    <div ng-controller=Ctrl>
        <input ng-model="ssn" mask-value />
    </div>
</div>

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 function error is currently in a waiting state as it already includes an

I encountered a particular issue that states: "await is only valid in async function." Here is the code snippet where the error occurs: async function solve(){ var requestUrl = "url"; $.ajax({url: "requestUrl", succes ...

Issue with AngularJS ui-router failing to resolve a service call

I am facing an issue while trying to implement the resolve feature in my ui-router state provider. Here is how I have configured it: app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ($stat ...

What is the best way to link optional and undefined paths in AngularJS routing?

When it comes to AngularJS routing, I have a question. How can we combine the use of a star (*) to match paths with slashes and a question mark (?) to match optional paths? Specifically, I am looking to match both /admin/tasks and /admin/tasks/arbitrary/pa ...

Organize data in a Vue.js table

Currently facing an issue with sorting my table in vue.js. Looking to organize the table so that campaigns with the highest spend are displayed at the top in descending order. Here is the code I'm working with: <template> <div class=" ...

Retrieve information from individual XML nodes in a parsed string

When making an Ajax call to retrieve XML data from a different domain using a PHP proxy to bypass cross-origin restrictions, I am unable to extract the values from the XML nodes and display them in my HTML tags. Despite no errors showing up in the browser ...

AngularJS route not functioning as expected

I am currently utilizing angular in combination with node. I am implementing routes to redirect the page. On my html page, I have defined 2 links as follows: <!DOCTYPE html> <html > <head> <title>My Angular App!</title> ...

Creating a password with two distinct numbers using regular expressions

In javascript I am struggling to create a password that meets the criteria of having at least eight characters, including two SEPARATE digits, one uppercase and one lowercase letter, as well as one special character (-, @, #, $, &, *, +) but not /, !, ? ...

Implement a T3 App Redirect in a TRPC middleware for unsigned users

Is there a way to implement a server-side redirect if a user who is signed in has not finished filling out their profile page? const enforceUserIsAuthed = t.middleware(({ ctx, next }) => { if (!ctx.session || !ctx.session.user) { throw new TRPCE ...

Can two Angular element components be utilized simultaneously on a single page in Angular 6?

Currently, I'm attempting to host independent Angular elements that can be seamlessly integrated into a non-Angular webpage. Everything works perfectly fine when there's only one element on the page, but as soon as I try to load two or more, I en ...

Utilizing SEO and incorporating special characters like !# in a website's URL

I came across an interesting concept about designing a website that utilizes AJAX to load each page section without compromising SEO. It involved incorporating !# in the URL, similar to the approach adopted by Twitter. However, I've been unable to loc ...

What causes scope to be undefined in Angular?

Using ionic to develop a hybrid app has been a smooth experience, especially with android! This is my login HTML: <body ng-app="starter"> <head> <script src="phonegap.js"></script> </head> <ion-header-ba ...

Warning: multiple selections have been made on the checkboxes

Currently, I am using FormData to submit data and trying to alert the values of checked checkboxes in my form. At the moment, I can only make it work for one checkbox. How can I alert the values of all checked checkboxes? var formData = new FormData(docu ...

Each page in NextJS has a nearly identical JavaScript bundle size

After using NextJS for a considerable amount of time, I finally decided to take a closer look at the build folder and the console output when the build process is successful. To my surprise, I noticed something peculiar during one of these inspections. In ...

Converting UTF-16 to UTF-8 in JavaScript: A step-by-step guide

I'm facing a challenge with Base64 encoded data in UTF-16 format. While most libraries only support UTF-8, I need to find a way to decode the data by dropping the null bytes, although I'm not sure how to go about it. Currently, I'm utilizin ...

Troubleshooting: Why isn't my CSS fixed position working for my sticky

I have a simple jQuery code snippet that is supposed to make the navigation element sticky by applying a class with position: fixed. However, I'm facing an issue on my Commerce platform where the fixed position property doesn't seem to work corre ...

The child component is not updating the v-model prop array of the parent component

In my current project, I have a main component called cms-custom-editor: <template> <div id="cms-custom-editor" class="cms-custom-editor"> <cms-editor-toolbar v-model:toggles="state.toggles"/> <d ...

The EJS is throwing an error because it cannot define the property "round" on an undefined object

I'm currently delving into the realm of Node.js, using the "Secrets of Ninja" book as my guide. I've come across an EJS program in the book that I copied verbatim to run, but I encountered an error despite not making any modifications to the code ...

What is the process for converting this code to HTML format?

I am new to programming and I am using an API with node.js to display the result in a browser. The API is working fine with console.log, but I want to render it on the browser instead. I am using Jade template for this purpose. How can I write the code t ...

Showing nested arrays in API data using Angular

I would like to display the data from this API { "results": [ { "name": "Luke Skywalker", "height": "172", "mass": "77", & ...

What is the best way to send a JSON object in Vue.js?

<template> <div id="app"> <div id="bee-plugin-container"></div> </div> </template> <script> // import axios from "axios"; // import Bee from "@mailupinc/bee-plugin"; import $ from 'jquery' ...