Ways to duplicate ui-sref

I need to create a directive that enables clicks on an outer element to duplicate the ui-sref of one of its inner elements. This means that clicking on the outer element should have the same effect as clicking on the .cloned element.

<div clone-click=".cloned">
    ...
    <a class="cloned" ui-sref="root.a" ng-if="true">example</a>
    <a class="cloned" ui-sref="root.b" ng-if="false">example</a>
    ...
    <a ui-sref="root.c">elsewhere</a>
    ...
</div>

I attempted to create an attribute directive to simulate the click action

app.directive('cloneClick', function() {
    return {
        restrict: 'A',
        scope: {
            selector: '@cloneClick'
        },
        link: function(scope, element) {
            element.click(function() {
                element.find(scope.selector).not(':disabled').first().click();
            })
        }
    };
})

Unfortunately, this resulted in some sort of infinite loop and did not work as intended. How can I fix this issue? Or is there a better approach to achieving the desired functionality?

Answer №1

Consider the concept of event bubbling. Currently, any click on the children will bubble up to the parent and trigger another click on the same element, potentially causing an infinite loop if the intended target is clicked.

My recommendation is to stop the event from propagating on the <a> element.

If the click occurs on the <a> itself, let the browser handle the redirection. If a click happens on any other part of the parent element, utilize the $location service to redirect based on the href value generated by ui-sref.

Here's an example snippet:

link: function(scope, element) {
  var $link = element.find(scope.selector).not(':disabled').first();
  // prevent bubbling on target link
  $link.click(function(e) {
    e.stopImmediatePropagation()
  });

  element.click(function(e) {
    // ensure the target link wasn't clicked
    if (e.target !== $link[0]) { // assumes no child tags in `<a>`
      $location.url($link.attr('href'));
    }
  });
}

You may need to make adjustments depending on your use of html5mode.

EDIT: It just occurred to me that you might be able to trigger the click on the <a> instead of using $location, considering that event propagation is still prevented.

Answer №2

<WIDGET clone-click=".is-clone-click:not(:disabled):not(.is-disabled)">
    <a class="is-clone-click" ui-sref="root.example">example</a>
</WIDGET>

I managed to make it work using this method. Certain disabled elements were clickable due to their container being the e.target so I included .is-no-clone-click on those containers to avoid them.

app.directive('cloneClick', function() {
    var angular = require('angular');
    var ignore = '[href], [ui-sref], [ng-click], .is-no-clone-click, label, input, textarea, button, select, option, optgroup';

    return {
        restrict: 'A',
        scope: {
            selector: '@cloneClick'
        },
        link: function (scope, element) {
            element.click(function(e) {
                if (e.isTrigger) {
                    return;
                }

                var cloned = element.find(scope.selector).first();
                var target = angular.element(e.target);

                if (cloned.length && !cloned.is(target) && !target.is(ignore)) {
                    cloned.click();
                }
            });
        }
    };
});

The cursor can also be changed with mouseover and a corresponding CSS class like

element.mouseover(function() {
    element.toggleClass('is-pointer', !!element.has(scope.selector).length);
});

However, I ultimately did not utilize this directive as I found a solution using CSS link masking technique that effectively addressed my original 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

Utilizing PhP and AJAX for seamless form uploads without the need to refresh the page

I have a form in PHP that reloads after submission. I implemented Ajax to prevent the reloading, but now the data is not being submitted to the database. Am I overlooking something here? When I remove the AJAX, it functions properly but reloads the page. I ...

Decoding Azure table results in Node.js: A comprehensive guide

I need guidance on how to properly parse a query result in Azure using Easy API. I have encountered difficulties with creating an object inside the function(results) since it causes an endless loop and eventually results in a httpcode 500 error. I'm s ...

Vue.js: Issue with applying class binding while iterating over an object

I've been working with an object data that looks like this: object = { "2020092020-08-01":{ "value":"123", "id_number":"202009" }, "2020092020-09-01":{ "value& ...

Identifying modifications in HTML elements triggered by JavaScript

Imagine having a select element with the ID 'test' and an onchange EventListener attached to it that detects changes made by users through both MouseEvents and KeyboardEvents. However, when changing the value programmatically like this: document ...

After refreshing, Angular route using html5Mode leads to a 'Page Not Found' error page

