Default selected value in mvc5 dropdown - c#

I have a linq query that is binded to a #Html.dropdownfor. If I assign a value to the user's account and leave the page. When I go back to the page, It's default value or preselected value is "Choose a schedule" even when I have a value assigned to it from before. I need it to preselect to the value already stored in the database. It was preselecting correctly with this
ScheduleBuilderList = _context.ScheduleBuilder.ToList()
until I binded LINQ query.
How can I get the database value to the be default value selected in dropdown without messing up the LINQ?
#Html.DropDownListFor(m => m.ApplicationUser.ScheduleSum, new SelectList(Model.ScheduleBuilderList, "ScheduleSummary", "ScheduleSummary"), "Choose a schedule", new {#class = "form-control", id="dropdown"})
LINQ
ScheduleBuilderList = _context.ScheduleBuilder.Where(s => s.IsScheduleAssigned == false).ToList()
Full Actionresult code with recommended change below
public ActionResult EmployeeDetails(string id, ScheduleBuilder scheduleBuilder, ApplicationUser applicationUser)
{
var user = _context.Users.SingleOrDefault(e => e.Id == id);
if (user == null)
{
return HttpNotFound();
}
var viewModel = new TierViewModel()
{
ApplicationUser = user,
TierLevel = _context.Tier.ToList(),
ScheduleBuilderList = _context.ScheduleBuilder
.Where(s => s.IsScheduleAssigned == false)
.Select(item => new SelectListItem
{
Text = item.ScheduleSummary,
Value = item.ScheduleSummary,
Selected = item.ScheduleSummary == user.ScheduleSum
})
};
var user1 = _context.Users.ToList();
var schedule1 = _context.ScheduleBuilder.ToList();
return View("EmployeeDetails", viewModel);
}

