I'm only starting in MVC4 and
I'm trying to put multiple partial views in one page every partial is suppose to be with different data but it is always show one partial with only one data
every partial is shown on button click.
This is the view code:
<section id="comments">
<h3>Comments</h3>
#{
foreach (MvcApplication4.Models.comment item in postComments)
{
<article>
<p>#item.body</p>
using (Html.BeginForm("Delete", null, new { id = item.ID ,pid = item.idPost}, FormMethod.Post))
{
#Html.HttpMethodOverride(HttpVerbs.Delete)
<button type="submit" class="button delete" >Delete</button>
}
<section>
<button type="submit" class="button Edit" id="edit" onclick="return showHide();" >Edit</button>
<div id="partial" hidden="hidden">
#Html.Partial("editCom",item)
</div>
</section>
}
}
</article>
}
}
</section>
This is the showhide partial:
<script type="text/javascript" language="javascript">// <![CDATA[
function showHide() {
var ele = document.getElementById("partial");
if(ele.style.display == "block") {
ele.style.display = "none";
}
else {
ele.style.display = "block";
}
}
// ]]></script>
This is the partial :
#using MvcApplication4.Models
#model MvcApplication4.Models.comment
#{comment com = Model;
}
#using (Html.BeginForm("Edit", null,new{ pid=com.idPost,cid=com.ID}, FormMethod.Post))
{
<fieldset>
<div class="editor-label">
#Html.LabelFor(x => com.user)
</div>
<div class="editor-field">
#Html.LabelFor(x => com.user,Session["username"].ToString())
#Html.ValidationMessageFor(x => com.user)
</div>
<div class="editor-label">
#Html.LabelFor(x => com.email)
</div>
<div class="editor-field">
#Html.EditorFor(x => com.email,com.email)
#Html.ValidationMessageFor(x => com.email)
</div>
<div class="editor-label">
#Html.LabelFor(x => com.url)
</div>
<div class="editor-field">
#Html.EditorFor(x => com.url,com.url)
#Html.ValidationMessageFor(x => com.url)
</div>
<div class="editor-label">
#Html.LabelFor(x => com.body)
</div>
<div class="editor-field">
#Html.EditorFor(x => com.body,com.body)
#Html.ValidationMessageFor(x => com.body)
</div>
<p>
<input type="submit" value="save" />
</p>
</fieldset>
}
Your code for
<div id="partial" hidden="hidden">
#Html.Partial("editCom",item)
</div>
Determines which sections are controled by the buttons:
var ele = document.getElementById("partial");
if(ele.style.display == "block") {
ele.style.display = "none";
}
....
You are generating several sections all with the same id of "partial" then expecting the button to determine which div to manage without a unique id of some kind via getElementById("partial")
Instead, you need to generate a unique id for each <div> and then use the same id in your javascript method for getElementById()
Related
i have mvc project to register new student and give him courses and degree,etc, as shown in the database(i use entity framework) database of the project
. the edit view code is :
#model IList<HighStudy.Models.Grade>
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title" align="center">Student Info</h3>
</div>
<div class="panel-body">
<div class="col-lg-4">
<p>Name: #Html.DisplayFor(model => model[0].Student.Name)</p>
<p>Level: #Html.DisplayFor(model => model[0].Student.Level)</p>
</div>
<div class="col-lg-4">
<p>Department: #Html.DisplayFor(model => model[0].Student.Department)</p>
<p>Study Type: #Html.DisplayFor(model => model[0].Student.StudyType)</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-lg-6">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title" align="center">Course 1</h3>
</div>
<div class="panel-body">
<ul class="list-group">
#for (var i = 0; i < Model.Count; i++)
{
if (Model[i].CourseNumber == 1)
{
if (Model[i].Mark == "A" || Model[i].Mark == "B")
{
<li class="list-group-item list-group-item-success">
<div class="row">
<div class="col-lg-8">
#Model[i].Cours.Course_Title
#Html.TextBoxFor(model => Model[i].Cours.Course_Title, new { style = "width:50%" })
#Html.ValidationMessageFor(model => Model[i].Cours.Course_Title)
</div>
<div class="col-lg-2">
#Model[i].Grade1
#Html.TextBoxFor(model => Model[i].Grade1, new { style = "width:30px" })
#Html.ValidationMessageFor(model => Model[i].Grade1)
</div>
<div class="col-lg-2">
#Model[i].Mark
#Html.TextBoxFor(model => Model[i].Mark, new { style = "width:30px" })
#Html.ValidationMessageFor(model => Model[i].Mark)
</div>
</div>
</li>
}
else
{
<li class="list-group-item list-group-item-danger">
<div class="row">
<div class="row">
<div class="col-lg-8">
#Model[i].Cours.Course_Title
#Html.TextBoxFor(model => Model[i].Cours.Course_Title, new { style = "width:50%" })
#Html.ValidationMessageFor(model => Model[i].Cours.Course_Title)
</div>
<div class="col-lg-2">
#Model[i].Grade1
#Html.TextBoxFor(model => Model[i].Grade1, new { style = "width:30px" })
#Html.ValidationMessageFor(model => Model[i].Grade1)
</div>
<div class="col-lg-2">
#Model[i].Mark
#Html.TextBoxFor(model => Model[i].Mark, new { style = "width:30px" })
#Html.ValidationMessageFor(model => Model[i].Mark)
</div>
</div>
</div>
</li>
}
}
}
</ul>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title" align="center">Course 2</h3>
</div>
<div class="panel-body">
<ul class="list-group">
#for (var i = 0; i < Model.Count; i++)
{
if (Model[i].CourseNumber == 2)
{
if (Model[i].Mark == "A" || Model[i].Mark == "B")
{
<li class="list-group-item list-group-item-success">
<div class="row">
<div class="col-lg-8">
#Model[i].Cours.Course_Title
#Html.TextBoxFor(model => Model[i].Cours.Course_Title, new { style = "width:50%" })
#Html.ValidationMessageFor(model => Model[i].Cours.Course_Title)
</div>
<div class="col-lg-2">
#Model[i].Grade1
#Html.TextBoxFor(model => Model[i].Grade1, new { style = "width:30px" })
#Html.ValidationMessageFor(model => Model[i].Grade1)
</div>
<div class="col-lg-2">
#Model[i].Mark
#Html.TextBoxFor(model => Model[i].Mark, new { style = "width:30px" })
#Html.ValidationMessageFor(model => Model[i].Mark)
</div>
</div>
</li>
}
else
{
<li class="list-group-item list-group-item-danger">
<div class="row">
<div class="col-lg-8">
#Model[i].Cours.Course_Title
#Html.TextBoxFor(model => Model[i].Cours.Course_Title, new { style = "width:50%" })
#Html.ValidationMessageFor(model => Model[i].Cours.Course_Title)
</div>
<div class="col-lg-2">
#Model[i].Grade1
#Html.TextBoxFor(model => Model[i].Grade1, new { style = "width:30px" })
#Html.ValidationMessageFor(model => Model[i].Grade1)
</div>
<div class="col-lg-2">
#Model[i].Mark
#Html.TextBoxFor(model => Model[i].Mark, new { style = "width:30px" })
#Html.ValidationMessageFor(model => Model[i].Mark)
</div>
</div>
</li>
}
}
}
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-12">
<input type="submit" value="Save" class="btn btn-default" />
</div>
}
<div class="col-lg-offset-0">
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
and in the controller code for the edit view is :
edit view code in the controller
. when it reach db.Entry(g).State = System.Data.Entity.EntityState.Modified;
it goes to catch block!!
any help will be useful, thanks in advance.
I believe you should iterate over your collection to add each object to the context, and set it to Modified.
foreach(grade in g)
{
db.Entry(grade).State = EntityState.Modified;
}
db.SaveChanges();
You must do SaveChanges outside the foreach statement
db.Entry(g).State = System.Data.Entity.EntityState.Modified;
In the above code you are getting g from another object, you need to originate it from the same db object which you are using to change the State
another things could be the list, I think state of List can't be modified altogether.
consider doing something like this
foreach (var item in g)
{
db.Set<Grade>().Attach(item);
db.Entry<Grade>(item).State = EntityState.Modified;
db.Configuration.ValidateOnSaveEnabled = false;
}
db.SaveChanges();
Recently gone through the same error, and foreach saved my life. Not sure if its a very clean way to do it.
SOLVED
my current exception was :
( Unable to update the EntitySet - because it has a DefiningQuery and no element exists in the element to support the current operation
steps that solve it :
delete all duplicate #html.hiddenfor(model=> model.StudentID) in the edit view
Right click on .edmx file and chose open with xml editor
search for DefiningQuery and Remove it, yes Remove it
search for ( store:Schema="dbo" ) and rename it to ( Schema="dbo" )
these were the steps that saved my life, thank you all my friends for help, i really appreciate your help
This is my controller code. I have one view and inside that i have one partial view. At the end in partial view i have one submit button. When i click this button i want to save data of main view and partial view to thier respective tables.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication2.Models;
using System.Data.Entity.Validation;
namespace MvcApplication2.Controllers
{
public class HomePageController : Controller
{
//
// GET: /HomePage/
MVCDemoEntities db = new MVCDemoEntities();
public ActionResult Submit()
{
List<DocTypeMaster> alldoclist = new List<DocTypeMaster>();
using (MVCDemoEntities db = new MVCDemoEntities())
{
alldoclist = db.DocTypeMasters.OrderBy(a => a.DocTypeName).ToList();
}
ViewBag.docid = new SelectList(alldoclist, "Id", "DocTypeName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Submit(DetailsEntry de)
{
List<DocTypeMaster> alldoclist = new List<DocTypeMaster>();
using (MVCDemoEntities db = new MVCDemoEntities())
{
alldoclist = db.DocTypeMasters.OrderBy(a => a.DocTypeName).ToList();
}
ViewBag.docid = new SelectList(alldoclist, "Id", "DocTypeName", de.DocumentId);
return View(de);
}
[HttpGet]
public PartialViewResult RacersByCountryPartial(string id)
{
Passport ps = new Passport();
Pan pn = new Pan();
string id1 = id.Trim();
if (id1 == "Passport")
return PartialView("~/Views/HomePage/id1.cshtml", ps);
else
return PartialView("~/Views/HomePage/pancard.cshtml", pn);
}
[HttpPost]
public ActionResult RacersByCountryPartial(string id,Passport ps, Pan pn,DetailsEntry dt)
{
return View(id);
}
}
}
this is my Mainview.
#model MvcApplication2.DetailsEntry
#{
ViewBag.Title = "Submit";
}
<h2>Submit</h2>
#using (Html.BeginForm("Submit", "HomePage", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>DetailsEntry</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ClientId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ClientId)
#Html.ValidationMessageFor(model => model.ClientId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ClientName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ClientName)
#Html.ValidationMessageFor(model => model.ClientName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EmployeeId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmployeeId)
#Html.ValidationMessageFor(model => model.EmployeeId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EmpCitizenId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmpCitizenId)
#Html.ValidationMessageFor(model => model.EmpCitizenId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EmpName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmpName)
#Html.ValidationMessageFor(model => model.EmpName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Nationality)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Nationality)
#Html.ValidationMessageFor(model => model.Nationality)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.DocumentId)
</div>
<div class="editor-field">
#Html.DropDownListFor(Model => Model.DocumentId, #ViewBag.docid as SelectList,"Select document Type")
#Html.ValidationMessageFor(Model=>Model.DocumentId)
</div>
</fieldset>
}
<div id="container"> </div>
<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.js"></script>
<script src="//code.jquery.com/jquery-1.11.2.min.js" type="text/javascript"></script>
<script type="text/javascript" src="scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery-1.7.1.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#DocumentId").change(function () {
$("#log").ajaxError(function (event, jqxhr, settings, exception) {
alert(exception);
});
var countrySelected = $("select option:selected").first().text();
$.get('#Url.Action("RacersByCountryPartial")',
{ id: countrySelected }, function (data) {
$("#container").html(data);
});
});
});
</script>
This is my partial view.
#model MvcApplication2.Passport
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Passport</legend>
<div class="editor-label">
#Html.LabelFor(model => model.pissueddate)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.pissueddate)
#Html.ValidationMessageFor(model => model.pissueddate)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.pissuedlocation)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.pissuedlocation)
#Html.ValidationMessageFor(model => model.pissuedlocation)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.pimage)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.pimage)
#Html.ValidationMessageFor(model => model.pimage)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
There is one submit button at the end of partial view. I want to save both main view and partial view data on single button click to respective tables. Please advise me.
So, if I understand correctly what you're trying to achieve...
Remove the submit button from the partial view and move it to the main view
Remove the form from the partial view and let the main form to handle a whole user's input - in your case you have two forms, that means each form should submit its own data to the respective controller/action. Nesting of html forms is impossible - Can you nest html forms?
If you need to do some actions (like showing dynamic dropdowns with loading of different data or something else) - do that as separate AJAX calls inside the partial view. But the main form, that finally submits data, should be the only one.
I'm using MVC 4 and Entity Framework and Grid.MVC for datagrid.
I have tried to implement a modal dialog to edit records using bootstrap.
When i click edit, modal window does not appear.
I follow the instruction how to create modal here:
Popup dialog for editing record using Grid.MVC in a ASP.NET MVC3
here is my code
YOU CAN DOWNLOAD MY SAMPLE PROJECT HERE
HomeController
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
[HttpGet]
public ActionResult HR201()
{
DCHREmployee dchremp = new DCHREmployee();
List<HREmployee> hrempList = new List<HREmployee>();
foreach (HREmployee hremp_ in dchremp.GetHREmployee(""))
{
hrempList.Add(hremp_);
}
return View(hrempList);
}
[HttpGet]
public ActionResult Edit(String EmpID)
{
DCHREmployee dchremp = new DCHREmployee();
List<HREmployee> hrempList = new List<HREmployee>();
foreach (HREmployee hremp_ in dchremp.GetHREmployee(EmpID))
{
hrempList.Add(hremp_);
}
return View(hrempList[0]);
}
}
HR201 cshtml view
#model IEnumerable<TAObjectModel.HREmployee>
#using GridMvc.Html
#using TAObjectModel
#{
ViewBag.Title = "HR201";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<link href="#Url.Content("~/Content/Gridmvc.css")" rel="stylesheet" />
<link href="#Url.Content("~/Content/bootstrap.min.css")" rel="stylesheet" />
<script src="#Url.Content("~/Scripts/bootstrap.min.js")"></script>
<script src="#Url.Content("~/Scripts/jquery-1.9.0.min.js")"></script>
<script src="#Url.Content("~/Scripts/gridmvc.min.js")"></script>
<title>Index</title>
</head>
<body>
<div class="container">
</div>
<div class="container">
#helper RenderDeleteForm(HREmployee hremp)
{
<form method="POST" action="#Url.Action("Delete", "HR201", new { EmpID = hremp.EmpID })">
<button type="submit" class="modal-link" onclick="return confirm('Are you sure you want to delete employee: #hremp.LastNm?');">
Delete
</button>
</form>
}
<h2>HR201</h2>
<div class="pull-left">
#using (Html.BeginForm())
{
<button type="submit" class="btn btn-primary">Add</button>
<button type="submit" class="modal-link">MODAL</button>
}
</div>
#Html.Grid(Model).Columns(columns =>
{
columns.Add(c => c.EmpID).Titled("EmpID").Filterable(true);
columns.Add(c => c.FirstNm).Titled("First Name");
//columns.Add(c => c.MiddleNm).Titled("Middle Name");
//columns.Add(c => c.LastNm).Titled("Lastn Name");
columns.Add(c => c.BirthDt).Titled("BirthDay").Format("{0:dd MMM yyyy}").Filterable(true);
columns.Add().Titled("Action")
.Sanitized(false)
.Encoded(false)
.RenderValueAs(d => Html.ActionLink("Edit", "Edit", new { EmpID = d.EmpID }, new { #class = "modal-link" }));
columns.Add().Titled("Action2")
.Sanitized(false)
.Encoded(false)
.RenderValueAs(c => RenderDeleteForm(c));
}).WithPaging(10).Sortable(true)
#Html.ActionLink("Click to Add Customer", "Edit",new{EmpID = "E9770003"}, new { #class = "modal-link" })
</div>
<!-- Modal -->
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">Ă—</button>
<h3 id="myModalLabel">Modal header</h3>
</div>
<div class="modal-body">
<p>Loading…</p>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<button class="btn btn-primary">Save changes</button>
</div>
</div>
<script>
//this script reset modal each time when you click on the link:
$(function () {
$(".modal-link").click(function (event) {
event.preventDefault();
$('#myModal').removeData("modal");
$('#myModal').modal({ remote: $(this).attr("href") });
});
})
</script>
</body>
</html>
EDIT VIEW
<div class="container">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>HREmployee</legend>
<div class="editor-label">
#Html.LabelFor(model => model.EmpID)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmpID)
#Html.ValidationMessageFor(model => model.EmpID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.FirstNm)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstNm)
#Html.ValidationMessageFor(model => model.FirstNm)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastNm)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastNm)
#Html.ValidationMessageFor(model => model.LastNm)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.MiddleNm)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.MiddleNm)
#Html.ValidationMessageFor(model => model.MiddleNm)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.SenseID)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SenseID)
#Html.ValidationMessageFor(model => model.SenseID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.NickNm)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.NickNm)
#Html.ValidationMessageFor(model => model.NickNm)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.BirthDt)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.BirthDt)
#Html.ValidationMessageFor(model => model.BirthDt)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
</div>
**
I have a Create cshtml Page as follows :-
#model MvcCommons.ViewModels.CompositeViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Article</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.ArticleTitle)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ArticleViewModel.Article.ArticleTitle)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleTitle)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.ArticleDate)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ArticleViewModel.Article.ArticleDate)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleDate)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.ArticleText)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ArticleViewModel.Article.ArticleText)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleText)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.ArticleSource)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ArticleViewModel.Article.ArticleSource)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleSource)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.CategoryID, "Category")
</div>
<div class="editor-field">
#Html.DropDownList("CategoryID", String.Empty)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.CategoryID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
and then I am getting the viewModel inside the Create Action as follows :-
[HttpPost]
public ActionResult Create(CompositeViewModel viewModel)
{
if (ModelState.IsValid)
{
unitOfWork.ArticleRepository.Insert(viewModel.ArticleViewModel.Article);
unitOfWork.Save();
return RedirectToAction("Index");
}
PopulateDropDownList(viewModel.ArticleViewModel.Article.CategoryID);
return View(viewModel);
}
The PopulateDropDownList code is as follows :-
private void PopulateDropDownList(object selectedCategory = null)
{
var categoryQuery = unitOfWork.CategoryRepository.Get(
orderBy: q => q.OrderBy(d => d.CategoryTitle));
ViewBag.CategoryID = new SelectList(unitOfWork.CategoryRepository.Get(), "CategoryID", "CategoryTitle", selectedCategory);
}
My problem is that the CategoryID inside the CompositeViewModel viewModel is always 0 no matter what values I choose in the dropdown list! The other data entered in the Create cshtml is filled correctly inside the viewModel.
I cannot spot what I am doing wrong.
Thanks for your help and time
Shouldn't you be using DropDownListFor:
#Html.DropDownListFor(model => model.ArticleViewModel.Article.CategoryID, (SelectList)ViewBag.CategoryID)
You should write
#Html.DropDownList("ArticleViewModel.Article.CategoryID", ViewBag.CategoryID, null)
so ModelBinding works correctly or even use DropDownListFor<>().
this is my controller:
public ActionResult Create() {
Number newNumber = new Number();
return View(newNumber);
}
and View :
#model PhoneBook.Models.Number
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="../../Scripts/jQuery.AddNewNumber.js" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.Contact.Id)
<fieldset>
<legend>Number</legend>
<div class="TargetElements">
<div class="editor-label">
#Html.LabelFor(model => model.PhoneNumber)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhoneNumber)
#Html.ValidationMessageFor(model => model.PhoneNumber)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.NumberKind)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.NumberKind.Title, NumberKinds)
</div>
</div>
<p>
<input class="AddNew" value="Add New" type="button" /></p>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
By press AddNew button (use jQuery AddNewNumber.js) new input+DropDown Added to form in client side. But there is a problem in retrieve values, When I have one entry element(include input+DropDown) I can retrieve values like the following in post of my controller:
[HttpPost]
public ActionResult Create(Number NewNumber, FormCollection collection) {
db.Numbers.Add(NewNumber);
db.SaveChanges();
return RedirectToAction("Index")
}
But when there is multi-entry how can I retrieve values and add them to DataBase?
Use by the name of element like this:
string[] PhoneNumbers = collection.GetValues("PhoneNumber");
You want all of your input elements to have the same name. Then in your POST action method, the parameter would be List. Here is an example:
Model Binding to a List of objects