Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

[Feature] Extend select tag helper #5584

Closed
joacar opened this issue Nov 30, 2016 · 4 comments
Closed

[Feature] Extend select tag helper #5584

joacar opened this issue Nov 30, 2016 · 4 comments

Comments

@joacar
Copy link

joacar commented Nov 30, 2016

Hi,

What about adding asp-text, asp-value, asp-selected and asp-objects to the tag helper?

This would allow developers to pass a list to the asp-objects and specify the name of the properties that should make up SelectListItem.Text and SelectListItem.Value.

The asp-textand asp-value can be a dot separated to traverse the object to find the correct property.

The asp-selected can take an integer that will will set the Selected property to true.

I will be happy to create a pull request if there is interest or if this has been rejected for some reason.

@frankabbruzzese
Copy link

@joacar ,
asp-selected makes no sense since, at moment select tag helper has already the capability to infer selected element from the value contained in the asp-for property. So basically, your proposal is basically to avoid the usage of new SelectList(......) in asp-items and move all items related information from the constructor of SelectList directly to th tag helper attributes, or better to give the user both options. I like this, since it is more intuitive for the user, but I would like to have both options since, in case several selects have the same option list it is more convenient to compute SelectList once and for all.

@joacar
Copy link
Author

joacar commented Nov 30, 2016

Thanks for pointing me to SelectList! I have used reflection directly to retrieve the values in the 'TagHelper.Init' instead of passning text and value along with objects to 'SelectList'.

My proposal is hence to "include" 'SelectList' functionality in the tag helper by adding the attributes 'text,value,objects'.

(Sent from phone so not sure about code formatting)

@joacar
Copy link
Author

joacar commented Dec 1, 2016

So after some experimenting I've come up with the following. I created a class that holds the text, value and items properties. This can be created in the controller with the nameof-operator to keep refactoring easy. For example

public IActionResult Index()
{
     ViewBag.CountriesDescriptor = new SelectListDescriptor(nameof(Country.Id), nameof(Country.Name), countries);
}

and used in the view

<select asp-for="Country" asp-descriptor="@ViewBag.CountriesDescriptor">
    <option>-- Choose country</option>
</select>

The attributes asp-objects, asp-text and asp-value are left and can be used as well. Not sure how to handle if multiple values are used simultaneously, perhaps throw an exception of some sort.

SelectListDescriptor

public class SelectListDescriptor
    {
        public SelectListDescriptor(string text, string value, IEnumerable items)
        {
            Text = text;
            Value = value;
            Items = items;
        }

        public string Text
        {
            get;
        }

        public string Value
        {
            get;
        }

        public IEnumerable Items
        {
            get;
        }
    }

Modifications to SelectTagHelper

[HtmlTargetElement("select", Attributes = TextAttributeName)]
[HtmlTargetElement("select", Attributes = ValueAttributeName)]
[HtmlTargetElement("select", Attributes = ObjectsAttributeName)]
[HtmlTargetElement("select", Attributes = DescriptorAttributeName)]
public class SelectItemsTagHelper : SelectTagHelper
{
    private const string TextAttributeName = "asp-text";
    private const string ValueAttributeName = "asp-value";
    private const string ObjectsAttributeName = "asp-objects";
    private const string DescriptorAttributeName = "asp-descriptor";



    public SelectItemsTagHelper(IHtmlGenerator generator)
        : base(generator)
    {
    }

    [HtmlAttributeName(TextAttributeName)]
    public string Text
    {
        get;
        set;
    }

    [HtmlAttributeName(ValueAttributeName)]
    public string Value
    {
        get;
        set;
    }

    [HtmlAttributeName(ObjectsAttributeName)]
    public IEnumerable Objects
    {
        get;
        set;
    }

    [HtmlAttributeName(DescriptorAttributeName)]
    public SelectListDescriptor Descriptor
    {
        get;
        set;
    }

    public override void Init(TagHelperContext context)
    {
        base.Init(context);
        if (Objects == null)
        {
            return;
        }
        if (Items != null)
        {
            throw new InvalidOperationException($"Cannot use '{ObjectsAttributeName}' in conjunction with 'asp-items'");
        }
        Items = new SelectList(Descriptor?.Items ?? Objects, Descriptor?.Value ?? Value, Descriptor?.Text ?? Text);
    }
}

@joacar joacar changed the title [Feature request] Extend select tag helper [Feature] Extend select tag helper Dec 1, 2016
@Eilon
Copy link
Member

Eilon commented Dec 27, 2016

Closing because we are not planning to add this feature. If you end up writing your own tag helper that does this, we'd be happy to have a link to it from the readme.

@Eilon Eilon closed this as completed Dec 27, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants