In my blazor app I have a component that has a button and a bootstrap collapse controlled by the button. Everything works fine when I only use that component once on a page but if I use it multiple times on a page then the button for one will also trigger the collapse element in the other since their IDs seem to be static. Is there a way around this?
Here is the code for the component
<button class="btn btn-primary form-control" type="button" data-toggle="collapse" data-target="#divCollapse" aria-expanded="false" aria-controls="divCollapse">
@Technician.Name
</button>
<div class="collapse" id="divCollapse">
<div class="card card-body">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Assigned To</th>
</tr>
</thead>
<tbody>
@foreach (var task in _repo.GetTasksByTechnician(Technician).ToList())
{
<tr>
<td>@task.Id</td>
<td>@task.AssignedTo</td>
</tr>
}
</tbody>
</table>
</div>
</div>
@code {
[Parameter]
public Technician Technician { get; set; }
}
Here is the code in the page that I use to create the component:
@foreach (var tech in _technicians)
{
<PersonComponent Technician="@tech"></PersonComponent>
}
You have to assign to your comoponent collapsible part an unique id. Now you've ended with many html elements with the same id on the page, wich is sintactically uncorrect, that's why Bootstrap fails to do it's work.
So you can try to do this:
<button class="btn btn-primary form-control" type="button" data-toggle="collapse"
data-target="#divCollapse@(Technician.Id)" aria-expanded="false" aria-controls="#divCollapse@(Technician.Id)">
@Technician.Name
</button>
<div class="collapse" id="divCollapse@(Technician.Id)">
etc...
That will work given that the each technician should have an Id, or just put any property that identifies each of them uniquely and could be appended to the "#divCollapse" string to create a sinctactically well formed id (no spaces or puntuation signs other than underscores or hyphens).
If the Technician entity doesn't hava a suitable property for that, just define another parameter in the component and inject it from outside:
@for (int idx = 0; idx < _technicians.Length; idx++)
{
int capturedIdx = idx; // <- Necessary to get the loop variable to the context
<PersonComponent Technician="@tech" Identifier="@capturedIdx"></PersonComponent>
}
of course in your component:
[Parameter]
public int Identifier { get; set; }
and then you can use it for appending to "divCollapse" ids.
Hope it helps!