Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 308 Vote(s) - 3.45 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Select Tag Helper in ASP.NET Core MVC

#1
I need some help with the select tag helper in ASP.NET Core.

I have a list of employees that I'm trying to bind to a select tag helper. My employees are in a `List<Employee> EmployeesList` and selected value will go into `EmployeeId` property. My view model looks like this:

public class MyViewModel
{
public int EmployeeId { get; set; }
public string Comments { get; set; }
public List<Employee> EmployeesList {get; set; }
}

My employee class looks like this:

public class Employee
{
public int Id { get; set; }
public string FullName { get; set; }
}

My question is how do I tell my select tag helper to use the `Id` as the value while displaying `FullName` in the drop down list?

<select asp-for="EmployeeId" asp-items="???" />

I'd appreciate some help with this. Thanks.
Reply

#2
I created an Interface and a `<options>` tag helper for this. So I didn't have to convert the `IEnumerable<T>` items into `IEnumerable<SelectListItem>` every time I have to populate the `<select>` control.

And I think it works beautifully...

The usage is something like:

<select asp-for="EmployeeId">
<option value="">Please select...</option>
<options asp-items="@Model.EmployeesList" />
</select>

And to make it work with the tag helper you have to implement that interface in your class:

public class Employee : IIntegerListItem
{
public int Id { get; set; }
public string FullName { get; set; }

public int Value { return Id; }
public string Text{ return FullName ; }
}

------------
These are the needed codes:

The interface:

public interface IIntegerListItem
{
int Value { get; }
string Text { get; }
}

The `<options>` tag helper:

[HtmlTargetElement("options", Attributes = "asp-items")]
public class OptionsTagHelper : TagHelper
{
public OptionsTagHelper(IHtmlGenerator generator)
{
Generator = generator;
}

[HtmlAttributeNotBound]
public IHtmlGenerator Generator { get; set; }

[HtmlAttributeName("asp-items")]
public object Items { get; set; }

public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.SuppressOutput();
// Is this <options /> element a child of a <select/> element the SelectTagHelper targeted?
object formDataEntry;
context.Items.TryGetValue(typeof(SelectTagHelper), out formDataEntry);

var selectedValues = formDataEntry as ICollection<string>;
var encodedValues = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
if (selectedValues != null && selectedValues.Count != 0)
{
foreach (var selectedValue in selectedValues)
{
encodedValues.Add(Generator.Encode(selectedValue));
}
}

IEnumerable<SelectListItem> items = null;
if (Items != null)
{
if (Items is IEnumerable)
{
var enumerable = Items as IEnumerable;
if (Items is IEnumerable<SelectListItem>)
items = Items as IEnumerable<SelectListItem>;
else if (Items is IEnumerable<IIntegerListItem>)
items = ((IEnumerable<IIntegerListItem>)Items).Select(x => new SelectListItem() { Selected = false, Value = ((IIntegerListItem)x).Value.ToString(), Text = ((IIntegerListItem)x).Text });
else
throw new InvalidOperationException(string.Format("The {2} was unable to provide metadata about '{1}' expression value '{3}' for <options>.",
"<options>",
"ForAttributeName",
nameof(IModelMetadataProvider),
"For.Name"));
}
else
{
throw new InvalidOperationException("Invalid items for <options>");
}

foreach (var item in items)
{
bool selected = (selectedValues != null && selectedValues.Contains(item.Value)) || encodedValues.Contains(item.Value);
var selectedAttr = selected ? "selected='selected'" : "";

if (item.Value != null)
output.Content.AppendHtml($"<option value='{item.Value}' {selectedAttr}>{item.Text}</option>");
else
output.Content.AppendHtml($"<option>{item.Text}</option>");
}
}
}
}

*There may be some typo but the aim is clear I think. I had to edit a little bit.*
Reply

#3
You can also use **IHtmlHelper.GetEnumSelectList.**


// Summary:
// Returns a select list for the given TEnum.
//
// Type parameters:
// TEnum:
// Type to generate a select list for.
//
// Returns:
// An System.Collections.Generic.IEnumerable`1 containing the select list for the
// given TEnum.
//
// Exceptions:
// T:System.ArgumentException:
// Thrown if TEnum is not an System.Enum or if it has a System.FlagsAttribute.
IEnumerable<SelectListItem> GetEnumSelectList<TEnum>() where TEnum : struct;

Reply

#4
In Get:

public IActionResult Create()
{
ViewData["Tags"] = new SelectList(_context.Tags, "Id", "Name");
return View();
}


In Post:

var selectedIds= Request.Form["Tags"];

In View :

<label>Tags</label>
<select asp-for="Tags" id="Tags" name="Tags" class="form-control" asp-items="ViewBag.Tags" multiple></select>
Reply

#5
My answer below **doesn't** solve the question but it *relates* to.

If someone is using `enum` instead of a class model, like this example:

public enum Counter
{
[Display(Name = "Number 1")]
No1 = 1,
[Display(Name = "Number 2")]
No2 = 2,
[Display(Name = "Number 3")]
No3 = 3
}

And a property to get the value when submiting:

public int No { get; set; }

In the razor page, you can use `Html.GetEnumSelectList<Counter>()` to get the enum properties.

<select asp-for="No" asp-items="@Html.GetEnumSelectList<Counter>()"></select>

It generates the following HTML:

<select id="No" name="No">
<option value="1">Number 1</option>
<option value="2">Number 2</option>
<option value="3">Number 3</option>
</select>
Reply

#6
You can use below code for **multiple select**:

<!-- language: asp -->

<select asp-for="EmployeeId" multiple="multiple" asp-items="@ViewBag.Employees">
<option>Please select</option>
</select>
You can also use:

<select id="EmployeeId" name="EmployeeId" multiple="multiple" asp-items="@ViewBag.Employees">
<option>Please select</option>
</select>
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through