Я работаю на стороне сервера blazor. Я столкнулся с проблемой, я не могу применить .multiselect();
множественный выбор на основе веб-API?
Мне нужен множественный выбор как отображение текста server1, server2 при поиске.
при выборе в первый раз, затем сервер1 и во второй раз выберите сервер2, затем server1,server2
что я пытаюсь, как показано ниже:
1 - создать модельные серверы
public class ServerNames
{
[Key]
public int ServerID { get; set; }
[Required(ErrorMessage = "Server name is required")]
public string Server_Name{ get; set; }
}
2 - Реализовать сервис
List<ServerNames> GetSimilarServers(string searchText);
public List<ServerNames> GetSimilarServers(string searchText)
{
var serverNames = _context.ServerNames.Where(p => p.Server_Name.Contains(searchText)).ToList();
return serverNames;
}
3 - вызов службы на веб-API контроллера
[HttpGet]
[Route("/api/ServerNames/GetSimilarServers/{searchText}")]
public JsonResult GetSimilarServers(string searchText)
{
var serversName = _IserverNamesService.GetSimilarServers(searchText);
return new JsonResult(serversName);
}
4 - в компоненте server.razor
я вызываю веб-API, делаю поисковый фильтр
@code
{
private List<ServerNames> SimilarServers{ get; set; }
public async Task<ServerNames> DisplayListServer(string SearchText)
{
var serversLists = await GetSimilarServers(SearchText);
SimilarServers = serversLists.ToList();
}
public async Task<IEnumerable<ServerNames>> GetSimilarServers(string searchText)
{
HttpClient httpClient = new HttpClient();
var response = await httpClient.GetAsync(config["API_URL"] + "ServerNames/GetSimilarServers/" + searchText + "");
if (response.IsSuccessStatusCode)
{
var result = await JsonSerializer.DeserializeAsync<ServerNames[]>(await response.Content.ReadAsStreamAsync(), new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
return result;
}
else
{
return null; //handle the response that was not successful here.
}
}
}
что я пытаюсь
<select class = "form-select">
@if (serversname.Any())
{
<option value = "0">--Select--</option>
@foreach (var serv in SimilarServers)
{
<option value = "@serv.serverID">
@serv.server_Name
</option>
}
}
</select>
Как заставить select принимать множественный текст выбора как server1, server2 и т. д.
Обновленный пост
Мне нужно выпадающее меню принять множественный выбор с флажком поэтому, если я отмечу сервер 1 и сервер 2, тогда сервер1, сервер2
см. изображение ниже
ровно 200 серверов - это точное количество серверов
если что-то не ясно, дайте мне сейчас, пожалуйста
Почему некоторые части кода отсутствуют, например атрибут multiple
в элементе select
? Не совсем понятно, просите ли вы полное решение или просто просите помощи в отношении определенной части кода.
мое решение, которое мне нужно, это раскрывающийся список с множественным выбором с флажком, поэтому, если я отмечу сервер1 и сервер 2, затем сервер1, сервер2
дайте мне знать, если мой результат мне не нужен
Что произойдет, если из ваших результатов поиска будет исключен сервер, который уже выбрал пользователь? Как вы справляетесь с этим? Создать работающий UX не так просто, как кажется на первый взгляд. Для этого решения вам почти наверняка понадобятся два элемента управления: список выбранных элементов и список элементов, которые вы можете выбрать или отменить выбор.
С 200 элементами для выбора вам не нужно беспокоиться о получении отфильтрованного списка при каждом нажатии клавиши. Получите лот и используйте список данных.
Вот мой составной элемент управления, который близок к тому, что, я думаю, вы хотите:
@inject CountryPresenter _presenter
@using System.Linq.Expressions;
@using System.Diagnostics.CodeAnalysis;
<div class = "col-12 col col-lg-4 mb-3">
<label class = "form-labelsm small">@this.Label</label>
<div class = "input-group">
<input type = "text"
list = "@listId"
@bind:get=_currentValue
@bind:set=this.SetValue
placeholder = "@this.PlaceholderText"
@attributes=this.AdditionalAttributes />
<button class = "btn btn-success" disabled = "@_isNotCurrentValue" @onclick=AddCurrentValue>Add</button>
</div>
</div>
<datalist id = "@listId">
@foreach (var option in OptionItems)
{
<option>@option</option>
}
</datalist>
@foreach (var item in _selectedItems)
{
<div class = "m-1 p-1">
<span class = "badge bg-danger" style = "cursor:pointer;" @onclick = "() => this.DeleteItem(item)">Remove</span>
<span class = "ms-4">@item</span>
</div>
}
@code {
[CascadingParameter] private EditContext? _editContext { get; set; }
[Parameter] public string[]? Value { get; set; }
[Parameter] public EventCallback<string[]?> ValueChanged { get; set; }
[Parameter] public Expression<Func<string[]>>? ValueExpression { get; set; }
[Parameter, EditorRequired] public IEnumerable<string> OptionItems { get; set; } = default!;
[Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary<string, object>? AdditionalAttributes { get; set; }
[Parameter, EditorRequired] public string Label { get; set; } = "No Label";
[Parameter] public string PlaceholderText { get; set; } = "Select a Value";
private List<string> _selectedItems = new();
private readonly string listId = Guid.NewGuid().ToString();
private string? _currentValue;
private bool _isNotCurrentValue => _currentValue is null;
public override Task SetParametersAsync(ParameterView parameters)
{
parameters.SetParameterProperties(this);
_selectedItems = new();
if (this.Value is not null)
_selectedItems = this.Value.ToList();
return base.SetParametersAsync(parameters);
}
private void SetValue(string value)
=> _currentValue = value;
private void DeleteItem(string value)
{
if (_selectedItems.Any(item => item.Equals(value)))
{
_selectedItems.Remove(value);
this.NotifyEditContext();
ValueChanged.InvokeAsync(_selectedItems.ToArray());
}
}
private void AddCurrentValue()
{
if (_currentValue is not null && !_selectedItems.Any(item => item.Equals(_currentValue)))
{
_selectedItems.Add(_currentValue);
_currentValue = null;
this.NotifyEditContext();
ValueChanged.InvokeAsync(_selectedItems.ToArray());
}
}
private void NotifyEditContext()
{
if (ValueExpression is not null && _editContext is not null)
{
var fi = FieldIdentifier.Create(ValueExpression);
_editContext?.NotifyFieldChanged(fi);
}
}
}
Демонстрационная страница
@page "/"
@inject CountryPresenter _countryPresenter
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
<div class = "mb-3">Welcome to your new app.</div>
<MultiSelectControl class = "form-control"
Label = "Select Countries"
@bind-Value=_countryPresenter.SelectedCountries
OptionItems=_countryPresenter.CountryList />
@*Display the data*@
<div class = "bg-dark text-white p-2 mt-5">
@if (_countryPresenter.SelectedCountries is not null)
{
@foreach (var item in _countryPresenter.SelectedCountries)
{
<pre>@item</pre>
}
}
</div>
@code {
protected async override Task OnInitializedAsync()
=> await _countryPresenter.LoadingTask;
}
Служба представления, которая управляет данными.
public class CountryPresenter
{
private CountryDataProvider _countryProvider;
public string[]? SelectedCountries { get; set; }
public IEnumerable<string> CountryList = Enumerable.Empty<string>();
public Task LoadingTask { get; private set; } = Task.CompletedTask;
public CountryPresenter(CountryDataProvider countryProvider)
{
_countryProvider = countryProvider;
this.LoadingTask = this.LoadCountriesAsync();
}
private async Task LoadCountriesAsync()
=> this.CountryList = await _countryProvider.GetCountyListAsync();
}
И поставщик данных о стране для наших данных.
public class CountryDataProvider
{
public async ValueTask<IEnumerable<string>> GetCountyListAsync()
{
//Dummy a async DB Call
await Task.Yield();
return CountryArray.AsEnumerable();
}
public static string[] CountryArray = new string[]
{
"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda",
"Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh",
"Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegovina",
"Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory", "Brunei Darussalam", "Bulgaria", "Burkina Faso",
"Burundi", "Cambodia", "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Central African Republic", "Chad", "Chile",
"China", "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo", "Congo, the Democratic Republic of the",
"Cook Islands", "Costa Rica", "Cote D'Ivoire", "Croatia", "Cuba", "Cyprus", "Czech Republic", "Denmark", "Djibouti",
"Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia",
"Falkland Islands (Malvinas)", "Faroe Islands", "Fiji", "Finland", "France", "French Guiana", "French Polynesia", "French Southern Territories",
"Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala",
"Guinea", "Guinea-Bissau", "Guyana", "Haiti", "Heard Island and Mcdonald Islands", "Holy See (Vatican City State)", "Honduras",
"Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iran, Islamic Republic of", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
"Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Korea, Democratic People's Republic of", "Korea, Republic of", "Kuwait",
"Kyrgyzstan", "Lao People's Democratic Republic", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libyan Arab Jamahiriya", "Liechtenstein",
"Lithuania", "Luxembourg", "Macao", "Macedonia, the Former Yugoslav Republic of", "Madagascar", "Malawi", "Malaysia", "Maldives",
"Mali", "Malta", "Marshall Islands", "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia, Federated States of",
"Moldova, Republic of", "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia", "Nauru", "Nepal",
"Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island",
"Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau", "Palestinian Territory, Occupied", "Panama", "Papua New Guinea",
"Paraguay", "Peru", "Philippines", "Pitcairn", "Poland", "Portugal", "Puerto Rico", "Qatar", "Reunion", "Romania", "Russian Federation",
"Rwanda", "Saint Helena", "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon", "Saint Vincent and the Grenadines",
"Samoa", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Senegal", "Serbia and Montenegro", "Seychelles", "Sierra Leone",
"Singapore", "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa", "South Georgia and the South Sandwich Islands",
"Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden", "Switzerland", "Syrian Arab Republic",
"Taiwan, Province of China", "Tajikistan", "Tanzania, United Republic of", "Thailand", "Timor-Leste", "Togo", "Tokelau",
"Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Uganda", "Ukraine",
"United Arab Emirates", "United Kingdom", "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan", "Vanuatu",
"Venezuela", "Viet Nam", "Virgin Islands, British", "Virgin Islands, US", "Wallis and Futuna", "Western Sahara",
"Yemen", "Zambia", "Zimbabwe",
};
}
Регистрация службы:
builder.Services.AddScoped<CountryDataProvider>();
builder.Services.AddTransient<CountryPresenter>();
Какова длина списка серверов?