ASP.NET MVC - Get Id from a dropdownlist - c#

I'm new in ASP.NET MVC and i have a problem. I needed to get a string "Category" from a dropdownlist, that was my code:
var CList = new List<string>();
StreetFooder sf = db.StreetFooders.Single(s => s.User.UserName == this.User.Identity.Name);
var Cqry = from d in db.Categories
where !d.IsDeleted && d.StreetFooder.Id == sf.Id
orderby d.Name
select d.Name;
CList.AddRange(Cqry.Distinct());
ViewBag.CategoryList = new SelectList(CList);
And the view:
<div class="col-md-10">
#Html.DropDownListFor(model => model.Category, (SelectList)ViewBag.CategoryList, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Category, "", new { #class = "text-danger" })
</div>
And that worked for me. After that, i realized i made a mistake and changed my string Category attribute in:
public virtual Categories Type { get; set; }
Now i want to save on my db the ID instead of string, but still want to see my string when select from dropdown list...but don't know how.

Use SelectListItem to create the SelectList, there you can specify Value = your id and Text = display text
https://msdn.microsoft.com/en-us/library/system.web.mvc.selectlistitem(v=vs.118).aspx
var CList = new List<SelectListItem>();
StreetFooder sf = db.StreetFooders.Single(s => s.User.UserName == this.User.Identity.Name);
var Cqry = from d in db.Categories
where !d.IsDeleted && d.StreetFooder.Id == sf.Id
orderby d.Name
select d;
CList.AddRange(Cqry.Distinct().Select(x => new SelectListItem
{
Value = x.Id.ToString(),
Text = d.Name
}));
ViewBag.CategoryList = new SelectList(CList);
You can even omit using the SelectList and simply pass a List<SelectListItem> if I recall correctly.

Try this:
var cqry = from d in db.Categories
where !d.IsDeleted && d.StreetFooder.Id == sf.Id
orderby d.Name
select new { Id = d.StreetFooder.Id, Value = d.Name};
ViewBag.CategoryList = new SelectList(cqry.Distinct(), "Id", "Value");
You need to also define Id and pass it to your DropDownList. This will initialize a new instance of the SelectList class by using the specified items for the list(cquery), the data value field(Id), and the data text field(Value) and add to you ViewBag then bind it to DropDownList.
You can use it on View like this:
#Html.DropDownList("CategoryList ", null, new { #class = "form-control" })
cqry.Distinct() will work if you have duplicates on result, which means that the Id and Value in collection are same, if you need to distinct only by name, you need to use group by.

In selectList, you can pass from which property you want to bind dropdown value and text property.
var Cqry = from d in db.Categories
where !d.IsDeleted && d.StreetFooder.Id == sf.Id
group d by new { names.Name } into nameGroup
select new { Name = nameGroup.Name, Id = nameGroup.FirstOrDefault().StreetFooder.Id};
ViewBag.CategoryList = new SelectList(Cqry,"Id","Name");
You were selecting Distinct name, so I have used here group by name.
As I've created anonymous object with property 'Id' and Name. Now you can bind it in SelectList.

Related

Json SelectListItem add item to top of list

I am returning the following Json within an ActionResult:
return Json(_lookUp.GetMgmtByIDs(_mgmtService.GetMgmt(D).ToList(), selectedIDs.ToList())
.Select(x => new SelectListItem { Text = x.SName, Value = x.SID.ToString() })
.OrderBy(y => y.Text), JsonRequestBehavior.AllowGet);
I need to add the an item to the top of the list: "Please Select" with a value of 0. I am not sure how to do this.
I know we can do the following but does not work in this case:
.Insert(0, "Please Select");
I'd say that something like this will probably work:
new[]{ new SelectListItem { Text = "Please Select", Value = "0" } }.Concat(
_lookUp.GetMgmtByIDs(_mgmtService.GetMgmt(D).ToList(), selectedIDs.ToList())
.Select(x => new SelectListItem { Text = x.SName, Value = x.SID.ToString() })
.OrderBy(y => y.Text)
)
though it might cause you some translation issue in the future
I know we can do the following but does not work in this case:
That'll work if you materialize to a List first:
var list = _lookUp.GetMgmtByIDs(_mgmtService.GetMgmt(D).ToList(), selectedIDs.ToList())
.Select(x => new SelectListItem { Text = x.SName, Value = x.SID.ToString() })
.OrderBy(y => y.Text)
.ToList();
list.Insert(0, new SelectListItem { Text = "Please Select", Value = "0" });
and then return the list

