0

RESOLVED

The code I have is completely correct. The problem was that I was referencing a bootstrap.js which was interfering with the CSS. Because my actual code has bootstrap CSS, the script side of bootstrap was messing things up. It was one of the hardest bugs to find! The fix was to remove the bootstrap.js script reference.

I have an array of objects which represents a list of clickable items. In my razor page i iterate thru this array with a @foreach. Inside the loop i am rendering simple html anchor element which is clickable.

When the link is clicked an icon is to be changed (for a toggle effect). I achieve this by changing the class attribute via following way:

Item @item.Name

The issue is that when i click on one link, all other links are getting the same icon rendered. Naturally i thought this was a simple error in the code. But I can see, by using System.Console.WriteLines, that the class names that SHOULD BE APPLIED to each anchor element is CORRECT.

To paraphrase, the class names that should be applied to each anchor looks correct (based on Console outputs). But the actual class name that is rendered is not correct (based on inspecting the DOM).

Now i've looked into loop related issues in Razor/Blazor. So i am aware of the pitfalls there. This is not that kind of problem since i am iterating thru a collection of object references.

Here is a snippet of the code in question:

@foreach (var item in this.MenuItems)
{          
   var classname = item.Class == "collapsed" ? "nav collapsed" : "nav";

   <li>
       <a class="@classname" @onclick="@(() => this.ToggleItemClass(item))">@item.Name</a>
   </li>
}

// Toggle method
void ToggleItemClass(Item item)
{
   item.Class = (item.Class == "collapse") ? "collapse show" : "collapse";
}
AlvinfromDiaspar
  • 6,611
  • 13
  • 75
  • 140

1 Answers1

2

They are no issues in your (first) code (the current one, with classname var is wrong):

enter image description here

The snipped has no issues and is running for me, try it at blazorfiddle.

@page "/"

<h1>Hello, world!</h1>

@foreach (var item in this.MenuItems)
{          

<li>
    <a class="@item.Class" 
       @onclick="@(() => this.ToggleItemClass(item))">@item.Name @item.Class
    </a>
</li>
}

@code {

    public class Item
    {
        public string Class {set; get;} = "blue";
        public string Name {set; get;} = "Item";
    }
    public List<Item> MenuItems = new List<Item>()
    {
        new Item(),
        new Item(),
        new Item(),
    };
    // Toggle method
    void ToggleItemClass(Item item)
    {
        item.Class = item.Class == "red" ? "green" : "red";
    }
}
dani herrera
  • 48,760
  • 8
  • 117
  • 177
  • @AlvinfromDiaspar, I changed the answer. – dani herrera Jul 24 '19 at 20:54
  • 1
    Because in `class="@classname"` the `classname` never change. Also, be careful with `collapse` vs `collapsed`. – dani herrera Jul 25 '19 at 03:57
  • You mean there is a possibility classname variable doesn't change, which would prevent Blazor from rendering the difference? – AlvinfromDiaspar Jul 25 '19 at 04:09
  • The classname variable is declared inside the loop. So not sure what you mean by it never changes. – AlvinfromDiaspar Jul 25 '19 at 04:17
  • You set a value to classname in first loop sentence and the var remains with this value forever. No one changes classname value again. You set a string to classname and this string remains on var because you never assign a new string to var again. – dani herrera Jul 25 '19 at 04:53
  • What do you mean the variable is never set again? The variable is declared inside the loop, which means it gets set every loop iteration. If this is not the case then I need to seriously review all of my razor files! – AlvinfromDiaspar Jul 25 '19 at 06:35
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/197000/discussion-between-alvinfromdiaspar-and-dani-herrera). – AlvinfromDiaspar Jul 25 '19 at 17:30
  • You're wrong, @dani. the variable classname is defined at each loop iteration, is assigned a value which is then assigned to the class attribute of the anchor element. This should work just as the first version of the loop should have work... As far as I understand the original code was fine, and the code should have worked, but it didn't.. why ? God knows...Let's move to the next question. Oh, AlvinfromDiaspar, did you see the answer to your previous question ? Weird things also happened there... – enet Jul 26 '19 at 07:07
  • @Issac, thanks about your comment. Are you so kind to fork https://blazorfiddle.com/s/ell2z9s2 with `classname` variable in a runable sample? I would like to see it running to better understand your approach. Thanks. – dani herrera Jul 26 '19 at 08:03
  • Hi @issac, when you have some time, fork blazzorfiddle and show me your code with `classbame` please. I want to understand. – dani herrera Jul 27 '19 at 19:21