Search code examples
blazormudblazor

How to override onExpand and onClick for MudExpansionPanel on MudBlazor


I am trying to invoke GetComments function when I click on the expansion panel, I have two issues with this, first is that the panels are not closing when I click to open another panel, and second is that I cannot invoke the function to get the data and display.

This is semi-pseudo code on what I am trying to achieve, but I think it is not entirely correct, because firstly MudExpansionPanel doesn't have an OnClick prop, and second is that from this question, first I would need to override @onclick:....

<MudExpansionPanels MultiExpansion="true">
  @foreach (var blog in blogs)
  {
    <MudExpansionPanel Text="@blog.Title" Onclick="() => GetComments(blog.Id)">
      @foreach (var item in data.Response)
      {
        <p>@item.Comment</p>
        <p>@item.Author</p>
      }
    </MudExpansionPanel>
  }
</MudExpansionPanels>

And this is the data that I want to be populated when GetComments has been called with the given Id.

private CommentsDto data;

private async Task GetComments(int itemId)
{
    Query.Id= itemId;
    data = await Mediator.Send(Query);
}

Has anyone tried to do the same thing, or similar, your feedback would be greatly appreciated.


Solution

  • It's best not to apply events such as @onclick directly to components, especially 3rd party components. As components are made up of one or more HTML elements and you will not know which element you're attaching the event to.

    Instead you should use the properties that components expose. Such as the IsExpandedChanged EventCallback.

    e.g. If you don't have any additional parameters required in your method then the payload of the EventCallback<bool> i.e. bool will implicitly be declared when you assign the method.

    <MudExpansionPanels>
        <MudExpansionPanel IsExpandedChanged="ExpandedChanged">
            <!-- content -->
        </MudExpansionPanel>
    </MudExpansionPanels>
    @code {
        private async Task ExpandedChanged(bool newVal)
        {
            // some custom logic
        }
    }
    

    However, since you have additional parameters required in your method then you have to explicitly pass the changed value, along with the additional parameters.

    <MudExpansionPanels MultiExpansion="true">
      @foreach (var blog in blogs)
      {
        <MudExpansionPanel Text="@blog.Title" 
          IsExpandedChanged ="(bool changedVal) => GetComments(changedVal,blog.Id)">
            @data
        </MudExpansionPanel>
      }
    </MudExpansionPanels>
    
    @code {
        private record Blog (string Title, int Id);
        List<Blog> blogs = new()
        {
            new("One",1),
            new("Two",2),
            new("Three",3)
        };
        string data = "no data";
    
        private void GetComments(bool newVal,int itemId)
        {
            if(newVal)
            {
                data = $"Data changed with item:{itemId}";
                Console.WriteLine("only when its expanded");
            }
            Console.WriteLine("Method end");
        }
    }
    

    Demo 👉 MudBlazor Snippet