I have created several Angular routes as illustrated in the code snippet below. app.config(function($routeProvider, $locationProvider, $provide) { $routeProvider .when('/', { templateUrl: 'home.html', controll ...

If you scroll quickly, watch out for the flickering of the fadeIn and fadeOut

I have a script that fades in an element once the user scrolls more than 145px from the top of the page. $(window).scroll(function(){ if ($(this).scrollTop() > 145) { $('#fademenu').fadeIn(); } else { $('#fademenu').fadeOut(); } } ...

When utilizing image.width in JavaScript, it returns 0 exclusively when accessed online, but functions correctly when

Recently, I encountered a problem while rendering an image in React. I was using JavaScript to set the image width and applying it to the img style. let img = new Image(); img.src = "image_url"; let i_width = (img.width * 2.54) / 30; <img sr ...

Executing a Data Factory Pipeline using JavaScript

In Azure Data Factory, I constructed a pipeline to transfer data from an Azure Storage Table to an Azure SQL database Table. The Azure Storage Table receives data from a JavaScript chatbot that captures responses and saves them in the table. I want to ini ...

Error message: The compareSync function in Object.bcrypt is indicating that the passed string is undefined. Are there any

Within my rendered Nunjucks template, I have set it up to accept a username and password input from the user. Upon clicking the submit button, the goal is for the system to search through a database in my JavaScript Express file to verify if the entered cr ...

Acquiring the $parent.$index variable within a custom directive

<li ng-repeat="value in array1 track by $index"> <div ng-repeat="j in array2"> <div example-directive > <p> {{$index}} ,{{$parent.$index}}</p> </div> </div> </li> Within t ...

unable to simultaneously scroll two elements

Within the realm of reactjs, I've crafted a function that smoothly scrolls elements by utilizing a useRef: ref.current?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center", }); ...

Optimizing the process of executing and validating values in JavaScript by retrieving MySQL data through AJAX or Cookies

Seeking advice on the most efficient method of retrieving and validating data from a MySQL table using JavaScript. Considering options like AJAX requests to avoid excessive HTTP requests, or storing values in client-side cookies to improve loading speed. C ...

Leveraging trustAsHTML with an array of object elements

I'm facing a challenge in passing an array of objects from an Angular Controller to the ng-repeat directive. The objects within the array have multiple properties, some of which may contain HTML that needs to be displayed using the ng-repeat. I' ...

Authentication with Laravel and Vue.js

After successfully implementing Laravel-Vue.js Authentication using Passport API, I am now able to obtain the token and send requests to api/user. Initially, I used the normal authentication process by sending data through a POST request to /login, which r ...

Having trouble with eliminating trailing whitespace from a string?

I'm confused as to why the output is 'now ' instead of just 'now'. mainQueryString = 'now '; mainQueryString = mainQueryString.replace('/\s+$/g', ''); /* removing the ending space */ console.log( ...

What is the best way to add a CSS style to any element that has the .btn:hover pseudo-class, except for those elements with the class '.dropdown-toggle'?

Is there a way to apply a style to all my .btn elements when hovering, except for those with the .dropdown-toggle class? I've tried a couple of methods but ran into some issues: attempt 1: .btn:not(.dropdown-toggle):hover { background-color: inher ...

Submit button in the contact form fails to refresh upon being clicked

My website features a contact form with mandatory fields that users must fill out. If a user misses a field and is prompted to complete all fields, upon returning to fill everything out and clicking "send," nothing happens. The SEND button becomes unrespo ...

Electron and React: Alert - Exceeded MaxListenersWarning: Potential memory leak detected in EventEmitter. [EventEmitter] has 21 updateDeviceList listeners added to it

I've been tirelessly searching to understand the root cause of this issue, and I believe I'm getting closer to unraveling the mystery. My method involves using USB detection to track the connection of USB devices: usbDetect.on('add', () ...

The responsive dropdown menu is failing to show the elements within the array

My website has a responsive navbar that updates values based on selected tabs. https://i.sstatic.net/Fl6tM.png Now, I'm trying to replicate the same functionality in mobile view by using a select menu instead of a navbar. https://i.sstatic.net/JGrH ...

Separate every fresh anagram of a list element onto its own line

I have been developing an anagram generator and facing a challenge in breaking off each new item in the array into a new line. The process involves slicing each array item and iterating through every character. The desired output should be: cat, cta, act ...