0

I want each card I dynamically generate to have its own clickable caret to expand more details about the object.

The method I've tried so far doesn't work and doesn't throw any errors:

@foreach (Person person in people)
{
    bool showFullDetails = false;
    <div class="card">
        <div class="card-body">
            <span @onclick="()=> showFullDetails = !showFullDetails" class="@(showFullDetails ? "oi oi-chevron-down" : "oi oi-chevron-right")"></span>

            <span>@person.Type.TypeName</span>
            <span>@person.FirstName @person.LastName</span>

            @if (showFullDetails)
            {
               <div>@person.Age  - @person.Email</div>
            }
        </div>
    </div>
}

Image of an html representation of a list of people each with a clickable caret to expand for more details

3
  • Does @onclick="@(e => showFullDetails = !showFullDetails)" work? Commented Aug 30, 2021 at 19:25
  • Try to move the onclick to the div card-body. In case it works use a div around spans Commented Aug 30, 2021 at 20:10
  • @NicolaBiada & gserg Looks like the issue was the template defined boolean showFullDetails - every time the view is re-rendered the boolean is too Commented Aug 30, 2021 at 20:28

1 Answer 1

1

You cannot define working variables in blazor like that. They must be specified in the @code section. All variables need to be predefined. Below are two examples of how you can show it.

One at a time:

<span @onclick="HideShowPerson" class="@(showFullDetails ? "oi oi-chevron-down" : "oi oi-chevron-right")"></span>


@if (ShownPerson == person)
{
    ...
}

@code {
    Person ShownPerson = null;
    
    void HideShowPerson(Person person) {
        
        // Check if person is assigned
        if (ShownPerson = person)
        {
            ShownPerson = null;
        } else {
            ShownPerson = person;
        }
    }
}

If you want to show multiple at the same time

@if (personList.Contains(person))
{
    ...
}

@code {
    // Person List
    List<Person> personList = new List<Person>();
    
    void HideShowPerson (Person person) 
    {
        if (personList.Contains(person))
        {
            personList.Remove(personList);
        } else {
            personList.Add(personList);
        }
    }
}
Sign up to request clarification or add additional context in comments.

7 Comments

I added some Console.PrintLine() statements and you're 100% right. Every time the view is-rerendered aka after a click, the showDetails boolean is re-initialized to 'false'. So even though the click action is working to re-assign the variable to 'true', the whole view is then immediately re-rendered and showDetails again becomes false.
I mean absolutely no offense and thank you for providing an alternative but it feels like your suggestion of removing & adding persons to the list is a clunky work-around when I don't want to alter the list at all.. I wish there was a better blazor wasm way to achieve the dynamic show-hide
@Jake I think if you add a variable to the Person itself called visible, that can work. Other than that you can change the list you are looping through to a List<(Person person, bool visible)> and loop through that and change the visible part when approproiate.
You cannot define working variables in blazor like that - the documentation seems to disagree.
@GSerg, No. In the documentation it is assigning a pointer to an existing variable. In the example showed it is creating a pointer to i defined in the for loop. What @Jake did in the above code is define a new variable outside the code scope. If it wasn't in a @if or @for section that code would show up as text - which it should have done in the code section anyway. You can test it with the following code ` @if (true) { int buttonNumber = 0; <button @onclick="() => buttonNumber++"> @buttonNumber </button> }. You'll see the value never gets updated. Though it doesn't throw an error.
|

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.