Passing arguments from an Angular directive to a controller function within an element's HTML

Is there a way to pass the URL of an anchor tag in the directive to the controller function "itemClicked"? The code below successfully logs the "post" object when clicked.

HTML:

<div ng-repeat="post in posts" >
    <div find-urls link-clicked="itemClicked(post)" ng-bind="post.content"><div>
</div>

Controller:

$scope.itemClicked = function(post) {
  console.log(post);
};

Directive:

function findUrls($compile) {
  return {
    restrict: 'AC',
    scope: {
        linkClickedCallback: '&linkClicked'
    },
    link: function (scope, elem, attrs) {
      if (attrs.ngBind) {
        scope.$watch(attrs.ngBind, _.debounce(wrapUrls));
      }
      if (attrs.ngBindHtml) {
        scope.$watch(attrs.ngBindHtml, _.debounce(wrapUrls));
      }

      function wrapUrls(text) {
        var linkPatterns = new Array({
          pattern: /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,
          template: '&nbsp;<a class="absolute_link" href="$1" target="_blank">$1</a>'
        },
        {
          pattern: /(^|[^\/])(www\.[\S]+(\b|$))/ig,
          template: '&nbsp;<a class="absolute_link" href="http://$2" ng-click="linkClickedCallback();" target="_blank">$2</a>'
        },
        {
          pattern: /([a-z0-9._-]+@[a-z0-9._-]+\.[a-zA-Z0-9._-]+)/ig,
          template: '&nbsp;<a class="absolute_link" href="mailto:$1" ng-click="linkClickedCallback();" target="_blank">$1</a>'
        },
        {
          pattern: /(^|[^a-z0-9@\\\/._-])([a-z0-9]{0,256}\.(com|net|org|edu)([a-z0-9\/?=\-_#]{0,256})?(\b|$))/ig,
          template: '&nbsp;<a class="absolute_link" href="http://$2" ng-click="linkClickedCallback();" target="_blank">$2</a>'
        });

        var html = elem.html();
        var newHtml = html;

        linkPatterns.forEach((item) => {
          newHtml = newHtml.replace(item.pattern, item.template);
        });

        if (html !== newHtml) {
          elem.html(newHtml);
          $compile(elem.contents())(scope);
        }
      }
    }
  };
}

Answer №1

Implementing this functionality is a breeze using $scope.$emit and $scope.$on.

If you want to pass a URL from your directive:

scope.$emit('passUrl', urlToPass);

In your controller, you can listen for the event like this:

$scope.$on('passUrl', function (event, data) {
  $log.debug(data); // receiving urlToPass variable from the directive
})

Answer №2

After some troubleshooting, I realized that the key element I was overlooking was how to properly pass arguments to the linkClickedCallback function in the controller. It's essential to pass the arguments as an object {arg1: 5, arg2: 10} and then include them in the function call within the HTML in the correct order to transmit them to the controller.

To address this issue, I created an object {link: 1} to be passed into linkedClickedCallback with a hardcoded value of 1. The output of the example now displays the value 1 followed by the "post" object defined in the HTML.

HTML:

<div ng-repeat="post in posts" >
    <div find-urls link-clicked="itemClicked(link, post)" ng-bind="post.content"><div>
</div>

Controller:

$scope.itemClicked = function(link, post) {
  console.log(link);
  console.log(post);
};

Directive:

function findUrls($compile) {
  return {
    restrict: 'AC',
    scope: {
        linkClickedCallback: '&linkClicked'
    },
    link: function (scope, elem, attrs) {
      if (attrs.ngBind) {
        scope.$watch(attrs.ngBind, _.debounce(wrapUrls));
      }
      if (attrs.ngBindHtml) {
        scope.$watch(attrs.ngBindHtml, _.debounce(wrapUrls));
      }

      function wrapUrls(text) {
        var linkPatterns = new Array(
        {
          pattern: /(^|[^\/])(www\.[\S]+(\b|$))/ig,
          template: '&nbsp;<a class="absolute_link" href="http://$2" ng-click="linkClickedCallback({link: 1});" target="_blank">$2</a>'
        },
        {
          pattern: /([a-z0-9._-]+@[a-z0-9._-]+\.[a-zA-Z0-9._-]+)/ig,
          template: '&nbsp;<a class="absolute_link" href="mailto:$1" ng-click="linkClickedCallback({link: 1});" target="_blank">$1</a>'
        },
        {
          pattern: /(^|[^a-z0-9@\\\/._-])([a-z0-9]{0,256}\.(com|net|org|edu)([a-z0-9\/?=\-_#]{0,256})?(\b|$))/ig,
          template: '&nbsp;<a class="absolute_link" href="http://$2" ng-click="linkClickedCallback({link: 1});" target="_blank">$2</a>'
        });

        var html = elem.html();
        var newHtml = html;

        linkPatterns.forEach((item) => {
          newHtml = newHtml.replace(item.pattern, item.template);
        });

        if (html !== newHtml) {
          elem.html(newHtml);
          $compile(elem.contents())(scope);
        }
      }
    }
  };
}

I still have some refining to do in terms of capturing and passing dynamic link values instead of a static "1," but this demonstration lays out the necessary steps for achieving this goal.

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

What is the best way to transform the request query id = ' [12eetftt76237,jhgasduyas7657] ' into an array of elements or strings like [12eetftt76237,jhgasduyas7657]?

Hey there, I am working on a project using hapijs and typescript. I have a requirement to send an array of IDs as parameters through the request URL. Here is an example of the URL: localhost:3444/?id='[askjajk78686,ajshd67868]' I attempted to u ...

Transforming JQuery text upon selecting preloaded content with fire

When I copy the first name into the last name field, everything works fine for new names on the page. However, once a few names have been entered and the browser starts showing a history of names, the function doesn't work anymore if a pre-filled or o ...

Verify your identity using Google reCaptcha during Passport authentication

I am currently working on integrating google reCaptcha into my signup form's back-end, which already includes passport authentication. The code I have so far looks like this: app.get('/signup', function(req, res) { // render the ...

Having trouble understanding why adding raw HTML is yielding different results compared to generating HTML using jQuery

I need assistance with two jsFiddles: http://jsfiddle.net/kRyhw/3/ http://jsfiddle.net/kBMSa/1/ In the first jsFiddle, there is code that adds HTML to my ul element, including an 'X' icon in SVG format. Attempting to recreate this functionali ...

Demonstrate how to pass a newline character from Ruby on Rails to JavaScript

I am working with a .js.erb file that is activated by a JavaScript function. Within this js.erb file, I have the following snippet of code: event = <%=raw @event.to_json %> $('#preview-event-body').html(event.body); The value of event.bo ...

How to efficiently eliminate duplicates from an array list using React framework

Keeping the array name constant while duplicating and repeating this process only clutters the list. Appreciate your help. setListItems(contents.data); console.log(contents.data); ...

Stopping the Game Loop in Windows Phone 8.1 with WinJS

Despite everything working smoothly, I am facing an issue with stopping the game loop when the Start button is pressed and the app is moved to the background. The event handler for suspend, app.oncheckpoint = function(args) {}, does not seem to fire for t ...

Issue encountered when employing the spread operator on objects containing optional properties

To transform initial data into functional data, each with its own type, I need to address the optional names in the initial data. When converting to working data, I assign a default value of '__unknown__' for empty names. Check out this code sni ...

"Converting circular structure into JSON" - Inserting BigQuery Data using Cloud Function in Node.js

I am currently facing an issue while attempting to load an array of JSON objects into a BigQuery Table from a Cloud Function built in NodeJS. Despite not having any circular references, I encountered the error message "Converting circular structure to JSON ...

Unable to modify the bar's color using the .css document

Below is the JavaScript code being used: var marginEducation = {top: 20, right: 30, bottom: 40, left: 300}, widthEducation = 1000, heightEducation = 460; const svgEducation = d3.select("#Education") .append("svg") .attr("w ...

The accordion feature fails to function properly when incorporated into an ajax response

When I click a button, an Ajax response is loaded. The response is successfully appended where it should be, but the issue arises with the accordion not working for the response part. Below is the structure of my response: <div class="articles-content ...

Incorporate an image into your webpage with the Fetch API by specifying the image link - JavaScript

I've been attempting to retrieve an image using the imageLink provided by the backend server. fetchImage(imageLink) { let result; const url = `https://company.com/internal/document/download?ID=${imageLink}`; const proxyurl = 'https:/ ...

Combining various postponed JavaScript file imports in the HTML header into a single group

I've been facing an issue with my code structure, particularly with the duplication of header script imports in multiple places. Every time I need to add a new script, I find myself manually inserting <script type="text/javascript" src=&q ...

What could be causing the lack of data to be returned by jQuery.getJSON?

I've come across this method: function getUserName(guid) { var name = "Unknown"; $.getJSON(urlCurrent, { "method" : "get_user_info", "guid" : guid, "auth_token" : temporaryAuthToken }, function(data) { if ...

Having trouble publishing project on Vercel because of a naming issue

Whenever I try to deploy a project on vercel, I encounter an error stating that the project name is not valid. The specific error messages are as follows: Error: The name of a Project can only contain up to 100 alphanumeric lowercase characters and hyphe ...

The attempt to decode the string from POST using json_decode failed due to a hang-up in

I'm currently learning about PHP, JSON, and JavaScript. I am facing an issue with using the json_decode function in PHP after receiving a JSON string from JavaScript. I am able to save the JSON string to a file without any problem, but when I try to ...

Populate an array with the present date and proceed in reverse order

In my code, there is an array that has a specific structure: var graphData = [{ data: [[1, 1300],[2, 1600], [3, 1900], [4, 2100], [5, 2500], [6, 2200], [7, 1800]} I want to replace the numbers in the first element of each sub-array with the corresponding ...

How come my form isn't functioning properly on mobile devices?

I recently downloaded a form from the website and integrated it within my desktop site successfully. However, when accessed on mobile devices, specifically iOS, the submit button changes to "sending ..." and the form gets stuck without displaying any erro ...

Wait for a for loop to finish before triggering a function in Node.js

Hey there! I'm a newbie when it comes to node.js and I feel like I'm stuck in callback hell at the moment. I've gone through various similar questions but still struggling to make my code work properly. Basically, what I'm trying to do ...

jQuery's outerHeight() and height functions may experience flickering or fail to update properly when the window is resized to an odd number

Two elements are placed side by side on a webpage. One element, with a fixed size of 100vh, is named .hero-half, while the other element, holding text of varying lengths, is fluid and labeled as .project-details. When the text container extends beyond the ...