You could try something like this:
var ScheduleBuilderList = _context.ScheduleBuilder
.Where(s => s.IsScheduleAssigned == false)
.Select(item => new SelectListItem
{
Text = item.ScheduleSummary,
Value = item.ScheduleSummary,
Selected = item.ScheduleSummary == "usersvalue"
});
Where the literal "usersvalue" should be replaced the value of ApplicationUser.ScheduleSum for which you are interested in. Then you should change a bit also your View, like below:
#Html.DropDownListFor(m => m.ApplicationUser.ScheduleSum,
Model.ScheduleBuilderList,
"Choose a schedule",
new {#class = "form-control", id="dropdown"})
and your Model should replace the type of ScheduleBuilderList with the following type:
IEnumerable<SelectListItem>

Related

Failed to set existing value for drop down list on edit page

First thing, I have pre-defined model from existing db.
I just want to show existing value on edit page with MVC 5.
Here's what I have done:
Controller
public async Task<ActionResult> Edit(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
slik_data_a01 slik_data_a01 = await db.slik_data_a01.FindAsync(id);
if (slik_data_a01 == null)
{
return HttpNotFound();
}
//init DD
var selectedjs = (from x in db.master_segmenfasilitas
where x.sandi == slik_data_a01.kode_jenis_segmen
select new { x.fasilitas, x.sandi }).FirstOrDefault();
var jenissegmen = new SelectList((from x in db.master_segmenfasilitas
select new { x.fasilitas, x.sandi }).ToList(), "sandi", "fasilitas", selectedjs);
ViewBag.jenissegmen = jenissegmen;
return View(slik_data_a01);
}
And my view is like this :
<div class="form-group">
#Html.LabelFor(model => model.kode_jenis_segmen, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.kode_jenis_segmen, ViewBag.jenissegmen as SelectList, new{ #class = "form-control input-sm" })
#Html.ValidationMessageFor(model => model.kode_jenis_segmen, "", new { #class = "text-danger" })
</div>
</div>
but the default value always shows the first data of the SelectList,
not the existing one, although I have defined the selected values on controller.
Any help really appreciated.
You need to set the selected value in the model property that is binded with the DropDownListFor helper before passing the object to View method at last line and you don't need to set the selected value in the SelectList constructor, so change the SelectList creation code to be:
var jenissegmen = new SelectList((from x in db.master_segmenfasilitas
select new { x.fasilitas, x.sandi }).ToList(),
"sandi",
"fasilitas");
and before passing model set selected value in the model property, and helper will take care itself for selecting the value:
slik_data_a01.kode_jenis_segmen = selectedjs;
ViewBag.jenissegmen = jenissegmen;
return View(slik_data_a01);
Now the control will set the selected value on the basis of the value coming in the property which is binded with it.
Hope it helps!
I have been trying all the way around to solve this and the simple answer is i cannot assign selected value on model that doesn't have relation in the model.
The only way is that i need to update my model, or create another model which represent my data in the form (CMIIW).
But i found a simple hack, that doesn't require changes in the model, still not perfect but its just fine for me.
here's my updated controller :
public async Task<ActionResult> Edit(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var slik_data_a01 = await db.slik_data_a01.FindAsync(id);
if (slik_data_a01 == null)
{
return HttpNotFound();
}
//init Dropdown Data
ViewBag.jenissegmen = new SelectList((from x in db.master_segmenfasilitas
select new { x.fasilitas, x.sandi }).ToList()
/*OrderByDescending to put the selected value on first row*/
.OrderByDescending(o => o.sandi == slik_data_a01.kode_jenis_segmen)
, "sandi", "fasilitas");
//then return to the view.
return View(slik_data_a01);
}
and the view still using the Html.DropDownListFor

ViewBag on ListBox gets empty data

I made a LINQ Statement to fill a ViewBag and display it on my View, however for some reason my ListBox displays empty so i saved the LINQ statement on a txt file to see if it was empty, but it has the correct data, so my question is:
Why my ViewBag is not Displaying on my ListBox in my View?
This is my Linq Filling the ViewBag:
foreach (var item in db.VENTA_PLATILLOS
.Select(v => new { Turno = v.Nombre_Turno, Total = v.Total })
.GroupBy(l => l.Turno)
.AsEnumerable()
.Select(z => new { Turno = z.Key, Total = String.Format("{0:$#,##0.00;($#,##0.00);Zero}", Decimal.Round(z.Sum(l => l.Total), 0)) })
.OrderByDescending(a => a.Turno))
{
listadesumas.Add(string.Format("{{{0}, Total = {1}}}", item.Turno, item.Total));
}
//txt file to see if Linq Statemnt is filled correctly and it is
var json5 = JsonConvert.SerializeObject(listadesumas);
System.IO.File.WriteAllText(#"C:\inetpub\wwwroot\SumasTurno.txt", json5);
//Filling my Viewbag with my LinQ Group By Result
var grupos = new SelectList(listadesumas.ToList());
ViewBag.Group = grupos;
This is my View ListBox:
#{
var group = (SelectList)ViewBag.Group;
}
#Html.ListBox("Group", (IEnumerable<SelectListItem>)ViewBag.Group, new { style = "width: 300px;" })
Try the following in your controller instead...
ViewBag["Group"] = grupos;
...and this in the view...
#Html.ListBox("Group", (IEnumerable<SelectListItem>)ViewBag["Group"], new { style = "width: 300px;" })
I have tried your example as best as I could without knowing the underlying database table. I have not found an issue and found that it does render the option list correctly through a viewbag property containing a select list. So in this example, I stubbed in a string list for the underlying database table. In this example, I am able to populate the option list through the viewbag property containing the resulting a list. I have to wonder if your conclusion that it is not displaying is related to contents of the viewbag property "Group"
My example code:
public ActionResult Index()
{
List<string> listadesumas = new List<string>();
var FakeDbTable = new List<string>() { "a.bc", "a.cde", "b.xyz" };
foreach (var item in FakeDbTable.Select(v=> new { itemname = v })
.GroupBy(l => l.itemname.Substring(0, 1)).AsEnumerable().Select(z =>new { GroupingValue= z.Key, Total=string.Format("count {0}",z.Count())}).OrderByDescending(a=>a.GroupingValue))
{
listadesumas.Add(string.Format(" result item {0}",item));
}
var grupos = new SelectList(listadesumas.ToList());
ViewBag.Group = grupos;
return View();
}
The view code
#{
ViewBag.Title = "Home Page";
var group = (SelectList)ViewBag.Group;
}
<div class="row">
<div class="col-md-12">
#Html.ListBox("Group", (IEnumerable<SelectListItem>)ViewBag.Group, new { style = "max-width: 500px;" })
</div>
</div>
Result shows as this:

Concatenate two fields in select list (C#)

I use a viewbag to create a select list and I want to Show two fields concatenated together. However, it is crashing on my view. Here is the viewbag code:
ViewBag.PackageId = new SelectList(db.Packages.Where(p => p.status == "A"), "u_package_id", "u_package_id" + "'-'" + "package_nme");
This should work
ViewBag.PackageId = db.Packages.Where(p => p.status == "A")
.Select(p => new SelectListItem
{
Text = p.u_package_id + "-" + p.package_nme,
Value = p.u_package_id
};
The 2nd and 3rd parameters of the SelectList constructor are strings that must match the names of properties in your model (in your case your don't have a property named "u_package_id-package_nme" hence the error).
In the controller, generate a collection of SelectListItem
ViewBag.PackageList = db.Packages.Where(p => p.status == "A").Select(p => new SelectListItem()
{
Value = p.u_package_id, // may need .ToString() depending on the property type
Text = string.Format("{0}-{1}", p.u_package_id, p.package_nme)
}
Side note: Suggest you name your properties to reflect what they are (i.e. its a collection of items, not an ID so PackageList, not PackageId) and this would be necessary anyway if the model your binding to contains a property named PackageId
Thanks to deramko, I have my answer. He was 99% of the way there. Here is the final code:
ViewBag.PackageId = db.Packages.Where(p => p.status == "A")
.Select(p => new SelectListItem
{
Text = p.u_package_id + "-" + p.package_nme,
Value = p.u_package_id.ToString()
});

MVC/C#: DropDownListFor not selecting 'selected' item

ok, I have a situation where I need to have multiple DDLs of 'BayTypes' that use the same dictionary, which isn't a problem. One DDL for each of 'n' BayOptions. I'm passing a dictionary to my view as 'BayTypes' like this:
(Controller)
var bayTypes = _bayTypeRepository.GetBayTypes().ToList();
property.BayTypes = bayTypes.ToDictionary(g => g.Name, g => g.BayTypeGuid.ToString());
(View)
var overrideValue = item.BayTypeOverride ? item.BayTypeOverrideValue.BayTypeGuid.ToString() : string.Empty;
var result = (from x in Model.BayTypes
select new SelectListItem()
{
Text = x.Key,
Value = x.Value,
Selected = x.Value == overrideValue <-- ***this is working***
});
if (item.BayTypeOverride == true)
{
#Html.DropDownListFor(x => x.BayTypes, result, new { #Name = "BayOptionsToSubmit[" + aCounter + "].BayTypeOverrideValue" })
}
else
{
#Html.DropDownListFor(x => x.BayTypes, result, new { #Name = "BayOptionsToSubmit[" + aCounter + "].BayTypeOverrideValue", #style = "display:none;" })
}
The correct item IS getting selected in the 'result' object. If I step through, and watch 'result', I can see that 'Selected = true' for the right one... but it's not selecting in the DDLFor when it renders...
What am I missing?
Ultimately, what determines the "selected" item in a drop down is ModelState, not the SelectListItem.Selected property. ModelState is composed from the following sources: Request, ViewData, ViewBag, and finally Model.
Check the values of Request["BayTypes"], ViewData["BayTypes"], ViewBag.BayTypes, and Model.BayTypes. If any of those has a different value from what you're expecting to be selected, that's your problem, particularly if the value is not even in the ballpark.
For example, a common cause of this is developers storing their actual select list choices in something like ViewBag.Foo and then trying to apply that to a dropdown bound to Model.Foo. The select list itself at that point becomes the selected item in ModelState, rather than the one particular value you selected.
Solved it... Changed to a .DropDownList (no 'For') and passed in the 'name' as the 'result' var created earlier. Works.
var overrideValue = item.BayTypeOverride ? item.BayTypeOverrideValue.BayTypeGuid.ToString() : string.Empty;
var result = (from x in Model.BayTypes
select new SelectListItem()
{
Text = x.Key,
Value = x.Value,
Selected = x.Value == overrideValue
});
if (item.BayTypeOverride)
{
#Html.DropDownList("result", result, htmlAttributes: new { #Name = "BayOptionsToSubmit[" + aCounter + "].BayTypeOverrideValue" })
}
else
{
#Html.DropDownList("result", result, htmlAttributes: new { #Name = "BayOptionsToSubmit[" + aCounter + "].BayTypeOverrideValue", #style = "display:none;" })
}

Update the selected dropdownlist value base on value from another linq query

I use the following code to get the LOV for dropdownlist and setting a selected value as well:
ViewData["dropDown_Color"] = correspondingDropDownValue
.Select(j =>
new SelectListItem {
Text = j.ListOfValue,
Value = j.ListOfValue,
Selected = j.ListOfValue
== x.DefaultValue
})
.ToList();
Now that I have a dropdownlist in my ViewData, I want to update the selected value of this ViewData["dropDown_Color"] base on the following query
var userPref = from m in db.UserColorPref
where m.UserID.Equals(userSessionID)
select m;
The value to be updated can be access by userPref.color. May I know how to achieve my objective?
Use this
List<SelectListItem> selectlist = ViewData["dropDown_Color"] as List<SelectListItem>;
selectlist.ForEach(x =>
{
x.Selected = x.Value == userPref.color;
});
You can achieve it as follows:
ViewData["dropDown_Color"] = new SelectList(YourSelectList, "Value", "Text", selectedValue);

Categories

Resources