I am using an input list because I need to contain more than 1,000 data and consider mobile users. So I am using it as another attribute to hide the real value.
ex)
<datalist id="list1">
<option realvalue="1">Option1</option>
</datalist>
<input type="text" list="list1" />
@code{
private string list1value;
private void inputchanged()
{
listvalue = ???//datalist realvalue
//etc
}
}
I need to use the real value in code
I want to communicate with DB using real value, but I don't know how to use it even after searching
I'm guessing you want something like a select
control, but using a data list. If so:
Here's my BlazrInputSelectList control that does that.
@using System.Linq.Expressions;
@typeparam TValue
@typeparam TListItem
<InputText @attributes=this.AdditionalAttributes
list="@listId"
Value=@this.selectedValue
ValueChanged=OnChange
ValueExpression="() => this.selectedValue"
placeholder="@this.PlaceholderText" />
<datalist id="@listId">
@foreach (var option in this.DisplayOptionsItems)
{
<option>@(this.OptionDelegateText(option))</option>
}
</datalist>
@code {
[Parameter] public TValue? Value { get; set; }
[Parameter] public EventCallback<TValue> ValueChanged { get; set; }
[Parameter] public Expression<Func<TValue>>? ValueExpression { get; set; }
[Parameter, EditorRequired] public IEnumerable<TListItem> DisplayOptionsItems { get; set; } = default!;
[Parameter, EditorRequired] public Func<TListItem, string> OptionDelegateText { get; set; } = default!;
[Parameter, EditorRequired] public Func<TListItem, string, bool> OptionDelegateFinder { get; set; } = default!;
[Parameter, EditorRequired] public Func<TListItem, TValue> OptionDelegateValue { get; set; } = default!;
[Parameter] public string PlaceholderText { get; set; } = "Select a Value";
[Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary<string, object>? AdditionalAttributes { get; set; }
private string? selectedValue;
private readonly string listId = Guid.NewGuid().ToString();
protected override void OnInitialized()
{
// Check we have all the delegates. If not throw an exception before we try and render a null list
ArgumentNullException.ThrowIfNull(this.DisplayOptionsItems);
ArgumentNullException.ThrowIfNull(this.OptionDelegateText);
ArgumentNullException.ThrowIfNull(this.OptionDelegateFinder);
ArgumentNullException.ThrowIfNull(this.OptionDelegateValue);
}
private async Task OnChange(string value)
{
selectedValue = value;
var item = this.DisplayOptionsItems.FirstOrDefault(item => this.IsItem(item));
if (item is not null)
await this.ValueChanged.InvokeAsync(this.OptionDelegateValue(item));
}
private bool IsItem(TListItem item)
{
if (selectedValue is not null)
return this.OptionDelegateFinder.Invoke(item, selectedValue);
return false;
}
}
You implement it in a form like this. I've shown cached and uncached delegate versions. The second cached version is more efficient [the anonymous methods are rebuilt every time the component renders], but has a little more code.
@page "/"
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
<div class="bg-dark text-white m-2 p-2">
<pre>Selected Guid : @_selectedUid </pre>
<pre>Selected Guid1 : @_selectedUid1 </pre>
</div>
<BlazrInputSelectList class="form-control mb-3"
@bind-Value=_selectedUid
DisplayOptionsItems=this._countries
OptionDelegateText="(item) => item.Name"
OptionDelegateFinder="(item, value) => item.Name.Equals(value, StringComparison.CurrentCultureIgnoreCase)"
OptionDelegateValue="(item) => item.Uid" />
<BlazrInputSelectList class="form-control mb-3"
@bind-Value=_selectedUid1
DisplayOptionsItems=this._countries
OptionDelegateText=this.GetOptionText
OptionDelegateFinder=this.GetOptionFinder
OptionDelegateValue=this.GetOptionValue />
@code {
private List<Country> _countries = new()
{
new(Guid.NewGuid(), "Portugal"),
new(Guid.NewGuid(), "France"),
new(Guid.NewGuid(), "Spain"),
};
private Guid? _selectedUid;
private Guid? _selectedUid1;
public record Country(Guid Uid, string Name);
private string GetOptionText(Country item)
=> item.Name;
private Guid? GetOptionValue(Country item)
=> item.Uid;
private bool GetOptionFinder(Country item, string value)
=> item.Name.Equals(value, StringComparison.CurrentCultureIgnoreCase);
}