I use List Box to replace List View to make custom grid filter.
The whole code of filter component is the next (and a few css separately):
@typeparam T
@using Syncfusion.Blazor.Inputs
@using Syncfusion.Blazor.DropDowns
@inherits OwningComponentBase<ApplicationDbContext>
@if (DataSource != null)
{
@if (DataSource.Count > 7 && !DataSource.Any(r => string.IsNullOrEmpty(r.GetPropertyValue(SearchHere)?.ToString())))
{
<div class="filter-search">
<SfTextBox Placeholder="@PlaceHolder" Input="@OnInput" />
</div>
}
<SfListBox @ref="@FilterListBox" TValue="int?[]" TItem="T" DataSource="@FilterSource" CssClass="filter-list m-0">
<ListBoxFieldSettings Text="@SearchHere" Value="@Id" />
<ListBoxSelectionSettings Mode="SelectionMode.Single" />
<ListBoxEvents TValue="int?[]" TItem="T" Created="@OnCreated" ValueChange="@OnSelected" />
<ListBoxTemplates TItem="T">
<ItemTemplate>
<div class="e-list-wrapper">
@((MarkupString)context.GetPropertyValue(ShowThis)?.ToString())
</div>
</ItemTemplate>
</ListBoxTemplates>
</SfListBox>
}
@code {
[Parameter]
public string SearchHere { get; set; } = nameof(DropDownListItem.SearchHere);
[Parameter]
public string ShowThis { get; set; } = nameof(DropDownListItem.ShowThis);
[Parameter]
public string Id { get; set; } = nameof(DropDownListItem.Id);
[Parameter]
public string PlaceHolder { get; set; }
[Parameter]
public T NotSet { get; set; }
[Parameter]
public T Value { get; set; }
[Parameter]
public EventCallback<T> ValueChange { get; set; }
[Parameter]
public Func<ApplicationDbContext, Task<List<T>>> GetDataSource { get; set; }
SfListBox<int?[], T> FilterListBox;
private List<T> DataSource { get; set; }
private List<T> FilterSource { get; set; }
private bool IsCreated { get; set; }
protected override async Task OnInitializedAsync()
{
DataSource = await GetDataSource(Service);
FilterSource = NotSet == null ? DataSource : DataSource.Prepend(NotSet).ToList();
}
private void OnInput(InputEventArgs args)
{
FilterSource = DataSource.FindAll(r =>
r.GetPropertyValue(SearchHere).ToString().Contains(args.Value, StringComparison.InvariantCultureIgnoreCase));
if (NotSet != null) FilterSource = FilterSource.Prepend(NotSet).ToList();
}
private void OnCreated(object args)
{
IsCreated = true;
if (Value != null)
FilterListBox.SelectItems(new int?[] { (int?)Value.GetPropertyValue(Id) });
else if (NotSet != null)
FilterListBox.SelectItems(new int?[] { (int?)NotSet.GetPropertyValue(Id) });
}
private void OnSelected(ListBoxChangeEventArgs<int?[], T> args)
{
if (IsCreated || args.Items == null)
{
IsCreated = false;
return;
}
T SelectedItem = args.Value == null ? args.Items.FirstOrDefault(r => r.GetPropertyValue(Id) == null) :
args.Items.FirstOrDefault(r => args.Value.Contains((int?)r.GetPropertyValue(Id)));
if (SelectedItem != null)
ValueChange.InvokeAsync(SelectedItem);
}
}
Everything works well, except one detail. When the Filter is opened and List Box Created, it should to show preselected Value. I to make it using FilterListBox.SelectItems(new int?[] { (int?)Value.GetPropertyValue(Id) }); in OnCreated method. But it is not work. I tried also SelectItemsAsync, @bind-Value and many different parameters for SelectItems method: T, T[], Text property value, string[] { Text property value}, int?.
What is the right way for programmatic selection when TValue="int?[]" TItem="T"?
We are facing the same problem in production. A hotfox would be very much appreciated.
Best regards,
Michel
Contrary to what was announced, the problem was not fixed with the update this week:
https://blazor.syncfusion.com/documentation/release-notes/19.3.56?type=all
Our customer relied on the problem being solved today.
A quick test from my side showed that the problem does not only
occur
with nullable int. It also happens with the non nullable type long as a value.
Please give me an update on when the issue will be fixed or please provide a workaround for this issue.
Regards,
Michel
<SfListBox TValue="int?[]" TItem="T" DataSource="@Vehicles" @ref="ListBoxObj" >
<ListBoxEvents TValue="int?[]" Created="created" TItem="T"></ListBoxEvents>
<ListBoxFieldSettings Text="Text" Value="Text" />
</SfListBox>
@code {
SfListBox<int?[], T> ListBoxObj;
public List<T> Vehicles = new List<T> {
new T { Text = 1, Id = 01 },
new T { Text = 2, Id = 02 },
new T { Text = 3, Id = 03},
new T { Text = 4, Id = 04},
new T { Text = 5, Id = 05},
new T { Text = 6, Id = 06 },
new T { Text = 7, Id = 07},
new T { Text = 8, Id = 08}
};
public class T
{
public int? Text { get; set; }
public int? Id { get; set; }
}
public int?[] Value = new int?[] { 2 , 3 };
private async Task created(object args)
{
await ListBoxObj.SelectItems(Value, true);
}
} |
I use TValue = int?[] because I have not only integer values, but also the null value to clear selection.
When I apply
await FilterListBox.SelectItems(new int?[] { null }, true);
I get the null exception. Please, correct it, the null value should be selected.
Integer values works
Hi Gayathri,
I have updated your package and everything works well few days already. Thank you