MVC4 application on handling list - asp.net-mvc-4

This is my model class with two classes Employee and Employee list
namespace EditMultiplerecords.Models
{
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Employeelist : IEnumerable<Employee>
{
public List<Employee> employee { get; set; }
public IEnumerator<Employee> GetEnumerator()
{
return employee.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return employee.GetEnumerator();
}
}
}
This is my View where i am writing code for editing using javascript
#model EditMultiplerecords.Models.Employeelist
#{
ViewBag.Title = "Homepage";
}
<link href="../../Content/StyleSheet1.css" rel="stylesheet" type="text/css" />
<script src="../../Scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$('.editor input').blur(function () {
$(this).hide();
$(this).closest('p').find('label').html($(this).val()).show();
});
$('.editor label').click(function () {
$(this).hide();
$(this).closest('p').find('input').show();
});
});
</script>
#foreach (var item in Model)
{
using (Html.BeginForm())
{
<div class="editor">
<p>
#Html.HiddenFor(x => item.Id)
#Html.LabelFor(x => item.Name, item.Name)
#Html.EditorFor(x => item.Name)
<input type="submit" value="OK" />
</p>
</div>
}
#* #Html.Partial("Details", item);*#
}
And this controller class
public ActionResult Homepage()
{
Employeelist el = new Employeelist();
el.employee = new List<Employee>();
el.employee.Add(new Employee { Id = 1, Name = "Rahul" });
el.employee.Add(new Employee { Id = 2, Name = "America" });
el.employee.Add(new Employee { Id = 3, Name = "NewJersey" });
return View(el);
}
[HttpPost]
public ActionResult Homepage(Employeelist el)
{
return View(el);
}
My problem is when i edit Rahul or America or NewJersey, on Post Action iam getting an empty list with null values rather an updated list

you need to add #foreach (var item in Model) loop inside using (Html.BeginForm()) to accept modified List
using (Html.BeginForm())
{
#foreach (var item in Model)
{
<div class="editor">
<p>
#Html.HiddenFor(x => item.Id)
#Html.LabelFor(x => item.Name, item.Name)
#Html.EditorFor(x => item.Name)
</p>
</div>
}
}
<input type="submit" value="OK" />
#* #Html.Partial("Details", item);*#
-- Edit Accept formCollection
[HttpPost]
public ActionResult Homepage(FormCollection formCollection)
{
var itemid = formCollection.GetValue("item.id");
var itemname= formCollection.GetValue("item.name");
---//use values to send it back to view----
return View();
}

Related

ASP.Net MVC: When form post then one view model property getting null

i have simple form where one dropdown and one submit button. i have two index function one for get and one for form post. when i select a product from dropdown and click on submit button then my index action getting invoke but there i notice my products property getting null. see my code please and tell me where i made the mistake.
view code
#model AuthTest.Models.SampleViewModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>DateValTest</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Products, htmlAttributes: new { #class = "control-label col-md-2", style = "padding-top:0px;" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.SelectedProductId, new SelectList(Model.Products, "ID", "Name"), "-- Select Product--")
#Html.ValidationMessageFor(model => model.SelectedProductId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Submit" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
model code
public class Product
{
public int ID { set; get; }
public string Name { set; get; }
}
public class SampleViewModel
{
[Display(Name = "Products")]
public List<Product> Products { set; get; }
[Required(ErrorMessage = "Select any one")]
public int SelectedProductId { set; get; }
}
controller code
public class TestValController : Controller
{
// GET: TestVal
public ActionResult Index()
{
var SampleVM = new SampleViewModel();
SampleVM.Products = new List<Product>
{
new Product{ ID=1, Name="IPhone" },
new Product{ ID=2, Name="MacBook Pro" },
new Product{ ID=3, Name="iPod" }
};
return View(SampleVM);
}
[HttpPost]
public ActionResult Index(SampleViewModel vm)
{
var SampleVM = new SampleViewModel();
SampleVM.Products = new List<Product>
{
new Product{ ID=1, Name="IPhone" },
new Product{ ID=2, Name="MacBook Pro" },
new Product{ ID=3, Name="iPod" }
};
if (ModelState.IsValid)
return View(vm);
else
return View(SampleVM);
}
}
when i debug second action then i saw vm products property getting null
please tell me where i made the mistake?
thanks
You are not making any mistake, You are not getting the list of products back because you are not including them in the HTML input form.
If you want to include the list of products you can add the following inside the input form
#for (int i = 0; i < Model.Products.Count(); i++)
{
<div>
#Html.HiddenFor(model => Model.Products[i].Name)
#Html.HiddenFor(model => Model.Products[i].ID)
</div>
}
#Mou,
Please modify your razor view and try this.
In Razor View nowhere you have specified the Http verb(Get,Post).
#using (Html.BeginForm("Index", "TestVal", FormMethod.Post)

