Best Practice for adding List<string> to DropDownList - c#

My controller looks as follow:
var _engine = new NopEngine();
var categoryService = _engine.Resolve<ICategoryService>();
var allCategory = categoryService.GetAllCategories();
List<string> ConvertedList = new List<string>();
for (int i = 0; i < allCategory.Count; i++)
{
ConvertedList.Add(allCategory[i].Name);
}
//fill the viewbag
ViewBag.CategoryList = ConvertedList;
return View("Nop.Plugin.Misc.ExportAttributes.Views.MiscExportAttributes.ExportCalculationSheet");
So basically I'm filling the ViewBag with a List of strings.
My view looks as follow:
#{
Layout = "";
}
#using Telerik.Web.Mvc.UI;
#model ExportCalculationSheetModel
#using Nop.Plugin.Misc.ExportAttributes.Models;
#using Nop.Web.Framework;
#using Nop.Core.Domain.Catalog;
#using (Html.BeginForm())
{
<table class="adminContent">
<tr>
<td colspan="2">
<b>Filter op Categorie:</b>
</td>
</tr>
<tr>
<td class="adminTitle">
#Html.NopLabelFor(model => model.searchCategory):
</td>
<td class="adminData">
#Html.DropDownListFor(x => x.searchCategory, new SelectList(ViewBag.CategoryList, "Name"))
</td>
</tr>
</table>
This works, the DropDownList gets filled with the correct values. But I don't think that the ViewBag is "Best-Practice", I heard something about using a Model to select the List from, I already added a reference to the model in the view:
#model ExportCalculationSheetModel
How can I fill the list at the model class and use it in my view?
I already tried to fill the model class the following way, but that didn't work out:
public List<string> AllCategories
{
get
{
return AllCategories;
}
set
{
var _engine = new NopEngine();
var categoryService = _engine.Resolve<ICategoryService>();
var allCategory = categoryService.GetAllCategories();
List<string> ConvertedList = new List<string>();
for (int i = 0; i < allCategory.Count; i++)
{
ConvertedList.Add(allCategory[i].Name);
}
AllCategories = ConvertedList;
}
}
So the two primary questions are:
How do I fill the list at the model page?
How do I connect the list at my model page to the dropdownlist at my view?
Thanks in advance!

The only thing DropDownListFor needs is an IEnumerable<SelectListItem> (i.e., that could be a list/collection/queryable/etc.). The problem right now is that you simply have a list string instead of SelectListItem. That's easy remedied with a little LINQ-fu:
#Html.DropDownListFor(x => x.searchCategory, Model.AllCategories.Select(m => new SelectListItem { Value = m, Text = m }))
However, the better approach would be to simply have AllCategories return a list of SelectListItems off-the-bat (assuming it's only being used for populating the dropdown list).
private IEnumerable<SelectListItem> allCategories;
public IEnumerable<SelectListItem> AllCategories
{
get
{
if (allCategories == null)
{
var _engine = new NopEngine();
var categoryService = _engine.Resolve<ICategoryService>();
allCategories = categoryService.GetAllCategories().Select(m =>
new SelectListItem { Value = m.Name, Text = m.Name });
}
return allCategories;
}
// You don't need a setter
}
The first time AllCategories is accessed, the associated private variable, allCategories, will be null, so your service spins up and the list of categories is fetched. Select is used to cast the returned categories into a collection of SelectListItems. If you category has something like an Id property, you should use that for Value instead of Name. Any subsequent accesses of AllCategories will simply return the value stored in the private without hitting the database again.
Bonus Pro Tip
If you actually do need to use a for loop for something like this, you don't need to create a new list, add items to the list in the loop, and then return that list. It's easier to just use yield. For example:
public IEnumerable<int> Numbers
{
for (int i = 0; i < 10; i++)
{
yield return i;
}
}

Change
List<string> ConvertedList = new List<string>();
to
List<SelectList> ConvertedList = new List<SelectList>();
do not need for loop . you can directly add the database return list values to ConvertedList
look this sample's
Binding Data To DropDownList MVC Razor
here is a good sample

May be you can try this:
Starting with a Dictionary in the Model
public class YourOptions
{
public Dictionary<int, string> Option { get; set; }
public YourOptions()
{
Option = new Dictionary<int, string>()
{
//Here you should put your code, this is an example
{ 0, "Option 1"},
{ 1, "Option 2"},
{ 2, "Option 3"},
{ 3, "Option 4"},
{ 4, "Option 5"},
//Here you should put your code, this is an example
};
}
In the View
#Html.DropDownListFor(model => model.Option.Keys,
new SelectList(
Model.Option,
"Key",
"Value"))
Sorry for my bad english! I hope this help you!

Related

How can i combine two object fields in Object List into one DropDown in mvc

Actually i have a action which generates a viewbag in it . i am passing an object List in my ViewBag . Now in the View i want to create a dropdown through my viewbag object which i need two fields as a combined in dropdown List in mvc . e.g. my ServiceList.field1 ,ServiceList.field2 . i want both these fields combined in dropdown .
public ActionResult Add()
{
List<service> ServiceList = new List<service>();
ServiceList = GetService();
ViewBag.BackUPList = ServiceBackupList;
return View();
}
and my view contains
#Html.DropDownList("name", (SelectList)ViewBag.BackUPList, new { #class =
"form-control" })
how to combine my both fields and show in dropDown grouped separately.
e.g.
ServiceList.field1
ServiceList.field1
ServiceList.field2
ServiceList.field2
You can generate a new collection in which you concatenate two properties in to one and then construct a SelectList like:
ServiceList = GetService();
var dropDownList = ServiceList.Select(x=> new
{
Id = x.IdField,
Name = x.Field1.ToString() + x.Field2.ToString()
}).ToList();
ViewBag.BackUPList = new SelectList(dropDownList,"Id","Name");
EDIT:
As per edited question you need to generate two collection and then concatenate:
var fieldList = ServiceList.Select(x=> x.IdField1)
.Concat(ServiceList.Select(x=> x.IdField2)).ToList();
and then create a SelectList and put in ViewBag :
ViewBag.BackUPList = fieldList.Select(x =>
new SelectListItem()
{
Value = x,
Text = x
}).ToList();
and in View :
#Html.DropDownList("name",
ViewBag.BackUPList as IEnumerable<SelectListItem>,
new { #class = "form-control" })

how to pass html option id or name or value from one view to another view's controller in MVC c#

I'm displaying dropdown list using html. then when a user select a item from the list that item's id or name or something should pass to my next view's controller.
this is my code...
***** this is my first controller *****
public ActionResult searchView()
{
XElement cruProductRoot = XElement.Load(Server.MapPath("~/XmlFiles/Cruisedata/cruiseprodutstwo.xml"));
var rootElement = cruProductRoot.Elements("CruiseProduct");//this is the root element
//for the location field
var getLocations = rootElement
.Select(l => l.Element("Location").Value)
.Distinct();
var getType = rootElement
.Select(t => t.Element("Types").Element("Type").Value)
.Distinct();
// Test productsTestone = new Test();
List<Test> productsLocation = new List<Test>();
List<Test> productsType = new List<Test>();
foreach (var iteml in getLocations)
{
productsLocation.Add(new Test
{
cruiseLocation = iteml.ToString()
});
};
foreach(var itemt in getType)
{
productsType.Add(new Test
{
cruiseType = itemt.ToString(),
});
}
ViewBag.Lc = productsLocation;
ViewBag.Tp = productsType;
return View();
}
*** and this is the view for the controller ****
#using (#Html.BeginForm("Test", "searchView", FormMethod.Post))
{
<div class="form-group" style="background-color:#808080; padding:30px;">
<div class="col-md-6" style="margin:10px;">
<label for="location">Destination </label>
<select id="location">
<option>Any</option>
#foreach (Test item in #ViewBag.Lc)
{
<option value=#item.cruiseLocation>#item.cruiseLocation</option>
}
</select>
</div>
</div>
******** this is my second controller ******
public ActionResult resultView(string value)
{
XElement sCruise = XElement.Load(Server.MapPath("~/XmlFiles/Cruisedata/cruiseprodutstwo.xml"));
var rootEle = sCruise.Elements("CruiseProduct")
.Where(s => s.Element("Location").Value == value);
foreach(var it in rootEle)
{
}
return View();
}
**** when user select an item from the list, and click submit then the selected item should send to the second view's controller. how can I do that.
if we use only links like this.
#Html.ActionLink(#itme.cruiseLocation,"resultView", new {name =#item.cruiseLocatin})
how to do for option also.I tried <option>#Html.ActionLink</option> also. help me with this
In first controller set
TempData["optionid"]=selectedid
And in second controller you can access that id from var a=TempData["optionid"]

How to add data to a 2D array in MVC view using HTML helper

I am coding a MVC 5 View, and would like to know how to add data to a hidden 2D array.
Here is my code:
#Html.Hidden("hdnArray")
#for (int i = 0; i < 2; i++)
{
string[] items = new string[4] { "1", "2", "3", "4" };
#Html.HiddenFor(items, { id = "hdnArray" })
}
In the above code, I am trying to add the string[] items array to the hidden 2D array called hdnArray.
I am getting many invalid expression errors at the line:
#Html.HiddenFor(items, { id = "hdnArray" })
Can someone please help me with this?
Thanks in advance.
You are calling HiddenFor incorrectly. If you want to just add hidden inputs that won't be binded to the model then use:
foreach (var item in new int[] {1, 2, 3, 4, 5})
{
#Html.HiddenFor(a => item)
}
But if you're looking to add this to your Model then you should initialize it in the controller before passing it to the view. Then it can be binded by pointing the expression to Model.ArrayItems:
Model:
public class YourModel{
public List<int> ArrayItems { get; set; }
}
View:
foreach (var item in Model.ArrayItems)
{
#Html.HiddenFor(a => Model.ArrayItems)
}

Issue with MVC2 DropDownListFor, only displaying the class-name

Good day,
I have this problem with Html.DropDownListFor which I can't seem to work out.. It gives me the correct number of options, if I do a breakpoint in the code where it is supposed to render the list, the "SelectItemList" object contains the items with correct values, but the actual HTML it spits out is the following:
<select id="Reason_ReasonId" name="Reason.ReasonId"><option>System.Web.Mvc.SelectListItem</option>
<option>System.Web.Mvc.SelectListItem</option>
<option>System.Web.Mvc.SelectListItem</option>
<option>System.Web.Mvc.SelectListItem</option>
<option>System.Web.Mvc.SelectListItem</option>
<option>System.Web.Mvc.SelectListItem</option>
</select>
The module containts this:
public SelectList ReasonList
{
get
{
SelectList selectList;
List<SelectListItem> selectItems;
using (var db = new EscalationDataContext())
{
var reasons =
db.Reasons
.OrderBy(r => r.Reason1)
.Select(r => new SelectListItem
{
Value = r.ReasonId.ToString(),
Text = r.Reason1
});
selectItems = reasons.ToList();
selectList = new SelectList(selectItems);
}
return selectList;
}
}
The controller just creates a default instantiation and sets the default value:
public ActionResult Create()
{
EscalationModel model = new EscalationModel
{
Reason = new Reason { ReasonId = new Guid("598c28c2-877a-44fa-9834-3241c5ee9355"), Reason1 = "Taken too long" },
ActionedDate = DateTime.Now
};
return View(model);
}
Last but not least, the view:
<%: Html.DropDownListFor(m => m.Reason.ReasonId, Model.ReasonList) %>
Any ideas why it behaves like this? As I said, in the actual code (in the view) I have the correct values, but.. It doesn't like me.. Any help would be greatly appreciated, thanks in advance!
Ok.. It seems you had to specify which variable in SelectListItem was used for "Value" and which was used for "Text"..
selectList = new SelectList(selectItems);
Became..
selectList = new SelectList(selectItems, "Value", "Text");
Which seems to have done the trick!

How can I make Html.DropDownList encode its values?

In my viewData I have an IList mls.
I want to use this to show in a dropdown. Like so:
<%= Html.DropDownList("ml3Code",
new SelectList(Model.Mls, "Code", "Description", Model.Ml3.Code ?? ""),
Model.T9n.TranslateById("Labels.All"),
new { #class = "searchInput" })%>
This works fine, until there's a myObject.Code == VOC<420 g/l.
I would have expected that an HTML helper would encode its values, but it doesn't.
How should I approach this problem? The only thing I can come up with is first making a dupe list of the objects with encoded values and then feeding it to the selectlist. This would be really bothersome.
P.S. I hope Phill H. and his team will have a long and thorough look at the encoding for asp.net-mvc 2.0...
I'm puzzled. The question "Do ASP.NET MVC helper methods like Html.DropDownList() encode the output HTML?" was asked on SO before, and the answer was "Yes" - and the source-code from the MVC framework was cited to back this assertion up.
Well, you can roll your own Html helper, but if you're like me you won't want to do that.
To me, I see two options here:
Write your select element in plain view without the helper. I've never felt the helpers provide you much save for highlighting an element when an error occurs.
Patch the select box on the client when the page loads, as in:
function encodeHtml(str)
{
var encodedHtml = escape(str);
encodedHtml = encodedHtml.replace(///g,"%2F");
encodedHtml = encodedHtml.replace(/\?/g,"%3F");
encodedHtml = encodedHtml.replace(/=/g,"%3D");
encodedHtml = encodedHtml.replace(/&/g,"%26");
encodedHtml = encodedHtml.replace(/#/g,"%40");
return encodedHtml;
}
window.onload = function()
{
var ml3Code = document.getElementById("ml3Code");
for(var i = 0; i < ml3Code.options.length; ++i)
{
ml3Code.options[i].value = encodeHtml(ml3Code.options[i].value);
}
};
It's a hack, I know. I strongly prefer the first choice.
This is encoded. But dont check with firebug - It shows values decoded.
Check in ViewSource of the Browser and things are encoded.
Controller
public List<CategoryInfo> GetCategoryList()
{
List<CategoryInfo> categories = new List<CategoryInfo>();
categories.Add(new CategoryInfo { Name = "Food<äü", Key = "VOC<420 g/l", ID = 2, Uid = new Guid("C0FD4706-4D06-4A0F-BC69-1FD0FA743B07") });
}
public ActionResult Category(ProductViewModel model )
{
IEnumerable<SelectListItem> categoryList =
from category in GetCategoryList()
select new SelectListItem
{
Text = category.Name,
Value = category.Key
};
model.CategoryList = categoryList;
return View(model);
}
View
<%= Html.DropDownList("Category" , Model.CategoryList) %>
Model
public class ProductViewModel
{
public IEnumerable<SelectListItem> CategoryList { get; set; }
public List<CategoryInfo> Categories { get; set; }
}
HTML
<select id="Category" name="Category"><option value="VOC<420 g/l">Food<äü</option>
</select>

Categories