How to use multiple edit form using Html Helper - asp.net

I want to make multiple editing page.
But I don't know how to use TextBoxFor(), TextAreaFor(), ValidationMessageFor() in a foreach loop.
#foreach (var note in Model.noteList)
{
using(Html.BeginForm()){
#Html.Hidden("id", note.id);
<div class="userIdArea"><b>#note.userId</b></div>
<div class="noteArea">#note.content</div>
<br />
<div class="editor-label">
#Html.LabelFor(model => model.note.userId)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.note.userId, new { #Value = note.userId })
#Html.ValidationMessageFor(model => model.note.userId)
</div>
<div class="editor-field">
#Html.TextAreaFor(note => note.noteList)
#Html.ValidationMessageFor(model => model.note.content)
</div>
<input type="submit" value="Edit" />
}
}
The code above cannot set the textarea value, and I don't think it's the right way to do that.
EDIT )
I changed code like this,
#foreach (var note in Model.noteList)
{
using(Html.BeginForm()){
#Html.Hidden("note.id", note.id);
<div class="userIdArea"><b>#note.userId</b></div>
<div class="noteArea">#note.content</div>
<br />
<div class="editor-label">
#Html.LabelFor(model => model.note.userId)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => note.userId)
#Html.ValidationMessageFor(model => note.userId)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => note.content)
#Html.ValidationMessageFor(_ => note.content)
</div>
<input type="submit" value="Edit" />
}
}
and I still have problem with using ValidationMessageFor().
I make only one content empty and submit form then it happens like this,
How should I do put ValidationMessage on right place?
[EDIT #2]
Yes, I have create form too in same view,
the View code is like this,
#model MemoBoard.Models.NoteViewModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Note</h2>
<br /><br />
#using(Html.BeginForm()){
<div class="editor-label">
#Html.LabelFor(model => model.note.userId)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.note.userId)
#Html.ValidationMessageFor(model => model.note.userId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.note.content)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.note.content, new { rows = 4})
#Html.ValidationMessageFor(model => model.note.content)
</div>
<input type="submit" value ="Save" />
} #* //End create form *#
<!-- List Area -->
#foreach (var note in Model.noteList)
{
using(Html.BeginForm()){
#Html.Hidden("note.id", note.id);
#Html.EditorForModel()
<div class="userIdArea"><b>#note.userId</b></div>
<div class="noteArea">#note.content</div>
<br />
<div class="editor-label">
#Html.LabelFor(model => model.note.userId)
</div>
<div class="editor-field">
#Html.EditorFor(model => note.userId, new { id = "A"})
#Html.ValidationMessageFor(model => note.userId)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => note.content)
#Html.ValidationMessageFor(model => note.content)
</div>
<input type="submit" value="Edit" />
}
}
And,
Model,
public class Note
{
[Key]
public int id { get; set; }
[Required(ErrorMessage="Content is required")]
[DisplayName("Note")]
public string content { get; set; }
public DateTime date { get; set; }
[Required(ErrorMessage = "User ID is required")]
[DisplayName("User ID")]
public string userId {get; set;}
public Boolean isPrivate { get; set; }
public virtual ICollection<AttachedFile> AttachedFiles { get; set; }
}
View Model,
public class NoteViewModel
{
public IEnumerable<Note> noteList { get; set; }
public Note note { get; set; }
}
Controller,
public ActionResult Index()
{
var notes = unitOfWork.NoteRepository.GetNotes();
return View(new NoteViewModel(){noteList=notes.ToList(), note = new Note()});
}
[HttpPost]
public ActionResult Index(Note note)
{
try
{
if (ModelState.IsValid)
{
unitOfWork.NoteRepository.InsertNote(note);
unitOfWork.Save();
return RedirectToAction("Index");
}
}catch(DataException){
ModelState.AddModelError("", "Unable to save changes. Try again please");
}
var notes = unitOfWork.NoteRepository.GetNotes();
return View(new NoteViewModel() { noteList = notes.ToList(), note = new Note() });
}

