browser icon indicating copy to clipboard operation
browser copied to clipboard

Unable to preventDefault on 'a' tag in Browser.application

Open michaeljones opened this issue 5 years ago • 2 comments

I've been struggling with using preventDefault to stop an a tag with href from navigating to that page. I would like to stop it and do a Browser.Navigation.replaceUrl instead in this one place.

Unfortunately due to this code in Browser and this code in virtual-dom we have very little control over the event that is driving the navigation. I can add preventDefault to my event listener but not to the core Elm one.

I'm not sure what the solution is but it seems like their needs to be client control over whether or not the default behaviour is executed and there doesn't seem to be at the moment.

Example

I have created a gist with the issue here: https://gist.github.com/michaeljones/0bb4ffabcdf97b3c757004449009ce43

Work around

Due to this line if we don't want the UrlRequest to come back into the application then we can add a target to the node and that should avoid that. I guess it doesn't matter what the target it is the intention is to suppress the behaviour but _self is the default value so that should cause the fewest issues.

michaeljones avatar Apr 03 '19 18:04 michaeljones

Thanks @michaeljones for raising this issue (Elm 0.19). I've just run into the same problem. Your target="_self" trick works well for the time being.

woochica avatar Apr 05 '20 16:04 woochica

Another solution was suggested in a StackOverflow post.

The solution is to add another pattern to update which matches on empty external URL, where we simply do nothing instead of trying to load the URL as we normally would with other external URLs. In regards to the question's example the following updated update function should do the trick:

update msg model =
   case msg of
       UrlRequested (Browser.Internal _) ->
           ( model, Cmd.none )

       UrlRequested (Browser.External "") ->
           ( model, Cmd.none )

       UrlRequested (Browser.External url) ->
           ( model, Browser.Navigation.load url )

       UrlChanged _ ->
           ( model, Cmd.none )

woochica avatar Nov 03 '21 13:11 woochica