-
-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow to return objects from tab buttons #525
Allow to return objects from tab buttons #525
Conversation
@gvreddy04 There is one thing left todo here. I've noticed that the property IsShown does not trigger a a tab activation when the property is changed from outside. |
To reproduce: <Tabs>
@foreach (var customer in customers)
{
<Tab IsActive="selectedCustomer == customer" OnTabClicked="async () => await OnTabClickedAsync(customer)" Title="@customer.CustomerName">
<Content>
<div class="mt-3">
This is the placeholder content for the <b>@customer.CustomerName</b> tab.
</div>
</Content>
</Tab>
}
</Tabs>
@if (selectedCustomer is not null)
{
<div class="mt-3">Selected customer: <b>@selectedCustomer.CustomerName</b></div>
}
<Button Color="ButtonColor.Success">Add customer</Button>
@code {
private List<Customer> customers = new()
{
new Customer(1, "Marvin Klein"),
new Customer(2, "Vikram Reddy"),
new Customer(3, "Bandita PA"),
new Customer(4, "Daina JJ")
};
private Customer? selectedCustomer;
protected override void OnInitialized()
{
selectedCustomer = customers.First();
}
private Task AddCustomerAsync()
{
var customer = new Customer(5, "Hello World");
customers.Add(customer);
selectedCustomer = customer;
return Task.CompletedTask;
}
private Task OnTabClickedAsync(Customer customer)
{
selectedCustomer = customer;
return Task.CompletedTask;
}
} Notice how active tab does not change when |
* Add vertical tabs * Code Format * Tabs - Vertical enhancements * #525 - Tabs - aria-orientation attribute updates --------- Co-authored-by: Vikram Reddy <gvreddy04@gmail.com>
@gvreddy04 did you consider my last comment here? |
@MarvinKlein1508 I missed the scenario. I think a few people asked for dynamic tabs. I'll check. |
Dynamically adding tabs #480 |
@MarvinKlein1508 Now dynamic tabs support added. |
@gvreddy04 that's still not what I mentioned above. I have use-cases where I set For example: <Tabs @ref="tabs">
@foreach (var customer in customers)
{
<Tab Title="@customer.CustomerName"
OnTabClicked="() => OnTabClicked(customer)"
IsActive="selectedCustomer == customer">
<Content>
<div class="mt-3">
This is the placeholder content for the <b>@customer.CustomerName</b> tab.
</div>
</Content>
</Tab>
}
</Tabs>
@if (selectedCustomer is not null)
{
<div class="mt-3">Selected customer: <b>@selectedCustomer.CustomerName</b></div>
}
<Button Color="ButtonColor.Success" Class="mt-3" @onclick="AddCustomer">Add customer</Button>
<Button Color="ButtonColor.Success" Class="mt-3" @onclick="Select2ndCustomer">Select 2nd customer</Button>
@code {
Tabs tabs = default!;
private List<Customer> customers = new() { new(1, "Marvin Klein"), new(2, "Vikram Reddy"), new(3, "Bandita PA"), new(4, "Daina JJ") };
private Customer selectedCustomer = default!;
protected override void OnInitialized() => selectedCustomer = customers.Last();
private void AddCustomer()
{
var count = customers.Count;
var customer = new Customer(count + 1, $"Customer {count + 1}");
customers.Add(customer);
//selectedCustomer = customer; NOTE: this line is not required
tabs.InitializeRecentTab(showTab: true);
}
private void Select2ndCustomer()
{
selectedCustomer = customers[1];
}
private void OnTabClicked(Customer customer) => selectedCustomer = customer;
} What I expect now is tab for customer In my use-case this is triggered when running validation for an object within the list. If the validation has failed I want the tab to open automatically so the user can see the error messages at a glance. To achieve this |
BTW. is there any reason for the control to rely on JavaScript in the first place? Wouldn't it be easier to implement it with vanilla HTML and C#? What I did in previous projects was someting like this: <div class="row">
<div class="col-md-2 mb-3">
<div class="nav flex-column nav-pills" role="tablist" aria-orientation="vertical">
@foreach (var pos in Input.Positions)
{
<button type="button" role="tab" @onclick="() => SelectedPosition = pos" class="@GetTabNavLinkClass(SelectedPosition == pos)" id="pos-tab-@pos.GetHashCode()" data-bs-toggle="pill">(@pos.Id) @pos.Name</button>
}
</div>
</div>
<div class="col-md-10">
<div class="tab-content">
@foreach (var pos in Input.Positions)
{
int posHash = pos.GetHashCode();
<div class="@GetTabClass(SelectedPosition == pos)" id="pos-@posHash" role="tabpanel" aria-labelledby="pos-tab-@posHash">
<p>Content for tab</p>
</div>
}
</div>
</div>
</div> public string GetTabNavLinkClass(bool active) => active ? "nav-link active" : "nav-link";
public string GetTabClass(bool active) => active ? "tab-pane fade active show" : "tab-pane fade"; |
ping @gvreddy04 |
I understand the scenario. The IsActive property is currently used in the OnInitialized stage, which is why it's not working as expected. For now, please use @ref to reference the tabs and then call the appropriate methods. I'll address this issue in version 1.11.0. However, the caveat is that we cannot use both IsActive and the methods to activate any of the tabs simultaneously. |
@gvreddy04 I don't think this is a problem. I think you are either using the activation via tabs or the attribute itself. The attribute might be used more frequently for dynamic tabs though. |
This PR adds a new feature to tabs which allows the user to return a custom object when the nav button of a tab has been clicked.
This is for use-cases where tabs are being used to render content for a list of objects. It's important to know which object is currently selected to adjust some logic on your blazor page.
I've added a short demo as well.
In my case I need this functionality to show a list of positions. Depending on the selected position I display additional information outside of the
Tabs
control.Implementation might not be perfect but it works fine in my case. Feel free to suggest changes.