You can actually do this if you want (don't need to use the model):
#Html.LabelFor(model => note.userId)
#Html.ValidationMessageFor(model => note.userId)
#Html.ValidationMessageFor(model => note.content)
Sometimes I change the lambda variable name to _, to show that the model is not important (but it's optional if you want):
#Html.LabelFor(_ => note.userId)
#Html.ValidationMessageFor(_ => note.userId)
#Html.ValidationMessageFor(_ => note.content)

Since you are iterating over the "note" var in the for each statement your html helpers would reference that "note" var and not the model. The solution is below:
#foreach (var note in Model.noteList)
{
using(Html.BeginForm()){
#Html.Hidden("id", note.id);
<div class="userIdArea"><b>#note.userId</b></div>
<div class="noteArea">#note.content</div>
<br />
<div class="editor-label">
#Html.LabelFor(note => note.userId)
</div>
<div class="editor-field">
#Html.TextBoxFor(note => note.userId, new { #Value = note.userId })
#Html.ValidationMessageFor(note => note.userId)
</div>
<div class="editor-field">
#Html.TextAreaFor(note => note.noteList)
#Html.ValidationMessageFor(note => note.content)
</div>
<input type="submit" value="Edit" />
}
}

Related

insert dropdown in asp.net mvc 4 view, and the data will be from another table

I am beginner in asp.net so may be I have stupid question, but I need some help.
I have a model and controller MAIN, with read/write rules.
I have a create action in MainController, and it works, but I need that one of the field be dropdown and it has options from another table of Department.
I have searched answer but I have not get full answer.
So if you can, help me.
If need I will write codes.
Thanks a lot.
MainController
public ActionResult Create()
{
return View();
}
//
// POST: /Main/Create
[HttpPost]
public ActionResult Create(Main main)
{
if (ModelState.IsValid)
{
db.Main.Add(main);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(main);
}
Main.cs (Model)
namespace PhoneBook.Models
{
public class Main
{
public int Id { get; set; }
public string F_L_Name { get; set; }
public string Regioni { get; set; }
public string Raioni { get; set; }
public string Department { get; set; }
public string Division { get; set; }
public string Position { get; set; }
public string Mobile { get; set; }
public string I_Phone { get; set; }
public string Email { get; set; }
public int Deleted { get; set; }
public string Comment { get; set; }
public string All_In_One { get; set; }
public DbSet<Department> DepartmentFI { get; set; }
}
}
Create.cshtml (View)
#model PhoneBook.Models.Main
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Main</legend>
<div class="editor-label">
#Html.LabelFor(model => model.F_L_Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.F_L_Name)
#Html.ValidationMessageFor(model => model.F_L_Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Regioni)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Regioni)
#Html.ValidationMessageFor(model => model.Regioni)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Raioni)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Raioni)
#Html.ValidationMessageFor(model => model.Raioni)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Department)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Department)
#Html.ValidationMessageFor(model => model.Department)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Division)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Division)
#Html.ValidationMessageFor(model => model.Division)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Position)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Position)
#Html.ValidationMessageFor(model => model.Position)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Mobile)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Mobile)
#Html.ValidationMessageFor(model => model.Mobile)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.I_Phone)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.I_Phone)
#Html.ValidationMessageFor(model => model.I_Phone)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
use like this to display department as drop down list
#Html.DropDownListFor(model => model.Department, model=>model.Departments)
Note: you need to populate model.Departments with the values from database table in controller/service

Persist values between multiple Posts

Hello I am not able to retain values on multiple posts and “Post1” action function in my in my controller always has MyViewModelObj.Field2 as null .I expect it to retain the old value in the 2nd post
How to I make the MyViewModel model class object persist the values ?
Mymodels.cs ( Model)
namespace RetainTest.Models
{
public class MyViewModel
{
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }
public string Field4 { get; set; }
}
}
RetainView.cshtml ( View )
#model RetainTest.Models.MyViewModel
#{
ViewBag.Title = "RetainView";
}
<h2>RetainView</h2>
#using (Html.BeginForm("Post1", "Retain", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.Field1);
#Html.HiddenFor(model => model.Field2);
#Html.HiddenFor(model => model.Field3);
#Html.HiddenFor(model => model.Field4);
<div class="form-horizontal">
<h4>MyViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Field1, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Field1, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Field1, "", new { #class = "text-danger" })
</div>
</div>
#{
if ( Model.Field2 == "Val2")
{
<div class="form-group">
#Html.LabelFor(model => model.Field2, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Field2, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Field2, "", new { #class = "text-danger" })
</div>
</div>
}
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
RetainController.cs ( Controller )
namespace RetainTest.Models
{
public class RetainController : Controller
{
// GET: Retain
public ActionResult Index()
{
MyViewModel MyViewModelObj = new MyViewModel();
MyViewModelObj.Field1 = "Val1";
return View("RetainView", MyViewModelObj);
}
[HttpPost]
public ActionResult Post1(MyViewModel MyViewModelObj)
{
if (string.IsNullOrEmpty(MyViewModelObj.Field2 ))
{
MyViewModelObj.Field2 = "Val2";
}
return View("RetainView", MyViewModelObj);
}
}
}
Try this:
namespace RetainTest.Models
{
public class MyViewModel
{
[Required(ErrorMessage = "Field1 is required")]
public string Field1 { get; set; }
[Required(ErrorMessage = "Field2 is required")]
public string Field2 { get; set; }
public string Field3 { get; set; }
public string Field4 { get; set; }
}
}
#model RetainTest.Models.MyViewModel
#{
ViewBag.Title = "RetainView";
}
<h2>RetainView</h2>
#using (Html.BeginForm("Post1", "Retain", FormMethod.Post, new { id = "form", enctype = "multipart/form-data"}))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.Field1);
#Html.HiddenFor(model => model.Field2);
#Html.HiddenFor(model => model.Field3);
#Html.HiddenFor(model => model.Field4);
<div class="form-horizontal">
<h4>MyViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<Label for="Field1" class="control-label col-md-2">Field1 </label>
<div class="col-md-10">
#if(Model.Field1 == "Val1")
{
<input type="text" name="Field1" id="Field1" class="form-control" value="#Model.Field1">
}
else
{
<input type="text" name="Field1" id="Field1" class="form-control">
}
<span class="field-validation-valid text-danger"
data-valmsg-for="Field1"
data-valmsg-replace="true">
</span>
</div>
</div>
<div class="form-group">
<Label for="Field2" class="control-label col-md-2">Field2 </label>
<div class="col-md-10">
#if(Model.Field2 == "Val2")
{
<input type="text" name="Field2" id="Field2" class="form-control" value="#Model.Field2">
}
else
{
<input type="text" name="Field2" id="Field2" class="form-control">
}
<span class="field-validation-valid text-danger"
data-valmsg-for="Field2"
data-valmsg-replace="true">
</span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
namespace RetainTest.Models
{
public class RetainController : Controller
{
private MyViewModel MyViewModelObj = new MyViewModel();
// GET
public ActionResult Index()
{
if (Session["MyObj"] != null)
MyViewModelObj = (MyViewModel)Session["MyObj"];
else
MyViewModelObj.Field1 = "Val1";
return View("RetainView", this);
}
[AcceptVerbs(HttpVerbs.Post)]
[ValidateInput(false)]
public ActionResult Post1(FormCollection form)
{
MyViewModelObj.Field1 = form.Get("Field1");
MyViewModelObj.Field2 = form.Get("Field2");
if (string.IsNullOrEmpty(MyViewModelObj.Field2))
MyViewModelObj.Field2 = "Val2";
// here you need to store the data somewhere!
// session, database.
// just an example:
Session.Add("MyObj", MyViewModelObj);
return View("RetainView", this);
}
}
}
I used the session to retain the values of the object but there are a few other ways to store the data. The above code will post the user input to the controller and retain he values in the session.
Got answer from Stephen Muecke
"Your view has a hidden input for each property of your model. The DefaultModelBinder reads the first name/value pair for each property in the request and ignores all others. Since the hidden inputs are first, the values of your EditorFor() methods are ignored. You only ever bind the initial vales of your model, not the edited values (making your form rather pointless). Remove the hidden inputs!"

DROP DOWN LIST SENDING ENTITY UNIQUE ID INSTEAD OF SELECTED ITEM

I'm populating a drop down list in my view with items sent from a view.bag populated from my db. In the view everything is fine, but when it saves to the database its passing along the unique ID for that entity instead of the selected value.. Can someone please help..
Thank You...
*note my static populated dropdown works... Its the dropdown from the database thats causing the proplem.
Heres my code:
Controller:
public ActionResult Create()
{
ViewBag.TeacherID = new SelectList(db.Teachers, "TeacherID", "LastName");
ViewBag.SemesterID = new SelectList(db.Semesters, "SemesterID",
SemesterName");
ViewBag.CourseID = new SelectList(db.Courses, "Section", "CourseSection");
ViewBag.RoomID = new SelectList(db.Rooms, "RoomID", "FacilityIdentifier");
var meetlist = new SelectList(new[]
{
new { ID="M", Name="M"},
new { ID="T", Name="T"},
new { ID="W", Name="W"},
new { ID="TH", Name="TH"},
new { ID="T", Name="T"},
new { ID="F", Name="F"},
new { ID="MW", Name="MW"},
new { ID="TTH", Name="TTH"},
},
"ID", "Name", 1);
ViewData["meetlist"] = meetlist
return View();
}
View:
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Assignment</legend>
<div class="editor-label">
COURSE
</div>
<div class="editor-field">
#Html.DropDownList("CourseSection", String.Empty)
#Html.ValidationMessageFor(model => model.Course.Section)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.TeacherID)
</div>
<div class="editor-field">
#Html.DropDownList("TeacherID", String.Empty)
#Html.ValidationMessageFor(model => model.TeacherID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.RoomID)
</div>
<div class="editor-field">
#Html.DropDownList("RoomID", String.Empty)
#Html.ValidationMessageFor(model => model.RoomID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.SemesterID)
</div>
<div class="editor-field">
#Html.DropDownList("RoomID", String.Empty)
#Html.ValidationMessageFor(model => model.RoomID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EnrollCap)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EnrollCap)
#Html.ValidationMessageFor(model => model.EnrollCap)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EnrollTotal)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EnrollTotal)
#Html.ValidationMessageFor(model => model.EnrollTotal)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.StartTime)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.StartTime)
#Html.ValidationMessageFor(model => model.StartTime)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EndTime)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EndTime)
#Html.ValidationMessageFor(model => model.EndTime)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Meeting)
</div>
<div>
#Html.DropDownListFor(u => u.Meeting, ViewData["meetlist"] as SelectList,
new { style = "width: 200px"})
#Html.ValidationMessageFor(u=>u.Meeting)
</div>
<p>
<input type="submit" value="Create" />
</p>
and model:
public class Assignment
{
public int AssignmentID { get; set; }
public int CourseID { get; set; }
public int TeacherID { get; set; }
public int RoomID { get; set; }
public int SemesterID { get; set; }
public int EnrollCap { get; set; }
public int EnrollTotal { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Meeting { get; set; }
public virtual Course Course { get; set; }
public virtual ICollection<Room> Room { get; set; }
public virtual ICollection<Teacher> Teacher { get; set; }
public virtual ICollection<Semester> Semester { get; set; }
}
thank you in advance.
Supply appropriate SelectList (through ViewBags in your case) as datasource to dropdowns like:
#Html.DropDownList("CourseSection", (SelectList)ViewBag.CourseID)
#Html.DropDownList("TeacherID", (SelectList)ViewBag.TeacherID )
and so on...

ViewModel assigned an object, how can I pass that back into the Post?

So I have two methods:
public ActionResult Create(Guid id)
{
Assignment viewModel = new Assignment();
viewModel.Classroom = classroomRepository.GetByID(id);
return View(viewModel);
}
[HttpPost]
public ActionResult Create(Assignment assignment)
{
if (ModelState.IsValid)
{
assignmentRepository.Insert(assignment);
assignmentRepository.Save();
return RedirectToAction("Index");
}
return View(assignment);
}
As you can see, when I load up my Create page, I'm loading a Classroom into the viewModel. This works and displays the correct Classroom on the View.
My problem occurs when I POST to the Create method, my assignment object I pass in now doesn't include (it's NULL) Classroom that I passed in on GET.
EDIT ~ To Show View:
#model My_School_Book.Models.Assignment
#{
ViewBag.Title = "Create";
}
<div class="span9">
<div class="row-fluid">
<h1>Creating New Assignment:</h1>
<hr />
#using (Html.BeginForm("Create", "Assignment", FormMethod.Post, new { #class = "form-horizontal" }))
{
#Html.ValidationSummary(true)
<div class="control-group">
#Html.LabelFor(model => model.Classroom.Name, "Classroom", new { #class = "control-label" })
<div class="controls">
<span style="font-size: 26px;">#Html.DisplayTextFor(model => model.Classroom.Name)</span>
</div>
</div>
<div class="control-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label" })
<div class="controls">
#Html.TextBoxFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="control-group">
#Html.LabelFor(model => model.Description, new { #class = "control-label" })
<div class="controls">
#Html.TextAreaFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
</div>
<div class="control-group">
#Html.LabelFor(model => model.AssignedDate, new { #class = "control-label" })
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-calendar"></i></span>#Html.TextBoxFor(model => model.AssignedDate)
</div>
#Html.ValidationMessageFor(model => model.AssignedDate)
</div>
</div>
<div class="control-group">
#Html.LabelFor(model => model.DueDate, new { #class = "control-label" })
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-calendar"></i></span>#Html.TextBoxFor(model => model.DueDate)
</div>
#Html.ValidationMessageFor(model => model.DueDate)
</div>
</div>
<div class="control-group">
#Html.LabelFor(model => model.Weight, new { #class = "control-label" })
<div class="controls">
#Html.TextBoxFor(model => model.Weight, new { #class = "span2" })
#Html.ValidationMessageFor(model => model.Weight)
</div>
</div>
<div class="control-group">
#Html.LabelFor(model => model.Total, new { #class = "control-label" })
<div class="controls">
#Html.TextBoxFor(model => model.Total, new { #class = "span2" })
#Html.ValidationMessageFor(model => model.Total)
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary"><i class="icon-plus-6"></i> Create</button>
<i class="icon-back"></i> Cancel
</div>
}
</div>
</div>
#section Scripts
{
<script type="text/javascript">
$(function () {
$("#AssignedDate").datepicker({
showOtherMonths: true,
selectOtherMonths: true,
dateFormat: "DD MM d, yy",
minDate: -14,
onSelect: function (selectedDate) {
$("#DueDate").datepicker("option", "minDate", selectedDate);
}
});
$("#DueDate").datepicker({
dateFormat: "DD MM d, yy",
minDate: 0,
onSelect: function (selectedDate) {
$("#AssignedDate").datepicker("option", "maxDate", selectedDate);
}
});
});
</script>
}
You are only including Classroom.Name, thus on the form post nothing is there for the model binder to populate your model with.
Do you really need the classroom populated back though? What are you trying to accomplish?
If you need the ID simply write it out as:
#Html.HiddenFor(o=>o.Classroom.ClassroomId)
(or whatever the id is) and load it back up on the server side.
If you really need it there - you can write it out as inputs via
#Html.EditorFor(o=>o.Classroom)
That then allows the end user to modify it which I dont think you want, thus I'd use the ID (guid).
If you want that Classroom survive post then you need to add it to form in hiddenfield:
Just add this into form:
#Html.HiddenFor(m=m.Classroom.ClassroomId)
#Html.HiddenFor(m=m.Classroom.ClassroomName)
I ended up using a View Model:
public class AssignmentCreateData
{
public Guid ClassroomID { get; set; }
public String ClassroomName { get; set; }
public Assignment Assignment { get; set; }
}
and my controller looked like this:
public ActionResult Create(Guid id)
{
AssignmentCreateData viewModel = new AssignmentCreateData();
Classroom classroom = classroomRepository.GetByID(id);
viewModel.ClassroomID = classroom.ClassroomID;
viewModel.ClassroomName = classroom.Name;
viewModel.Assignment = null;
return View(viewModel);
}
[HttpPost]
public ActionResult Create(AssignmentCreateData viewModel)
{
if (ModelState.IsValid)
{
viewModel.Assignment.ClassroomID = viewModel.ClassroomID;
assignmentRepository.Insert(viewModel.Assignment);
assignmentRepository.Save();
return RedirectToAction("Index");
}
return View(viewModel);
}
Then my View includes:
#Html.HiddenFor(model => model.ClassroomID)

