2

I am using an <a> tag instead of a button because I need to add the feature that allow user to right click and then open in new tab:

enter image description here

The issue right now is that this tag have an onClick function which simply doesn't run at all when user select open link in new tab. I need this function to run because it would show a warning dialog before navigating to other page. This is the code, any advice would be appreciated!

<a
    mat-flat-button
    class="action"
    [routerLink]="'/sponsor'"
    [queryParams]="{ id: 'sponsorId', viewPk }"
    [disabled]="isLoading || dataLength === 0 || !isFiltering"
    (click)="onClickNavigateToPageX()"
  >
    <mat-icon svgIcon="graph" class="icon"></mat-icon>
    See graph
  </a>

3 Answers 3

2

I can't say what's the best solution for the particular use case, but there are various points to consider when deciding what's the best tradeoff:

  • the decision to use an a or button tag should not be determined by the presence of the menu. One is a navigational element and the other is used to perform actions on the page. If it's a navigation on a website, <a> is probably the right tag.
  • the context menu is a browser "thing" and it's in the control sphere of the user. Depending upon your site's philosophy you should not mess up with the browser's basic functionality.
  • when the user navigates away from your page, the browser will trigger the beforeunload event, which will trigger when the current page is being closed. It is a browser's native functionality (the same you get here on StackOverflow when you leave a page with unsaved changes), so it's not customizable in style, but it suits more an HTML-first approach. If you need an 'unsaved changes' message, this is the usual way to go.
  • you can use good ol' window.open with target _blank in a button javascript handler if you want to expose a button with the open in new tab functionality. This way you stay in your JavaScript context and can do whatever you need.
  • if you want more of a Single Page Application style, you can replace the native context menu with something else, as suggested, but you have to evaluate if you are building an application or a website. I like the websites I use to behave like websites and do not interfere with my browser's basic capabilities. YMMV.

Probably there are more considerations worth taking, but this are the ones from the top of my mind.

Sign up to request clarification or add additional context in comments.

Comments

1

You already correctly figured out that it cannot work the way you want. You need an idea, right? Here is it: therefore, you need to modify your design. This way, you can combine both kinds of behavior you need.

One of the different possible solutions could be this: on your <a> element, you can handle the event "contextmenu". In the handler of this event, you can implement some custom context menu, or some equivalent behavior that gives the user the opportunity to choose one of alternative actions. At the same time, if the user simply activates the anchor, the navigation will load a new page according to a href value, and, if the user holds Shift key — in a new tab.

Let's assume for simplicity that the page has only one <a> element:

<a href="https://stackoverflow.com">Stack overflow</a>

Then it could be set up like this:

const anchor = document.querySelector("a"); // or more complicated selector
anchor.addEventListener("contextmenu", event => {
    // activate menu or something, depending on event.target
});

One of the options in this custom context menu could provide the optional side effect you want. One option may be navigation to the page according to anchor's href, but with the call to your side-effect function.

How to implement a custom menu behavior? This is a separate question. I personally have such a component so I can share it. Or you can implement something, depending on what you want.

Another alternative could be a composite control that has two inner elements: <a>, to provide navigation to the page according to href, in a separate tab or not, and another one to provide the choice of action, not necessarily simulating the behavior of a context menu.

You decide.

5 Comments

I know this is not related to the question but can i get your custom context menu
thanks for the solutions, custom right click menu seem like a good idea. This is used in many places in my app, so I guess I will create a directive to handle this
I did not post a custom menu code in the formal answer, because in the past I was blamed for “advertisement” (which is ridiculous for a completely open-source contribution). You can use this repository. Now, the demo shows both a horizontal menu and a vertical context menu — the choice is defined by the menu constructor call. So, will you formally accept my answer now?
@Sriram Prasanth — my custom context menu? Sure, please see my previous comment.
By the way, the discussion on the menu repository is now open.
0

You could use CanDeactivate guard built into to angular. a use case in this blog here: https://medium.com/@altamashali/angular-candeactivate-guard-e9069e1adf0f

We have a NavigateAwayService in our app that utilises this. for when we want to show a popup saying "You have unsaved changes / are you sure?" when a user tries to navigate forward or back or close the browser tab.

1 Comment

In this case the user can open the link in new tab, I don't think the guard can handle that?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.