MVC Dropdown list not showing selected value using ViewBag

I have filled the ViewBag.BankNames using Banks table as
ViewBag.BankNames = new SelectList(db.Banks, "BankId", "BankName", applicationSettings.BankId);
where applicationSettings.BankdId is having the value which I need to show as the selected value in dropdown, then passed the applicationSetting model object to view.
In my View I have used that ViewBag like
#Html.DropDownListFor(model => model.BankId, ViewBag.BankNames as SelectList, "Select Bank", htmlAttributes: new { #class = "form-control" })
It will show me the dropdown list with all values of Bank names but the selected value is Select Bank and not the value which I set as selected value in ViewBag?
Can you assign applicationSettings.BankId to BankId of model property and check..
you are binding #Html.DropDownListFor(model => model.BankId, ViewBag.BankNames as SelectList, "Select Bank", htmlAttributes: new { #class = "form-control" }) but in model.BankId is zero..
Assign Model.BankId = applicationSettings.BankId before returning it to view
In Controller
public ActionResult Index()
{
var banks = new List<Banks>()
{
new Banks()
{
BankId =1,
BankName = "Bank 1"
},
new Banks()
{
BankId =2,
BankName = "Bank 2"
}
};
var list = new SelectList(banks, "BankId", "BankName");
ViewBag.Banks = list;
var modelBanks= new Banks();
modelBanks.BankId = 2;
return View(modelBanks);
}
In View
#model Banks
#using WebApplication3.Models
#Html.DropDownListFor(model => model.BankId, ViewBag.Banks as SelectList,"Select Bank")

DropDownList issue with Enums

I'm currently localizing an open source project and I have an issue with Enums.
Here is my Enums.cs (not the whole file, just part of where the issue appears).
public enum ModeratorLevel
{
[Display(Name = "Sahip")]
Owner = 1,
[Display(Name = "Moderatör")]
Moderator = 2,
[Display(Name = "Temizlikçi")]
Janitor = 3,
[Display(Name = "Boyacı")]
Designer = 4,
[Display(Name = "Paylaşımcı")]
Submitter = 99
}
and this is my View (again, not the whole file, contains only the codes that I want to fix)
#{
string subverseName = ViewBag.SubverseName;
var levelsAvailable = Enum.GetValues(typeof(ModeratorLevel)).OfType<ModeratorLevel>();
var currentLevel = ModeratorPermission.Level(User.Identity.Name, subverseName);
levelsAvailable = levelsAvailable.Where(x => x > currentLevel || currentLevel == ModeratorLevel.Owner);
}
#* these areas contain other codes is not related to my issue *#
<div class="form-group">
#Html.Label("foo", htmlAttributes: new {#class = "control-label col-md-2"})
<div class="col-md-4">
#Html.DropDownListFor(model => model.Power, levelsAvailable.Select(x => new SelectListItem() { Text = x.ToString(), Value = ((int)x).ToString() }), new { #class = "form-control"} )
#Html.ValidationMessageFor(model => model.Power, "", new {#class = "text-danger"})
</div>
</div>
#* these areas contain other codes is not related to my issue *#
and this is output;
dropdownlist
aaand now, What I want?
I want to display DisplayNames instead Enum values.
The outpot looks like:
foo = Owner
Moderator
Janitor
Designer
Submitter
But I want to show it looks like:
foo = Sahip
Moderatör
Temizlikçi
Boyacı
Paylaşımcı
But in this change, changes must be only visual. We shouldn't change any code that affects to Enum's function. I just want to show only DisplayNames instead of Enum values.
Thanks.
you can add an extension method :
public static string DisplayName(this Enum value)
{
Type enumType = value.GetType();
var enumValue = Enum.GetName(enumType, value);
MemberInfo member = enumType.GetMember(enumValue)[0];
var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false);
var outString = ((DisplayAttribute)attrs[0]).Name;
if (((DisplayAttribute)attrs[0]).ResourceType != null)
{
outString = ((DisplayAttribute)attrs[0]).GetName();
}
return outString;
}
and then use it in the view :
#Html.DropDownListFor(model => model.Power, levelsAvailable.Select(x => new SelectListItem() { Text = x.DisplayName(), Value = ((int)x).ToString() }), new { #class = "form-control"} )
Use the EnumDropDownListFor helper
#Html.EnumDropDownListFor(model => model.Power)