i would like to populate one drop down list using another drop down list

i tried a code from a video and got an error :
This is the Error when i click my drop down to display the states from country
this is my controller code:
public ActionResult Submit()
{
List<Country> allCountry = new List<Country>();
List<State> allState = new List<State>();
using (DropDownTestEntities1 dc = new DropDownTestEntities1())
{
allCountry = dc.Countries.OrderBy(a => a.CountryName).ToList();
}
ViewBag.CountryID = new SelectList(allCountry, "CountryID", "CountryName");
ViewBag.StateID = new SelectList(allState, "StateID", "StateName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken] // this is for prevent CSRF Attack
public ActionResult Submit(Feedback fb)
{
List<Country> allCountry = new List<Country>();
List<State> allState = new List<State>();
using (DropDownTestEntities1 dc = new DropDownTestEntities1())
{
allCountry = dc.Countries.OrderBy(a => a.CountryName).ToList();
if (fb != null && fb.CountryID > 0)
{
allState = dc.States.Where(a => a.CountryID.Equals(fb.CountryID)).OrderBy(a => a.StateName).ToList();
}
}
ViewBag.CountryID = new SelectList(allCountry, "CountryID", "CountryName", fb.CountryID);
ViewBag.StateID = new SelectList(allState, "StateID", "StateName", fb.StateID);
if (ModelState.IsValid)
{
using (DropDownTestEntities1 dc = new DropDownTestEntities1())
{
dc.Feedbacks.Add(fb);
dc.SaveChanges();
ModelState.Clear();
fb = null;
ViewBag.Message = "Successfully submitted";
}
}
else
{
ViewBag.Message = "Failed! Please try again";
}
return View(fb);
}
[HttpGet]
public JsonResult GetStates(string countryID = "")
{
List<State> allState = new List<State>();
int ID = 0;
if (int.TryParse(countryID, out ID))
{
using (DropDownTestEntities1 dc = new DropDownTestEntities1())
{
allState = dc.States.Where(a => a.CountryID.Equals(ID)).OrderBy(a => a.StateName).ToList();
//allState = dc.States.Where(a => a.CountryID.Equals(ID)).OrderBy(a => a.StateName).ToList();
}
}
if (Request.IsAjaxRequest())
{
return new JsonResult
{
Data = allState,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
return new JsonResult
{
Data = "Not valid request",
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
}
}
this is my model code :
public partial class Feedback
{
public int FeedbackID { get; set; }
[Display(Name = "Full Name")]
[Required(ErrorMessage = "Please provide your fullname", AllowEmptyStrings = false)]
public string FullName { get; set; }
[Display(Name = "Mobile No")]
public string MobileNo { get; set; }
[Display(Name = "Country")]
[Required(ErrorMessage = "Please select country", AllowEmptyStrings = false)]
public int CountryID { get; set; }
[Display(Name = "State")]
[Required(ErrorMessage = "Please select state", AllowEmptyStrings = false)]
public int StateID { get; set; }
}
and this is my view with my ajax code :
#using (Html.BeginForm("Submit", "Feedback", FormMethod.Post))
{
#Html.ValidationSummary(true)
#Html.AntiForgeryToken()
<fieldset>
<legend>Feedback</legend>
#if (ViewBag.Message != null)
{
<div style="border:solid 1px black">
#ViewBag.Message
</div>
}
<div class="editor-label">
#Html.LabelFor(model => model.FullName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FullName)
#Html.ValidationMessageFor(model => model.FullName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.MobileNo)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.MobileNo)
#Html.ValidationMessageFor(model => model.MobileNo)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CountryID)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.CountryID, #ViewBag.CountryID as SelectList, "Select Country")
#Html.ValidationMessageFor(model => model.CountryID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.StateID)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.StateID, #ViewBag.StateID as SelectList, "Select State")
#Html.ValidationMessageFor(model => model.StateID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script language="javascript">
$(document).ready(function () {
$("#CountryID").change(function () {
// this will call when Country Dropdown select change
var countryID = parseInt($("#CountryID").val());
if (!isNaN(countryID)) {
var ddState = $("#StateID");
ddState.empty(); // this line is for clear all items from State dropdown
ddState.append($("<option></option").val("").html("Select State"));
// Here I will call Controller Action via Jquery to load State for selected Country
$.ajax({
url: "#Url.Action("GetStates","Feedback")",
type: "GET",
data: { countryID: countryID },
dataType: "json",
success: function (data) {
$.each(data, function (i, val) {
ddState.append(
$("<option></option>").val(val.StateID).html(val.StateName)
);
});
},
error: function () {
alert("Error!");
}
});
}
});
});
</script>
}
All i want is for my country selecteditem to populate my state with the link between the two. E.g. if i select South Africa, it must only display Gauteng, Cape Town etc.
Please can your'll help me with my error or provide guidance thanks.
Issue 1: Try using == instead of using .Equals() because if CountryIDis null, you'll throw an error.
Issue 2: Change
if (Request.IsAjaxRequest())
{
return new JsonResult
{
Data = allState,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
to
return Json(allState, JsonRequestBehavior.AllowGet);
Possible Issue 3?
Try this as your success function:
success: function (data) {
$(data).each(function () {
ddState.append(
$("<option></option>").val(this.StateID).html(this.StateName)
);
});
},

MvC multiple submits diffrent columns same row

So this is the code, i have 2 submit buttons when i press "Start" I want it to send the Datetime.now to the start row, and when i press "Stop" i want it to send the Stop datetime.now to the column, this should be happening in the same row. And when i press Start again it should generate a new ID 2, etc. print the start date on the second row.
Exampel ID 1 : Start 2013-11-15 05:12 Slut : 2013-11-15 05:15
Greetings Patrik
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.LabelFor(model => model.Start)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Start, new { style = "display: none;", #Value = #DateTime.Now })
#Html.ValidationMessageFor(model => model.Start)
</div>
<p>
<input type="submit" name="#Html.NameFor(x => x.Command)" value="Start" formaction="/tider/create" />
</p>
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.LabelFor(model => model.Slut)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Slut, new { #Value = #DateTime.Now })
#Html.ValidationMessageFor(model => model.Slut)
</div>
<p>
<input type="submit" name="#Html.NameFor(x => x.Command)" value="Stop" />
</p>
}
</fieldset>
<div class="editor-label">
#Html.LabelFor(model => model.Slut)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Slut, new { #Value = #DateTime.Now })
#Html.ValidationMessageFor(model => model.Slut)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
controller
{
public class TiderController : Controller
{
private TiderDBContext db = new TiderDBContext();
//
// GET: /Tider/
public ActionResult Index()
{
return View(db.Tider.ToList());
}
//
// GET: /Tider/Details/5
public ActionResult Details(int id = 0)
{
ArbetsTider arbetstider = db.Tider.Find(id);
if (arbetstider == null)
{
return HttpNotFound();
}
return View(arbetstider);
}
//
// GET: /Tider/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Tider/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ArbetsTider arbetstider)
{
if (ModelState.IsValid)
{
db.Tider.Add(arbetstider);
db.SaveChanges();
}
return View(arbetstider);
}
//
// GET: /Tider/Edit/5
public ActionResult Edit(int id = 0)
{
ArbetsTider arbetstider = db.Tider.Find(id);
if (arbetstider == null)
{
return HttpNotFound();
}
return View(arbetstider);
}
//
// POST: /Tider/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ArbetsTider arbetstider)
{
if (ModelState.IsValid)
{
db.Entry(arbetstider).State = EntityState.Modified;
return RedirectToAction("Index");
}
return View(arbetstider);
}
//
// GET: /Tider/Delete/5
public ActionResult Delete(int id = 0)
{
ArbetsTider arbetstider = db.Tider.Find(id);
if (arbetstider == null)
{
return HttpNotFound();
}
return View(arbetstider);
}
//
// POST: /Tider/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
ArbetsTider arbetstider = db.Tider.Find(id);
db.Tider.Remove(arbetstider);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
[HttpPost]
public ActionResult Start(ArbetsTider model)
{
using (var context = new TiderDBContext())
{
context.Tider.FirstOrDefault(x => x.ID == model.ID).Start = model.Start;
context.SaveChanges();
}
return View("Index");
}
[HttpPost]
public ActionResult Stop(ArbetsTider model)
{
using (var context = new TiderDBContext())
{
context.Tider.FirstOrDefault(x => x.ID == model.ID).Slut = model.Slut;
context.SaveChanges();
}
return View("Index");
}
}
}
model
public class ArbetsTider
{
public int ID { get; set; }
public DateTime Start { get; set; }
public DateTime Slut { get; set; }
}
public class TiderDBContext : DbContext
{
public DbSet<ArbetsTider> Tider { get; set; }
}
You need to use Ajax method to submit the one form partially without refreshing the whole page.
Try something like this:
First change like this(remove type='submit'):
#using (Html.BeginForm("Create", "Tider", FormMethod.Post, new { #id= "formStart" } ))
{
// html code
<input id="submittStartDate" name="#Html.NameFor(x => x.Command)" value="Start" class="submitButton" />
});
And
#using (Html.BeginForm("Stop", "Tider", FormMethod.Post, new { #id= "formStop" } ))
{
//html
<input id="stop" name="#Html.NameFor(x => x.Command)" value="Stop" class="submitButton" />
//html
});
Then add a function in javascript file:
$(document).ready(function () {
$("input.submitButton").click(function() {
SubmitForm(this);
});
});
function SubmitForm(input) {
var url = "";
var formData = "";
if(input[0].id == "formStart")
{
url = "../Tider/Create";
data = $('form#formStart').serialize();
}
else if(input[0].id == "formStop") {
url = "../Tider/Stop";
data = $('form#formStop').serialize();
}
$.ajax({
type: "POST",
url: url,
data: data,
success: function (result) {
// Do your stuff here
},
error: function () {
alert("Error in saving");
}
});
}
You need to change the return types of the C# methods Create and Stop to required type(I think you need int here) and retun that. And you will get the data "success" function of the Ajax call.

Saving multiple records on submit click into differnt entities in MVC4. Not getting values from view in Controller

I am trying to save the class attendance for multiple students on click of submit button. I am able to create the blank records in the concern tables and then populate the data in view.
I have the following view model:
public class TeacherAttendanceModel
{
#region Required Properties
public long ScholarAttendanceId { get; set; }
public string Student { get; set; }
public bool Absent { get; set; }
public string AbsentComment { get; set; }
public bool Uniform { get; set; }
public bool Homework { get; set; }
public string HomeworkComment { get; set; }
public String UniformCommentSelected { get; set; }
public IEnumerable<String> UniformComment { get; set; }
#endregion
}
My Controller is as below.
public class TeacherAttendanceController : Controller
{
//
// GET: /TeacherAttendance/
public ActionResult Index()
{
long classId = Success.Business.Roles.Teacher.GetHomeRoomClassID(Convert.ToInt64(Session[GlobalVar.LOGGED_IN_ID]));
var classAttendanceStatus = Success.Business.Entities.ClassAttendance.GetClassAttendanceStatus(classId);
ViewBag.status = classAttendanceStatus;
var attendanceData = TeacherAttendance.CreateClassAttendance(classId);
return View(attendanceData);
}
[HttpPost]
public ActionResult Index(IEnumerable<TeacherAttendanceModel> teacherAttendanceModel)
{
try
{
if (ModelState.IsValid)
{
TeacherAttendance.SaveAttendance(teacherAttendanceModel);
}
}
catch (Exception e)
{
}
return View(teacherAttendanceModel);
}
}
Get Index is working fine. But I am not getting the TeacheAttendanceModel object in Post index. I get null object. I would be thank full to get any help in this regards. How to update the multiple records of attendance on submit click?
I am using the following View:
#foreach (var item in Model) {
<tr >
<td style="border-style:solid; border-color:darkslategray; border-width:thin;">
#Html.DisplayFor(modelItem => item.Student)
</td>
<td style="border-style:solid; border-color:darkslategray; border-width:thin;">
#Html.CheckBoxFor(modelItem => item.Absent, ViewBag.status == 2 ? new {disabled = "disabled"} : null)
#Html.TextBoxFor(modelItem => item.AbsentComment, ViewBag.status == 2 ? new {disabled = "disabled"} : null)
</td>
<td style="border-style:solid; border-color:darkslategray; border-width:thin;">
#Html.CheckBoxFor(modelItem => item.Uniform, ViewBag.status == 2 ? new {disabled = "disabled"} : null)
#Html.DropDownListFor(modelItem => item.UniformCommentSelected, new SelectList(item.UniformComment),item.UniformCommentSelected ?? "---Select---", ViewBag.status == 2? new {disabled = "disabled"} : null)
</td>
<td style="border-style:solid; border-color:darkslategray; border-width:thin;">
#Html.CheckBoxFor(modelItem => item.Homework, ViewBag.status == 2 ? new {disabled = "disabled"} : null)
#Html.TextBoxFor(modelItem => item.HomeworkComment, ViewBag.status == 2? new {disabled = "disabled"} : null)
</td>
</tr>
}
Model:
public class Test
{
public List<string> UniformComment { get; set; }
}
Controller:
public ActionResult Index()
{
var model = new Test
{
UniformComment = new List<string>{ "one", "two", "three" }
};
return View(model);
}
[HttpPost]
public ActionResult Index(Test model)
{
return View(model);
}
View:
#using (Html.BeginForm())
{
for (var i = 0; i < Model.UniformComment.Count; i++)
{
#Html.TextBoxFor(x => Model.UniformComment[i])
}
<input type="submit" value="Save" />
}
Rendered html example:
<input id="UniformComment_0_" name="UniformComment[0]" type="text" value="one" />
<input id="UniformComment_1_" name="UniformComment[1]" type="text" value="two" />
<input id="UniformComment_2_" name="UniformComment[2]" type="text" value="three" />
The idea is iterate with for loop or create EditorTemplate and then you receive indexed items.
Added (Feel the difference):
View:
#using (Html.BeginForm())
{
foreach (var comment in Model.UniformComment)
{
#Html.TextBoxFor(x => comment)
}
<input type="submit" value="Save" />
}
Rendered html:
<input id="comment" name="comment" type="text" value="one" />
<input id="comment" name="comment" type="text" value="two" />
<input id="comment" name="comment" type="text" value="three" />
Use a IList instead of IEnumerable in the view and replace the foreach loop with a for loop.
Step 1:
Use
#model IList<TeacherAttendanceModel>
instead of
#model IEnumerable<TeacherAttendanceModel>
Step 2:
Use
#for (var i = 0; i < Model.Count; i++)
instead of
#foreach (var item in Model)
Refer How to pass IEnumerable list to controller in MVC including checkbox state? for more details.

MVC4 sending model propert id to controller class

How to send id of a model property Name to Controller class in an MVC4 application
public class{
public Name{get;set;}
}
For Accesing name using id of that property
Update:
Here if change Name using jquery at runtime i want to send the changed name id to the controller class
UPDate:
This is my VIew
<script type="text/javascript">
$(function () {
$('.editor input').blur(function () {
$(this).hide();
$(this).closest('p').find('label').html($(this).val()).show();
});
$('.editor label').click(function () {
$(this).hide();
$(this).closest('p').find('input').show();
});
});
#using (Html.BeginForm("Homepage", "Home", FormMethod.Post))
{
<div class="editor">
<p>
#Html.LabelFor(x => x.Name, Model.Name)
#Html.EditorFor(x => x.Name)
<input type="submit" value="OK" />
</p>
<p>
#Html.LabelFor(x => x.Company, Model.Company)
#Html.EditorFor(x => x.Company)
<input type="submit" value="OK" />
</p>
<p>
#Html.LabelFor(x => x.City, Model.City)
#Html.EditorFor(x => x.City)
<input type="submit" value="OK" />
</p>
</div>
<input type="submit" value="OK" />
}
This is my model
public class Details
{
public string Name
{ get; set; }
public string Company
{ get; set; }
public string City
{ get; set; }
}
This is my COntroller methods
public ActionResult Homepage(Details d)
{
d.Name = "Rakesh";
d.Company = "TCS";
d.City = "DElhi";
return View(d);
}
[HttpPost, ActionName("Homepage")]
public ActionResult Indexof(Details d)
{
return View(d);
}
Here i am editing and sending data to the controller but my problem is when i click on Rakesh for example and change the name then i need to click button twice then only the changed data is sent to the controller class
Model:
public class SomeModel {
public string Name { get; set; }
}
Controller:
[HttpPost]
public ActionResult YourAction( SomeModel m )
{
if( ModelState.IsValid )
{
// use model
var name = m.Name;
return RedirectToAction( "Index", "Home" );
}
return View( m );
}
If this isn't what you need, please clarify what's this "id" you're talking about.