Hi i am new in mvc and I'm trying to send my dropdown value to database and post it to table, any suggest best way how it will work ? .. thanks in advance
ContactController.cs
public ActionResult Create()
{
List<SelectListItem> items = new List<SelectListItem>();
items.Add(new SelectListItem { Text = "English", Value = "0", Selected = true });
items.Add(new SelectListItem { Text = "German", Value = "1" });
items.Add(new SelectListItem { Text = "Spanish", Value = "2"});
items.Add(new SelectListItem { Text = "Italian", Value = "3" });
ViewBag.LanguageList = items;
return View();
}
Create.cshtml
<div class="editor-label">
#Html.LabelFor(model => model.language)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.language, new SelectList(ViewBag.LanguageList))
#Html.ValidationMessageFor(model => model.language)
</div>
Index.cshtml
<td>
#Html.DisplayFor(modelItem => item.language)
</td>
Ok, put your Dropdown selection in a form with a submit button:
using (Html.BeginForm("Create", "ContactController", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<div class="editor-label">
#Html.LabelFor(model => model.language)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.language, new SelectList(ViewBag.LanguageList))
#Html.ValidationMessageFor(model => model.language)
</div>
<input type="submit" value="Enable" class="btn btn-link" />
}
Controller:
//This action can only be accessed with the Http.Post verb
[HttpPost]
//Validate the antiforgerytoken we set with `#Html.AntiForgeryToken()` in the view (Prevents CSRF attacks)
[ValidateAntiForgeryToken]
public ActionResult Create(YourModel model)
{
//Your model will now contain the value of the selected dropdown if you have wired up your model correctly.
//Connect to db, persist model.language
return View();
}
Related
I have a partial view for editing a collection (most of which I've truncated here):
#using CustomSurveyTool.Models
#model Basiclife
<div class="editorRow">
#using (Html.BeginCollectionItem(""))
{
<div class="form-horizontal">
<div class="row">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-md-2">
#Html.LabelFor(model => model.Plantype, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Plantype, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Plantype, "", new { #class = "text-danger" })
</div>
<div class="col-md-1">
X
</div>
</div>
</div>
}
</div>
Which is part of a wrapper view:
#using CustomSurveyTool.Models
#model IEnumerable<Basiclife>
#{
ViewBag.Title = "CreateBasicLifeResponse";
}
<h2>Basic Life Insurance Plans</h2>
<div id="planList">
#using (Html.BeginForm())
{
<div id="editorRows">
#foreach (var item in Model)
{
#Html.Partial("_BasicLifeResponse", item)
}
</div>
#Html.ActionLink("Add", "BasicLifeResponse", null, new { id = "addItem", #class = "button" });
<input type="submit" value="submit" />
}
</div>
Which posts back to this controller:
[HttpPost]
public ActionResult CreateBasicLifeResponse(IEnumerable<Basiclife> model)
{
foreach(var item in model)
{
string currentUserId = User.Identity.GetUserId();
Response targetresponse = db.response.FirstOrDefault(x => x.Userid == currentUserId);
int responseid = targetresponse.Id;
item.ResponseId = responseid;
db.basiclife.Add(item);
db.SaveChanges();
}
List<Basiclife> basiclife = new List<Basiclife>();
return View(model);
}
I am getting a NullReferenceException on the foreach(var item in model) after submitting the form. What could be causing this?
You need to follow the MVC naming convention which involves using a for loop with an index instead of foreach in your Razor view. Check out this article:
How to pass IEnumerable list to controller in MVC including checkbox state?.
I would recommend the Editor Template approach described in the article, it is most similar to your current PartialView approach.
I'm unable to get selected value in dropdown using simple below code -
<select class="form-control" id="team-name" name="gameTypes">
#{long selectedOption = #ViewBag.HomeTeamId;}
#foreach (var item in Model.teams)
{
<option value="#item.TeamId" data-logo="#item.LogoURL" selected="#(selectedOption == #item.TeamId ? "selected" : "")">#item.FullName</option>
}
</select>
I would do it like this:
Write your method to get the needed Teams in a List<SelectListItem> and then in your controller put the values in a ViewBag (ViewBag.Teams = GetTeams();)
For exmaple:
[NonAction]
private List<SelectListItem> GetTeams()
{
IEnumerable<Team> teams = new List<Team>();
//fill the teams here from the DB
return teams.Select(team => new SelectListItem
{
Text = team.TeamName, //here you can select the property that you want to show as text in the dropdown
Value = team.ID.ToString()
}).ToList();
}
And in your view, retrieve
#{
List<SelectListItem> teams = ViewBag.Teams as List<SelectListItem>;
}
And here define your dropdown and pass teams as the datasource:
<div class="col-md-6 form-group">
#Html.LabelFor(model => model.TeamId, htmlAttributes: new { #class = "control-label" })
#Html.DropDownListFor(model => model.TeamId, teams, "Select a team", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.TeamId, "", new { #class = "text-danger" })
</div>
I am using BeginForm and the initial value of one of the Dropdown's is not being set properly. The value is held in a SelectLitemItem and is correctly shown in the preceding Table (in the Index view). The available values provided for list are also correct. It always defaults to "Create" which has a value of "1" even when it should be "Update" which has a value of "2".
The Model.RuleType.Value is shown correctly if I just display it on the form.
I cannot see what I'm doing wrong. I can see no duplicate ID/ Name and have tried including a Hidden field.
There is another dropdown that happens to use a common value for both Value and Text and that works.
Any ideas?
Thanks.
#model AMS.Web.Areas.Admin.Models.RuleActionModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true) #Html.HiddenFor(model => model.ID)
<div class="form-group">
#Html.LabelFor(model => model.RuleType, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Partial("Partials/_RuleTypeDropdown") #Html.ValidationMessageFor(model => model.RuleType)
</div>
</div>
RuleTypeDropdown
#using Kendo.Mvc.UI;
#(Html.Kendo().DropDownList()
.Name("RuleType")
.DataTextField("Text")
.DataValueField("Value")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("RuleTypeList", "List", new { Area = "Admin" });
});
})
)
Model
public class RuleActionModel
{
public RuleActionModel() { }
public RuleActionModel(RuleAction ruleAction)
{
...
RuleType = new SelectListItem()
{
Value = ruleAction.RuleType.ToString(),
Text = ((RuleType)(ruleAction.RuleType)).EnumToString()
};
}
[Display(Name = "Type")]
public SelectListItem RuleType { get; set; }
Controller
public ActionResult Edit(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
RuleAction ruleAction = UnitOfWork.RuleActionRepository.FirstOrDefault(x => x.ID == id);
if (ruleAction == null)
{
return HttpNotFound();
}
var model = new RuleActionModel(ruleAction);
return View(model);
}
I have a html selector, and I want to use the selected value for my "model => model.type" in my form. Is there a way to set the value in my #Html.EditorFor(model => model.type) to the value of the selector?
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Bet</legend>
<div class="editor-label">
#Html.LabelFor(model => model.type)
</div>
<div class="editor-field">
<select id ="type">
<option value="Football">Football</option>
<option value="Rugby">Rugby</option>
<option value="Horse Racing">Horse Racing</option>
</select>
#Html.EditorFor(model => model.type)
#Html.ValidationMessageFor(model => model.type)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
You can try with this options:
Model:
public string Type { get; set; }
public IEnumerable<SelectListItem> TypeList
{
get
{
return new List<SelectListItem>
{
new SelectListItem { Text = "Football", Value = "Football"},
new SelectListItem { Text = "Rugby", Value = "Rugby"},
new SelectListItem { Text = "Horse Racing", Value = "Horse Racing"}
};
}
}
HTML (Razor):
#Html.DropDownListFor(model => model.Type, Model.TypeList)
OR
HTML (Razor):
#Html.DropDownListFor(model => model.Type, new SelectList(new string[] {"Football", "Rugby", "Horse Racing"}, Model.Type))
#andresdescalzo's solution (last one) works with a minor change:
#Html.DropDownListFor(model => model.Type, new SelectList(new string[] {"Football", "Rugby", "Horse Racing"}, "Rugby"), htmlAttributes: new { #class = "form-control" })
First: Add a selected item for dropdown list (e.g. "Rugby")
Second: remove last Model.Type and add htmlAttributes
PS: SelectedList open parentheses closed after selected item of list (here is "Rugby")
The solution provided by #andresdescalzo works only when we pass the model from Controller to the view.
public class SomeController : Controller
{
public ActionResult SomeAction()
{
return View(new SomeModelWithIEnumerationsSelectListItem())
}
}
An addition to the existing answers: If you get the exception "object reference not set to an instance of an object" when implementing #andresdescalzo's solution, you either need to:
Return the model that you are working with as #diwas mentioned
Instantiate a model on the razor page so you can call the method. This is helpful if you are using a ViewModel instead of a simple EF model.
The second can be done like this:
#{ var tempModel = new YourNameSpace.Models.YourModel(); }
#Html.DropDownListFor(model => model.Type, tempModel.TypeList, Model.Type))
This is the Razor View
<div class="editor-field col-md-3">
#Html.DropDownListFor(model => model.Servers,
Model.AvailableServers,new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.SqlServerName)
</div>
Dynamic DropDown from controller
List<SelectListItem> ServersAvailable = new List<SelectListItem>();
bool IdSelected = false;
ServersAvailable.Add(new SelectListItem { Text = "......Select your server name......", Value = "" });
for (int i = 0; i < dt.Rows.Count; i++)
{
ServersAvailable.Add(new SelectListItem
{
Text = dt.Rows[i].ItemArray[0].ToString(),
Value = dt.Rows[i].ItemArray[0].ToString(),
Selected = IdSelected
});
}
I want to insert a fixed date into table. How can I do this ?
<div class="editor-label">
Description :
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Description, new { #class = "textboxes" })
#Html.ValidationMessageFor(model => model.Description)
</div>
<div class="editor-label">
Date :
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Date, new { #class = "textboxes" }) /// I wanna be here a fixed date .
#Html.ValidationMessageFor(model => model.Date)
</div>
My controller code is:
public ActionResult Index(tblOrder tblorder)
{
if (ModelState.IsValid)
{
db.tblOrders.AddObject(tblorder);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.fxBudjet = new SelectList(db.tblBudjets, "ID", "Budjet", tblorder.fxBudjet);
ViewBag.fxServiceType = new SelectList(db.tblServiceTypes, "ID", "Service", tblorder.fxServiceType);
ViewBag.fxStartTime = new SelectList(db.tblStartDates, "ID", "StartDate", tblorder.fxStartTime);
return View(tblorder);
}
Do I need to change my controller code?
#Html.DisplayTextFor(model => model.Date, new { #class = "textboxes" })
if the date is needed in a post you can do
#Html.DisplayTextFor(model => model.Date, new { #class = "textboxes" })
#Html.HiddenFor(model => model.Date)
or in the post method you can use TryUpdateModel and exclude the date field
Edit from your update i would set the value for the model in the controller e.g. say you had a class year that you wanted to prepopulate the year value
public ActionResult Create()
{
return View(new Year() { Value = DateTime.Now.Year });
}
again if you want it for the post you can use a hiddenfor or else regenerate it in the post
if this field is only required in the post method a better option might be to create a viewmodel without that field and then have some mapping logic in the post method
Edit 2: As with MVC music store you should really have 2 methods a get and a post. I will assume it is for a create.
[HttpGet]
public ActionResult Create()
{
ViewBag.fxBudjet = new SelectList(db.tblBudjets, "ID", "Budjet");
ViewBag.fxServiceType = new SelectList(db.tblServiceTypes, "ID", "Service");
ViewBag.fxStartTime = new SelectList(db.tblStartDates, "ID", "StartDate");
return View(new tblOrder() { Date = DateTime.Now });
}
[HttpPost]
public ActionResult Create(tblOrder tblorder)
{
if (ModelState.IsValid)
{
db.tblOrders.AddObject(tblorder);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.fxBudjet = new SelectList(db.tblBudjets, "ID", "Budjet", tblorder.fxBudjet);
ViewBag.fxServiceType = new SelectList(db.tblServiceTypes, "ID", "Service", tblorder.fxServiceType);
ViewBag.fxStartTime = new SelectList(db.tblStartDates, "ID", "StartDate", tblorder.fxStartTime);
return View(tblorder);
}
then in your view something like
#model tblOrder
#Html.BeginForm()
{
#Html.DisplayTextFor(model => model.Date, new { #class = "textboxes" })
#Html.HiddenFor(model => model.Date)
...other form stuff
<input type="submit" value="Delete" />
}
Hopefully this should give you some idea of how to fix your code