CKEditor MVC 3 implementation

Learning mvc and I am trying to implement a page with 3 fields Name-Surname-Description
So in my learning example I am loading employees and I should be able to create and edit them.
The description should use CKEditor .
I can load employees
I can save them
However I cannot seem to be able to save the description,such as whatever the user types in the description field. I have seen few examples on the net but none with a solution to download,as I cannot seem to put together. I have found this guy with a cool html helper but cannot seem to be able to put an example together
http://www.andrewbarber.com/post/CKEditor-Html-Helpers-ASPNET-MVC-Razor-Views.aspx
The problems are :
How do you get the value that is typed inside the ckEditor.
In my viewModel the description is null all the time
the ckEditor slow down the creation of the page quite a lot.How can I make it faster? I dont need all the options.
Is there an example using mvc3 out there that I can use as a template.
I have done all the plumbing as follows:
Create.chtml
#model MvcApplicationCKEditorIntegration.Models.EmployeeViewModel
#{
ViewBag.Title = "Create";
}
<h2>
Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>EmployeeViewModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhotoPath)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhotoPath)
#Html.ValidationMessageFor(model => model.PhotoPath)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
<textarea class="ckeditor" id="ckeditor" rows="10"></textarea>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script type="text/javascript" src="../../ckeditor/ckeditor.js"></script>
EmployeeController
public class EmployeeController : Controller
{
public ActionResult Index()
{
var employeeRepository=new EmployeeRepository();
var employees = employeeRepository.GetAll();
var employeeList = employees.Select(employee => new EmployeeViewModel
{
EmployeeId = employee.EmployeeId,
FirstName = employee.FirstName,
LastName = employee.LastName,
PhotoPath = employee.PhotoPath,
Email = employee.Email,
Description = employee.Description
}).ToList();
return View(employeeList);
}
public ActionResult Create()
{
return View(new EmployeeViewModel());
}
[HttpPost]
public ActionResult Create(EmployeeViewModel vm)
{
if(ModelState.IsValid)
{
var employeeRepository=new EmployeeRepository();
var emp=new Employee
{
FirstName = vm.FirstName,
LastName = vm.LastName,
Description = vm.Description,
Email = vm.Email,
PhotoPath = vm.PhotoPath
};
employeeRepository.Insert(emp);
return RedirectToAction("Index");
}
return View(vm);
}
}
}
Thanks for any suggestions!!!
EDITED EXAMPLE USING CKEditor helper
#using MvcApplicationCKEditorIntegration.Helpers
#model MvcApplicationCKEditorIntegration.Models.EmployeeViewModel
#{
ViewBag.Title = "Create";
}
<h2>
Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#Html.CKEditorHeaderScripts()
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>EmployeeViewModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PhotoPath)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.PhotoPath)
#Html.ValidationMessageFor(model => model.PhotoPath)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
#Html.CKEditorFor(model=>model.Description)
<p>
<input type="submit" value="Create" onclick="#Html.CKEditorSubmitButtonUpdateFunction()" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script type="text/javascript" src="../../ckeditor/ckeditor.js"></script>
You aren't actually using the CKEditor helper at all like is described on that blog page (which is my own blog)
The purpose of that helper is that once you have included the code correctly into your project, you can simply do this:
#Html.CKEditorFor(model=>model.Description)
However, you seem to simply be creating a plain-old text area and working with it 'manually' after that. There isn't anything to bind it to your property, as would exist if you had used the helper described in that post.
Also note that you aren't using the code that Updates the text area behind the scenes; so if your model has Required set on the Description field, you will get a client-side validation error the first time you submit an otherwise properly-configured CKEditorFor() This isn't unique to my helper; any bound property that is 'required' needs the bit of Javascript that is mentioned in that blog post, too. I do it as an onclick off the submit button, but you can run that same code anywhere. You just need to include it in the page, which you haven't done.
You might want to try setting the name attribute of the textarea to "Description"
so:
<div class="editor-field">
<textarea class="ckeditor" id="ckeditor" rows="10" name="Description"></textarea>
</div>
if that doesn't work then you might have to use javascript to get the value of what's in the editor and set it in a hidden field before the post.

Resources