MVC Html.DropDownListFor not binding on selecting the same value

I have a state drop down in my MVC application and calling an helper method to populate the dropdown. On selecting the same value more than one time, drop down is getting reset to the default value "Select State", instead of the correct state.
HTML View
<div>
#Html.LabelFor(m => m.Pat.StateId)
#Html.DropDownListFor(m => m.Pat.StateId, listHelper.GetState(Model.Pat.StateId))
#Html.ValidationMessageFor(m => m.Pat.StateId)
</div>
Helper code
public static IList<SelectListItem> GetStateOptions(int? selectedId = null)
{
var lookupService = DependencyResolver.Current.GetService<IConstantsHelper>();
var result = lookupService.GetAll<State>().Select(x => new SelectListItem
{
Value = x.Id.ToString(),
Text = x.Text,
Selected = selectedId.HasValue && selectedId == x.Id
}).OrderBy(x => x.Text).ToList();
result.Insert(0, new SelectListItem { Value = "", Text = "Select state...", Disabled = true, Selected = result.Any(x => !x.Selected)});
return result;
}
I think the issue is in your .Any condition, because there will be non selected options in your list, so it will return true.
Try changing it to:
result.Insert(0, new SelectListItem { Value = "", Text = "Select state...", Disabled = true, Selected = !result.Any(x => x.Selected)});

MVC - Ordered List

I am trying to order the following list by descending but I can't seem to figure out how it is done:
var cust = item.Profiles.Select(c => new
{
id = c.CustId,
Name = c.Name
}).ToList();
ViewBag.Customers = new MultiSelectList(cust, "id", "Name");
This is what I have already tried:
var cust = item.Profiles.Select(c => new
{
id = c.CustId,
Name = c.Name.OrderByDescending();
}).ToList();
ViewBag.Customers = new MultiSelectList(cust, "id", "Name");
This is how the list is displayed on my view:
#Html.DropDownList("id", (MultiSelectList)ViewBag.Customers, new { #class = "form-control", id = "lstCustomer" })
Note: I am trying to sort the list in alphabetical order
var cust = item.Profiles.Select(c => new
{
id = c.CustId,
Name = c.Name
}).OrderByDescending(c=>c.Name).ToList();
Or
var cust = item.Profiles.OrderByDescending(a=>a.Name).Select(c => new
{
id = c.CustId,
Name = c.Name
}).ToList();
Using Linq:
var cust = item.Profiles.Select(c => new
{
id = c.CustId,
Name = c.Name
}).OrderByDescending(c => c.Name).ToList();
Or More Elegant (Query Syntax):
var cust = (from c in item.Profiles
orderby c.Name
select new
{
id = c.CustId,
Name = c.Name
}).ToList();
To do the same thing with query syntax:
var cust = (from c in item.Profiles
orderby c.Name descending
select new
{
id = c.CustId,
Name = c.Name
}
).ToList();

Categories

Resources