简体   繁体   中英

MVC dropdown menu of variables

I am working on an MVC4 Project and I'm looking to add a search by dropdown menu so that the user can select different variables to search through.

My Model

 public class BloodStoredModel
{
    [Required]
    public int ID { get; set; }
    [Required]
    [DisplayName("Blood Type")]
    public string bloodType { get; set; }
    [Required]
    [DisplayName("RH Factor")]
    public string rhFactor { get; set; }
    [Required]
    [DisplayName("Last Name")]
    public string donorLastName { get; set; }
    [Required]
    [DisplayName("First Name")]
    public string donorFirstName { get; set; }
    [Required]
    [DisplayName("Address")]
    public string address { get; set; }
    [Required]
    [DisplayName("Phone #")]
    public string telephoneNumber { get; set; }

    public class BloodDBContext : DbContext
    {
        public DbSet<BloodStoredModel> BloodStored { get; set; }
    }
}

Here is my Controller method

public ActionResult SearchIndex(string searchString)
    {
        //string searchString = id;
        var list = new SelectList(new[]
                                      {
                                          new{ID="1",Name="bloodType"},
                                          new{ID="2",Name="rhFactor"},
                                          new{ID="3",Name="donorLastName"},
                                          new{ID="4",Name="donorFirstName"},
                                          new{ID="5",Name="address"},
                                          new{ID="6",Name="telephoneNumber"}
                                      },
                        "ID", "Name", 1);
        ViewData["list"] = list;

        var bloodSearch = from m in db.BloodStored
                     select m;

        if (!String.IsNullOrEmpty(searchString))
        {
            //bloodSearch = bloodSearch.Where(s => s.donorLastName.Contains(searchString));
            bloodSearch = list.Select((value, index) => new { value, index })
                                     .Where(s => s.value.Contains(searchString))
                                     .Select(s => s.index);
        }

        return View(bloodSearch);
    }

The commented lambda expression works but only for that certain variable. What I would like to do is have that be selectable dynamically through a dropdown list.

Here is my relevant view

 @using (Html.BeginForm()){    
     <p> @Html.DropDownList("list", ViewData["list"] as SelectList)
     @Html.TextBox("SearchString")<br />  
     <input type="submit" value="Filter" /></p> 
    }

The reason the value is not changing in the backend is because you are using DropDownList instead of DropDownListFor . DropDownListFor will automatically bind the selection to your model once the submit button is pressed (POST is executed). You are going to have to include the drop down list in a ViewModel or tweak your front end using JavaScript/Jquery.

EDIT

You would have to create a new class:

public DropDownOption
{
   public int Id {get; set;}
   public string Description {get; set;}
}

create a ViewModel :

public myViewModel
{
   public List<DropDownOption> DropDownOptions {get; set;}
   public int OptionSelected {get; set;}
}

Controller:

{
//other stuff
var myVM = new myViewModel();
myVM.DropDownOptions = new List<DropDownOption>(){
   new DropDownOption{Id = 1, Name = "bloodType"},
   new DropDownOption{Id = 2, Name = "rhFactor"},
   //etc.
}

View:

@model .myViewModel
//other stuff
@Html.DropDownListFor(m => m.OptionSelected,
   Model.DropDownOptions.Select(option => new SelectListItem
   {
      Text = option.Description,
      Value = option.Id
   })

To search the array of BlookSearchModel using a property selected by the user you would need to use reflection. Add the following function.

private string GetValue(BloodStoredModel obj, string propertyName)
{
    Type type = typeof(BloodStoredModel);
    if (type != null)
    {
        PropertyInfo property = type.GetProperty(propertyName);
        if (property != null)
        {
            return (string)property.GetValue(obj);
         }
    }

    return null;
}

You can then you it like this

bloodSearch = models.Where(s => string.Compare(GetValue(s, propertyName), searchString) == 0);

Of course there is a potential for errors by hard coding the property names. You could use reflection to enumerate the property names.

ViewBag.SearchFields = from prop in properties
                       select new SelectListItem() { Text = prop.Name };

This would also select the Id field from your model. However, you can modify the linq statement to exclude it.

EDIT I added the following. Plus I changed the above code to use ViewBag instead of ViewData.

To have your view use this you can do this.

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "form1" }))
{
    @Html.DropDownList("SearchFields")
 <input type="submit" value="submit" onclick="return SetAction();" />
}
<script>
    function SetAction() {
        form = document.getElementById("form1");
        dropdown = document.getElementById("SearchFields");

        form.action = "/" + "?searchString=" + dropdown.value;

        return true;
    }
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM