.NET MVC 3 Adding attributes to SelectListItem in

2019-04-30 12:19发布

问题:

So I'm trying to stylize the tag in a dropdown. My MVC helper is set up kind of like this but the real thing pulls from the DB, so the data is not hard coded.

@{
    List<string> ListOfText = new List<string> { "FirstThing","SecondThing","ThirdThing"};
    List<string> ListOfValue = new List<string> { "1","2","3"};
    List<SelectListItems> ListOFSELCETLISTITEMS = new List<SelectListItem>();    

    for (int x = 0; x < 3; x++)
    {
        ListOFSELCETLISTITEMS .Add(new SelectListItem
        {
            Text = ListOfText[x],
            Value = ListOfValue[x],
            Selected = (selectedValue == ListOfValue[x])
        });
    }
}   
@Html.DropDown("NAME",ListOFSELCETLISTITEMS)

This gives me something like

<select id="Name" name="Name">
    <option value="1">FirstThing</option>
    <option value="2">SecondThing</option>
    <option value="3">ThirdThing</option>
</select>

What i need is something like this

<select id="Name" name="Name">
    <option value="1" class="option1">FirstThing</option>
    <option value="2" class="option2">SecondThing</option>
    <option value="3" class="option3">ThirdThing</option>
</select>

I've tried doing things like

@{
    List<string> ListOfText = new List<string> { "FirstThing","SecondThing","ThirdThing"};
    List<string> ListOfValue = new List<string> { "1","2","3"};
}
<select id="Name" name="Name">
    @ for (int x = 0; x < 3; x++)
    {
        <text>
        <option value="@ListOfValue[x]" @{if(selectedValue == ListOfValue[x])
            { @Html.Raw("selected='selected'") }}
            @class = '@Html.Raw("option"+x)'>
            @ListOfText[x]
        </option>
        </text>
    }   
</select>

But this seems to confuse the controller and it doesn't recognize that the dropdown's value above maps to

public ActionResult method(string Name)

in the controller on a post or get. Well the line

 @Html.DropDown("NAME",ListOFSELCETLISTITEMS)

in the view does allow the controller to understand the method should map to that dropdown's value.

How can i do this? Is there a way to unconfuse the controller and be able to hand write HTML without the Html.helpers?

回答1:

To render directly a controller action, you can try :

@{ Html.RenderAction(Action, Controller); }

To invoke your controller action that should be returning a string with your content.

[HttpGet]
public string Action(int id) 
{
   return your context in here
}

However I think it's cleaner to add an Ajax action returning the data for building the select and after having the results, using jquery solution for adding a class (which can be returned in the AJAX response itself)

EDIT: clarification:

Assuming you've got a collection of Item as follows:

class Item {
   public int Value { get; set; }
   public string CssClass { get; set; }
   public string Description{ get; set; }
}
private const string EMPTY_OPTION = "<option value=''></option>";
[HttpGet]
public string Action(int id) 
{
    // Load a collection with all your option's related data
    IQueryable data = LoadSomethingFromDbOrWherever(id);
    // Build output
    StringBuilder sb = new StringBuilder();
    sb.AppendFormat("<select id='foo' name='foo'>");
    sb.AppendFormat(EMPTY_OPTION);
    foreach (Item b in data)
    {
            sb.AppendFormat("<option value='{0}' class='{1}'>{2}</option>",
                            b.Value, b.CssClass, b.Description);
    }
    sb.AppendFormat("</select>");
    return sb.ToString();
}

for ajax option:

[HttpGet]
public JsonResult Action(int id) 
{
   //same as above, obtain a collection
    // Load a collection with all your option's related data
    IQueryable data = LoadSomethingFromDbOrWherever(id);
    var jsonData = new
            {
                    from c in data
                    select new
                    {
                        Value= c.Value,
                        CssClass = c.CssClass,
                        Description = c.Desription
                    }).ToArray()
            };
    return Json(jsonData);
}

Call this via $.ajax and in the callback you'll have a javascript object containing all your data, then use jQuery to build up the select options.

Regards



回答2:

With jquery you can try something like this:

$('#Name option').each(function(){
    var i = $(this).attr('value');
    $(this).addClass('option'+i);
});

(I am still a newbie in jquery, but I tried this and it worked)



回答3:

EDIT: My previous post was linking to incorrect code.

I would suggest that you create your own HTML Helper extension method. This is how I had done it in the past, unfortunately I don't have the code to hand to show an example.

You basically need to create a method that takes your parameters and returns a htmlstring

you would end up replacing

@Html.DropDown("NAME",ListOFSELCETLISTITEMS)

with something like

@Html.MyDropDown("NAME",ListOFSELCETLISTITEMS)

where you are looping the list and creating a correctly formatted html string to return, then you can add as much extra attributes as you want