MVC combobox and how to save it in database? - c#

I am a beginner in MVC (but not in C#), but the project must be made in Visual Studio .NET app (MVC or WPF) using Entity Framework. I made a Database First app, but here is my problem:
In table Customers
I have Id, Title, Name, MiddleName, Surname, Address, CountryId(relationship to Table Countries[Id, Name] 1 to many), Active(bit, True/False, Checkbox)
In table Countries
Id, Name(predefined)
Another table Titles(that I made, because I couldn't hardcode dropdownlists)
Id, TitleName
My question is when I created the Controller + View, the Title is displayed as TextBox(aka #Html.Editor(...)), when I change it to #Html.DropDownList("nameHere", null, new { htmlAttributes = new { #class = "form-control" } })
Then in my GET I create a dropdown view list:
public ActionResult Create()
{
ViewBag.nameHere = new SelectList(db.Titles, "Id", "TitleName");
ViewBag.CountryId = new SelectList(db.Countries, "Id", "Name");
return View();
}
Then in my POST I put it too:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Title,Name,MiddleName,Surname,Address,CountryId,Active")] Customer customer)
{
if (ModelState.IsValid)
{
db.Customers.Add(customer);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.nameHere = new SelectList(db.Titles, "Id", "TitleName", db.Title); //selects from table Titles the Id and TitleName for the field Title in Customers table? at least that's how I interpretate it
ViewBag.CountryId = new SelectList(db.Countries, "Id", "Name", customer.CountryId); //same for Country
return View(customer);
}
But I have 3 problems:
1st one - the server returns for Title in db.Customers NULL value
2nd one - if I don't use dropdown then it will send the value from the TextBox field(but people can write whatever they want)
3rd one(when using ViewBag and ViewData) - There is no ViewData item of type 'IEnumerable' that has the key "nameHere"
I just want a simple dropdown list where I have 4 options - Ms, Mrs, Mr, Miss and when I select it and send the full form to the server(Name, MiddleName, Surname, etc), in the table Customers to save the string from the dropdown list. nothing more.
I made my db with Database First(aka creating db then Model, not around)

I managed to come up with an answer with some OOP:
Inside the controller(GET method):
List<string> ListItems = new List<string>();
ListItems.Add("Ms.");
ListItems.Add("Mrs.");
ListItems.Add("Mr.");
ListItems.Add("Miss");
SelectList Titles = new SelectList(ListItems);
ViewData["Titles"] = Titles;
Inside the View:
<div class="form-group">
#Html.LabelFor(model => model.Title, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("Title", ViewData["Titles"] as SelectList, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Title, "", new { #class = "text-danger" })
</div>
</div>

Related

Reloading the webpage will make the dropdownlist null

I am trying to load all the database agents into a dropdown list, and I want to insert the selected id into another table. Dropdown list function and insert functions are working, but after the page reload, the dropdown list return as null, and I am getting this error There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key AssignPerson The code is mentioned below
View
#Html.DropDownListFor(m => m.AssignPerson, (IEnumerable<SelectListItem>)ViewBag.users, "Select Assign Person", new { #class = "form-control", #required = "required" })
Controller
public ActionResult NewAccess()
{
List<Agent> countryList = _context.Agents.ToList();
ViewBag.users = new SelectList(countryList, "AgentID", "AgentName");
return View();
}

Getting the selected value from a DropDownListFor using a ViewBag list

I'm having trouble getting the data from a DropDownListFor using a ViewBag list with my model. Here is my Controller code:
[HttpGet]
public ActionResult JoinTeam()
{
var TeamList = _db.TeamModels.ToList();
SelectList list = new SelectList(TeamList, "Id", "TeamName");
ViewBag.TeamList = list;
return View();
}
And the Razor view form looks like this:
#using (Html.BeginForm("JoinTeam", "Home", FormMethod.Post))
{
#Html.TextBoxFor(m => m.DisplayName, new { #class = "form-control form-control-lg", placeholder = "Enter your Battle Net ID" })
<br/>
#Html.DropDownListFor(m => m.TeamModel, (SelectList)ViewBag.TeamList, "- Select a Team to Join -", new { #class= "form-control form-control-lg" })
<br />
<button type="submit" class="btn btn-primary" style="width:100%;text-align:center;">Submit</button>
}
The TextBoxFor helper is returning the data correctly, but whatever option I have selected in the drop down does not get passed into my post method. Does anyone have any ideas?
The post action does work as it's getting the data from the model for the TextBoxFor help, but here's what it looks like:
[HttpPost]
public async Task<ActionResult> JoinTeam(GuardianModel model)
{
try
{
string BNETId = model.DisplayName.Replace("#", "%23");
long memberId = 0;
if (ModelState.IsValid)
{
Bungie.Responses.SearchPlayersResponse member = await service.SearchPlayers(MembershipType.Blizzard, BNETId);
memberId = member[0].MembershipId;
}
using (var context = new CoCodbEntities1())
{
var g = new GuardianModel
{
MembershipId = memberId.ToString(),
DisplayName = BNETId,
MembershipType = 4,
TeamID = model.TeamModel.Id
};
TempData["UserMessage"] = ViewBag.TeamList.Id;
return RedirectToAction("Success");
}
}
catch
{
}
return View();
}
These are the values getting passed into the Post action
From the screenshot you shared, it looks like TeamModel property is the virtual navigational property of type TeamModel. You should not bother about loading that. All you need to worry about loading the forign key property value (usually a simple type like an int or so.
Your SELECT element name should be TeamID. When the form is submitted, it will map the selected option value to the TeamID property value of your model which is the foreign key property.
#Html.DropDownListFor(m => m.TeamID, (SelectList)ViewBag.TeamList,
"- Select a Team to Join -", new { #class= "form-control form-control-lg" })
While this might fix the issue, It is a good idea to use a view model instead of using your entity class.
I found the issues I was having. All I needed to get passed into the post action was the Id of the TeamModel. So I changed this line:
#Html.DropDownListFor(m => m.TeamModel.Id, (SelectList)ViewBag.TeamList, "- Select a Team to Join -", new { #class= "form-control form-control-lg" })
I just added the Id and it seemed to work.

asp.net MVC set default value for dropdown list

I'm displaying a dropdown list for countries, which is populated from a database call in the controller. On page load I would like the selected value to default to 'United States'. How do I do this?
Code from view:
<div class="form-group">
#Html.LabelFor(m => m.Country)
#Html.DropDownListFor(m => m.Country, new SelectList(Model.CountriesDDL, "CountryCode", "Country"), "--Select--", new { #class = "form-control" })
</div>
In your GET action, you can set the value of Country property to the CountryCode of United states (or whatever country you want to set as default) of your view model
public ActionResult Show()
{
var vm = new YourViewModel();
vm.CountriesDDL = GetCountriesFromSomeWhere();
vm.Country="United States";
return View(vm);
}
Assuming Country is of type string

How to properly use SelectListItem for HTML.DropDownList instead of SelectList?

I've been digging through other posts trying to figure out how to go from using a SelectList in my controller to fill an #Html.DropDownList in my View to instead use what seems to be the commonly suggested SelectListItem, but I'm completely lost?
I have a main INV_Assets model that when I go to the Edit View, I include Drop Down Lists for other Model Properties (Location, Manufacturer, Model, Status, Type, Vendor, etc.) My current code below adequately fills the lists and allows me on Edit() to change the chosen entity value to any other value stored in that relevant table.
CURRENT CODE:
Controller:
// GET: INV_Assets/Edit/5
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
INV_Assets iNV_Assets = await db.INV_Assets.FindAsync(id);
if (iNV_Assets == null)
{
return HttpNotFound();
}
ViewBag.Location_Id = new SelectList(db.INV_Locations, "Id", "location_dept", iNV_Assets.Location_Id);
ViewBag.Manufacturer_Id = new SelectList(db.INV_Manufacturers, "Id", "manufacturer_description", iNV_Assets.Manufacturer_Id);
ViewBag.Model_Id = new SelectList(db.INV_Models, "Id", "model_description", iNV_Assets.Model_Id);
ViewBag.Status_Id = new SelectList(db.INV_Statuses, "Id", "status_description", iNV_Assets.Status_Id);
ViewBag.Type_Id = new SelectList(db.INV_Types, "Id", "type_description", iNV_Assets.Type_Id);
ViewBag.Vendor_Id = new SelectList(db.INV_Vendors, "Id", "vendor_name", iNV_Assets.Vendor_Id);
return View(iNV_Assets);
}
// POST: INV_Assets/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Id,Model_Id,Manufacturer_Id,Type_Id,Location_Id,Vendor_Id,Status_Id,ip_address,mac_address,note,owner,cost,po_number,description,invoice_number,serial_number,asset_tag_number,acquired_date,disposed_date,created_date,created_by,modified_date,modified_by")] INV_Assets iNV_Assets)
{
if (ModelState.IsValid)
{
db.Entry(iNV_Assets).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewBag.Location_Id = new SelectList(db.INV_Locations, "Id", "location_dept", iNV_Assets.Location_Id);
ViewBag.Manufacturer_Id = new SelectList(db.INV_Manufacturers, "Id", "manufacturer_description", iNV_Assets.Manufacturer_Id);
ViewBag.Model_Id = new SelectList(db.INV_Models, "Id", "model_description", iNV_Assets.Model_Id);
ViewBag.Status_Id = new SelectList(db.INV_Statuses, "Id", "status_description", iNV_Assets.Status_Id);
ViewBag.Type_Id = new SelectList(db.INV_Types, "Id", "type_description", iNV_Assets.Type_Id);
ViewBag.Vendor_Id = new SelectList(db.INV_Vendors, "Id", "vendor_name", iNV_Assets.Vendor_Id);
return View(iNV_Assets);
}
View - Just [Locations] for example:
<div class="form-group">
#*#Html.LabelFor(model => model.Location_Id, "Location_Id", htmlAttributes: new { #class = "control-label col-md-2" })*#
<span class="control-label col-md-2">Location:</span>
<div class="col-md-10">
#Html.DropDownList("Location_Id", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Location_Id, "", new { #class = "text-danger" })
</div>
</div>
What I'm trying to do now is add a value to each list stating "Add New", which I want to allow users to click on and have a (partial view?) popup for them to immediately add a new relevant record (Ex. New [Location] of "Warehouse 2") and then be able to choose that from the [Locations] list for the particular Asset being Edited.
Can anyone walk me through this?
A lot of the suggestions are to add a SelectList or IEnumerable<SelectListItem> to my relevant Model properties, but from there I am lost on what to tweak in my controller/view? Currently I am using Code-First Migrations with an InventoryTrackerContext.cs inside my DAL folder for the project.
You're confusing two very different aspects of this. First, Html.DropDownList only requires an IEnumerable<SelectListItem>. Passing a full SelectList object satisfies this parameter merely because a SelectList is an IEnumerable<SelectListItem>. The advice to not use SelectList is simply to save yourself the work of having to construct a full SelectList object (and remembering to do things like set the selectedValue to the right item), when Razor will handle this for you. Whether you use SelectList or IEnumerable<SelectListItem> has no bearing on the remainder of your question.
As far as adding items to an existing drop down list goes, you have to use JavaScript for that. At a basic level, it's as simple as just just selecting the select element in the DOM and appending a new option node.

How to have a selecteditem "focused" in a dropdown list (asp.net mvc 5) in a dynamically way?

I have table called Roles with the following columns: RoleID, RoleName. The rows of the table are :
RoleID RoleName
1 .NET Developer
2 Java Developer
3 Tester
I have another table called Employees with the following columns: EmployeeID, Name, RoleID (a one-to many relationship with the Roles table).The rows of the table are:
EmployeeID Name RoleID
1 John 1
2 Dan 2
In my ASP.NET MVC 5 application I'm doing a CRUD opperation on employees. When I want to add a emploee I will have, besides the Name field, I have a dropdown list with the role that I want to assign. If I want to create a employee everything works well.
My problem is that, when I want to edit a employee my dropdown list does not work as I am expecting. Lets assume that I want to change Dan's role to a Tester (RoleID should be changed from 2 to 3)
I click edit on the Edit view and the selection of the dropdown list is .NET developer (the first entity), although I want to be a Java Developer (the second entity). I know why. I do not know how to fix it.
The Edit method from the controller which I believe is correct is the following:
[HttpGet]
public ActionResult Edit(int id=0)
{
Employee employeeToUpdate = db.Employees.Find(id);
Role selectedRole = employeeToUpdate.Role;
ViewBag.RoleID = new SelectList(db.Roles, "RoleID", "RoleName",selectedRole);
return View(employeeToUpdate);
}
The code from the view wich I believe I should modify it but I don't know how is the following:
<div class="form-group">
#Html.LabelFor(model => model.RoleID, "RoleID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("RoleID", null, "The Acctual Employee Role", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.RoleID, "", new { #class = "text-danger" })
</div>
</div>
I can delete the parameter "The Acctual Employee Role" but I will get the list of all roles froom the database without being selected the coresponding role (Java Developer).
I tried, to replace the "The Acctual Employee Role" with a #ViewBag.AcctualRole wich was initialized on the controller. Unfortunately that does not work because I may not use dinamycally expresions there.
Any help will be appreciated!
Change your selectlist to (so it does not have the save name as the property name you are binding to)
ViewBag.RoleList = new SelectList(...
and your dropdown to
#Html.DropDownListFor(m => m.RoleID, (SelectList)ViewBag.RoleList, "The Actual Employee Role", htmlAttributes: new { #class = "form-control" }
The initial selected item will now be the value of employeeToUpdate.RoleID

Categories

Resources