33

In Blazor I have an <a> element that has both a href and an onclick method:

<a href="" onclick="@(() => ChangePage(_someObject))">Test</a>

onclick calls this method:

  private bool ChangePage(object objectToDisplay)
  {
    _currentObject = objectToDisplay;
    StateHasChanged();

    return false;
  }

Normally in JavaScript returning false from the event method stops the subsequent navigation to the link in the href but this doesn't seem to be working with my code above.

How can I stop Blazor changing the page to the root url after the link is clicked?

(The obvious answer here would be to remove the href altogether, but I'm using the link in a bootstrap Pill and removing the href stops the Pills working)

Other things I've tried that didn't work:

  • Changing the <a> element to a span and setting the data-target attribute, but that stops the Pills rendering properly.
  • Adding return into the onclick event (as per this answer): onclick="return @(() => ChangePage(_overviewModel))" but that doesn't compile.
  • Adding return after the onclick event: onclick="@(() => ChangePage(_overviewModel)); return false;" but that doesn't compile either.
  • using a Blazor NavLink component <NavLink href="" onclick="@(() => ChangePage(_someObject))">NavLink</NavLink>. That doesn't work, see here for more on that.
tomRedox
  • 24,242
  • 20
  • 108
  • 147

5 Answers5

85

The way to do it after release 3.1 of ASP.NET Core seems to be

<a href="" @onclick="@SomeAction" @onclick:preventDefault />
Antonio Correia
  • 1,005
  • 1
  • 15
  • 21
Stilgar
  • 21,249
  • 9
  • 61
  • 99
7

You could try adding the javascript void method to the href.

<a href="javascript: void(0);" onclick="@(() => ChangePage(_someObject))">Test</a>

simpleman
  • 143
  • 7
  • Excellent, that's got the event working without then navigating to the href. The link is also behaving correctly in a Bootstrap pill too. – tomRedox May 17 '19 at 10:47
  • This is a hacking and temporary solution, of course. The use of href="javascript: void(0);" is considered abusive and is repudiated. Needless to say that JavaScript functions should not be embedded in Blazor code... There is one way to call a JavaScript from Blazor: JS Interop. – enet May 17 '19 at 13:20
  • @Issac, yes absolutely re avoiding JS. I've added some notes in the original question to reflect that. – tomRedox May 17 '19 at 13:40
  • This will work, but for .net 6, you will need to put @onclick="@(() =>Method())". Using just onclick will apply onclick as an attribute, like 'class=', and it will not work. – Brandon Dekker Mar 29 '22 at 11:54
6

Currently you can't control event propagation in Blazor. This feature will be available in the next preview, which is preview 6. You can see the relevant issue on GitHub, https://github.com/aspnet/AspNetCore/issues/5545.

As you have found the pills in bootstrap are styled based on the elements used hence why swapping the a tag for another breaks things.

I think your options right now are either wait for preview 6 or rewrite the pills yourself.

Chris Sainty
  • 6,955
  • 1
  • 35
  • 55
  • Ah yes of course, I've already been down the event propagation rabbit hole with something else, but it didn't occur to me this was another instance of the same sort of thing. Thanks Chris, and thanks for the heads up that this should be in preview 6, I hadn't spotted that. – tomRedox May 17 '19 at 10:08
  • No problem, glad to help. – Chris Sainty May 17 '19 at 10:08
3

This has been finally fixed.

<a style="text-underline-position:below; cursor:pointer" @onclick="(() => CloseValidation())">x</a>
Fahad Mullaji
  • 1,252
  • 5
  • 15
  • 30
0

I had the same problem, and didnt like the idea of adding the extra onclick:preventDefault

I also want to avoid adding javascript and seeing how much blazor and C# I can use.

So i used a button instead. I get the cursor on hover over and it acting as I would like.

<button class="btn btn-primary" @onclick="ChangePage">
   Test
 </button>
Ashley Kilgour
  • 957
  • 2
  • 14
  • 29