0

I am iterating through a LARGE list of objects all of which will open the same modal window that will be loaded with dynamic information. To make this work, I create a counter called MenuCounter that I know increments just fine.

That said, I am attempting to wrap a hyperlink around the icons I need to use and the injection of the method keeps pointing to the last value of the MenuCounter.

I first tried this:

<a href="#" onclick="@(() => SetupChangeName(MenuCounter))" class="menuButton">...</a>

When I ran into the issue, I tried reducing the code to the following but then the page somehow activates the hyperlink and the modal window appears and will not go away.

<a href="#" onclick="SetupChangeName(MenuCounter)" class="menuButton">...</a>

Can somebody please help me out?

Thank you!

Ken Tola
  • 93
  • 1
  • 1
  • 9
  • Please clarify: Is SetupChangeName a C# or a JS function? – H H Nov 16 '21 at 09:40
  • [Polite :-)] To do anything other than make some serious/wild assumptions about 99% of the context code, can you please put up a reproducible example of your problem. Two anchors with no context isn't very helpful! – MrC aka Shaun Curtis Nov 16 '21 at 09:45

2 Answers2

0

I'm not a fan of onclick attributes, but if you're set on this method, I believe you just need to santize the C# and JS in the same line like this:

<a href="#" onclick="SetupChangeName('@MenuCounter')" class="menuButton">...</a>

Adding the quotes will ensure at least an empty string is present for JS, and then you can process it.

Alternative method

Since mixing languages like that is quite frustrating, I find it easier to use data tags, for example

<a href="#" data-menu-counter="@MenuCounter" class="menuButton">...</a>

And then in your JS file:

var links = document.querySelectorAll('[data-menu-counter]');
links.forEach(x => x.addEventListener('click', /* your function code here */);
John Pavek
  • 2,595
  • 3
  • 15
  • 33
  • Yeah - I am a backend coder, all of this frontend code is Greek to me and I am just suffering through until I can obtain funding for my startup and hand this effort off to actual experts. – Ken Tola Nov 16 '21 at 16:06
  • @Ken Tola, I'm originally a backend coder as well, and shifting to frontend was not easy at first...it's much more difficult. Nowadays, however, frameworks like Blazor are intended to make backend user code to the web with the language they use in the backend (as for instance, C#). – enet Nov 16 '21 at 20:15
0

You should apply a lambda expression to the Blazor @onclick directive instead of using the onclick Html attribute, in which case it should call a JS function, which you did not mean.

Note that I've introduced a new directive to prevent the default action of the anchor element: @onclick:preventDefault

Test this code:

@page "/"


<a href="#" @onclick:preventDefault @onclick="@(() => SetupChangeName(MenuCounter))" >Click me...</a>

 <div>Counter is @output</div>
@code
{
    private int MenuCounter = 10;
    private int output;

    private void SetupChangeName (int counter)
    {
        output = counter;
    }
}

Note: If you use a for loop to render a list of anchor elements, you must define a variable local to the loop, and provide it as the input to your lambda expression, something like this:

@for(int MenuCounter = 0; MenuCounter < 10; MenuCounter++)
{
   int local= MenuCounter; 
   <a href="#" @onclick:preventDefault @onclick="@(() => 
       SetupChangeName(local))" >Click me...</a> 
}

otherwise, all the lambda expressions will have the the same value for MenuCounter, which is the value incremented for the last iteration. See For loop not returning expected value - C# - Blazor explaining the issue.

enet
  • 41,195
  • 5
  • 76
  • 113
  • 2
    Thank you so much for your answer! I am a backend coder, owner of a cyber startup, and I have not coded on the frontend since my manual HTML days! Building middleware is a joke but I never even heard of Blazor/Razor before last week. I have a TON of respect for your expertise! – Ken Tola Nov 16 '21 at 16:04