I have a asp.net MVC View Page which is Master/Detail style.
After reading from this , I realize that I need to serialize jqgrid data before I send to Controller Layer.
[HttpPost]
public ActionResult Detail(Seminar Seminar, List<Seminar_Detail> Seminar_Details)
{
}
So my question is,
1. How could i send data to controller, by using 2 ViewModel classes.
SeminarMaster for Form Input Fields and SeminarDetail for Jqgrid entire rows.
2.If you say, I have only one way which is serializing to jqgrid, then Do i need to serialize Form input fields also?
3.If I have to use serialize way, Do I have chance to use ViewModel classess to parse data to Controller Layer ?
Updated
Or Detail Page which user can make Insert/update or delete process.
@model MvcMobile.ViewModel.SeminarListDetailViewModel
@{
ViewBag.Title = "Detail";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Detail</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>Seminar</legend>
<table>
<tr>
<td>
<div class="editor-label">
@Html.LabelFor(model => model.Seminar.Seminar_Code)
</div>
</td>
<td>
<div class="editor-field">
@Html.EditorFor(model => model.Seminar.Seminar_Code)
@Html.ValidationMessageFor(model => model.Seminar.Seminar_Code)
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-label">
@Html.LabelFor(model => model.Seminar.Title)
</div>
</td>
<td>
<div class="editor-field">
@Html.EditorFor(model => model.Seminar.Title)
@Html.ValidationMessageFor(model => model.Seminar.Title)
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-label">
@Html.LabelFor(model => model.Seminar.Description)
</div>
</td>
<td>
<div class="editor-field">
@Html.EditorFor(model => model.Seminar.Description)
@Html.ValidationMessageFor(model => model.Seminar.Description)
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-label">
@Html.LabelFor(model => model.Seminar.Room)
</div>
</td>
<td>
<div class="editor-field">
@Html.EditorFor(model => model.Seminar.Room)
@Html.ValidationMessageFor(model => model.Seminar.Room)
</div>
</td>
</tr>
</table>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<table id="list" class="scroll" cellpadding="0" cellspacing="0"></table>
<div id="pager" class="scroll" style="text-align:center;"></div>
<script type="text/javascript">
jQuery(document).ready(function () {
var AllSpeakers = (function () {
var list = null;
$.ajax({
'async': false,
'global': false,
'url': 'GetAllSpeakers',
'dataType': 'json',
'success': function (data) {
list = data;
}
});
return list;
})();
var AllTags = (function () {
var list = null;
$.ajax({
'async': false,
'global': false,
'url': 'GetAllTags',
'dataType': 'json',
'success': function (data) {
list = data;
}
});
return list;
})();
var lastSel = 0;
jQuery("#list").jqGrid({
url: '/Seminar/DetailGridData/',
editurl: "/Seminar/MyEdit/",
datatype: 'json',
mtype: 'GET',
colNames: ['Seminar_Code', 'Speaker', 'Tag', 'DateAndTime'],
colModel: [
{ name: 'Seminar_Code', index: 'Seminar_Code', width: 40, align: 'left', editable: true, edittype: "text", editoptions: { size: "35", maxlength: "50"} },
{ name: 'SpeakerID', index: 'SpeakerID', align: 'left', editable: true, edittype: "select", formatter: 'select', editoptions: { value: AllSpeakers,
dataEvents: [
{ type: 'change',
fn: function (e) {
//alert("Speaker change"); // For Cascading Dropdownlist Or Dependent Combo
}
}
]
}, editrules: { required: true}
},
{ name: 'TagID', index: 'TagID', align: 'left', editable: true, edittype: 'select', formatter: 'select', editoptions: { value: AllTags }, editrules: { required: true} },
{ name: 'DateAndTime', index: 'DateAndTime', width: 40, align: 'left', editable: true, edittype: "text", editoptions: { size: "35", maxlength: "50"} }
],
pager: jQuery('#pager'),
rowNum: 10,
rowList: [5, 10, 20, 50],
sortname: 'SpeakerName',
sortorder: "desc",
viewrecords: true,
autowidth: true,
autoheight: true,
imgpath: '/scripts/themes/black-tie/images',
caption: 'My first grid'
})
$("#list").jqGrid('navGrid', '#pager', { edit: false, add: false, del: false, refresh: false, search: false });
$("#list").jqGrid('inlineNav', '#pager', {
addtext: "Add",
edittext: "Edit",
savetext: "Save",
canceltext: "Cancel",
addParams: {
addRowParams: {
// the parameters of editRow used to edit new row
keys: true,
oneditfunc: function (rowid) {
alert("new row with rowid=" + rowid + " are added.");
}
}
},
editParams: {
// the parameters of editRow
key: true,
oneditfunc: function (rowid) {
alert("row with rowid=" + rowid + " is editing.");
}
},
cancelParams: {
key: true,
oneditfunc: function (rowid) {
//alert("row with rowid=" + rowid + " cancel.");
}
}
});
});
</script>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Controller Layer Code
public class SeminarController : Controller
{
ISeminarListDetailRepository seminarRepository;
//
// Dependency Injection enabled constructors
public SeminarController()
: this(new SeminarListDetailRepository()) {
}
public SeminarController(ISeminarListDetailRepository repository)
{
seminarRepository = repository;
}
/// <summary>
/// Just for Listing page.
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
return View();
}
/// <summary>
/// Master Detail CRUD form according to previous form's choosen code.
/// </summary>
/// <param name="Seminar_Code"></param>
/// <returns></returns>
public ActionResult DetailByCode(string Seminar_Code)
{
return View();
}
/// <summary>
/// Master Detail CRUD form.
/// </summary>
/// <returns></returns>
public ActionResult Detail()
{
var SeminarListDetailViewModel = new SeminarListDetailViewModel();
return View(SeminarListDetailViewModel);
}
/// <summary>
/// It is this method what I really focus when it comes to save all rows of jqgrid at once.
/// </summary>
/// <param name="Seminar"></param>
/// <param name="Seminar_Details"></param>
/// <returns></returns>
[HttpPost]
public ActionResult Detail(Seminar Seminar, List<Seminar_Detail> Seminar_Details)
{
return View();
}
/// <summary>
/// Just for test purpose only.
/// I will not use this method when I know how to save JQGrid's All Rows at once.
/// </summary>
/// <param name="Seminar_Detail"></param>
/// <returns></returns>
public ActionResult MyEdit(Seminar_Detail Seminar_Detail)
{
//var seminar_Code = Seminar_Detail.Seminar_Code;
var jsonData = new
{
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
public ActionResult GetAllSpeakers()
{
string AllSpeakers = " : ;";
var Speakers = seminarRepository.GetAllSpeakerList().Seminar_Item_Speaker;
for (int i = 0; i < Speakers.Count; i++)
{
if (i == Speakers.Count - 1)
{
///For the last row
AllSpeakers += Speakers[i].SpeakerID + ":" + Speakers[i].SpeakerName;
}
else
{
AllSpeakers += Speakers[i].SpeakerID + ":" + Speakers[i].SpeakerName + ";";
}
}
return Json(AllSpeakers, JsonRequestBehavior.AllowGet);
}
public JsonResult GetAllTags()
{
string AllTags = " : ;";
var Tags = seminarRepository.GetAllTagList().Seminar_Item_Tag;
for (int i = 0; i < Tags.Count; i++)
{
if (i == Tags.Count - 1)
{
///For the last row
AllTags += Tags[i].TagID + ":" + Tags[i].TagName;
}
else
{
AllTags += Tags[i].TagID + ":" + Tags[i].TagName + ";";
}
}
return Json(AllTags, JsonRequestBehavior.AllowGet);
}
public ActionResult DetailGridData(string sidx, string sord, int page, int rows)
{
int currentPage = Convert.ToInt32(page) - 1;
int totalRecords = 0;
var SeminarList = seminarRepository.GetSeminarDetail("CMP04").Seminar_Detail; //OrderBy(x => x.Seminar_Code).Skip(page * rows).Take(rows).ToList();
var totalPages = (int)Math.Ceiling(totalRecords / (float)rows);
var jsonData = new
{
total = totalPages,
page,
records = totalRecords,
rows = (
from s in SeminarList
select new
{
id = s.Seminar_Code + "__" + s.SpeakerID + "__" + s.TagID,
cell = new object[]
{
s.Seminar_Code,
s.SpeakerID,
s.TagID,
s.DateAndTime
}
}).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
public ActionResult ListingGridData(string sidx, string sord, int page, int rows)
{
int currentPage = Convert.ToInt32(page) - 1;
int totalRecords = 0;
var SeminarList = seminarRepository.AllSeminarList().Seminar_Masters; //OrderBy(x => x.Seminar_Code).Skip(page * rows).Take(rows).ToList();
var totalPages = (int)Math.Ceiling(totalRecords / (float)rows);
var jsonData = new
{
total = totalPages,
page,
records = totalRecords,
rows = (
from s in SeminarList
select new
{
id = s.Seminar_Code,
cell = new object[]
{
s.Seminar_Code,
s.Title,
s.Description,
s.Room
}
}).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
}
Updated 2
Please let me make my question more clear.
I have two tables to insert data at once.
1.SeminarMaster(Seminar_Code, Title, Description, Room)
[At Razor View] - Form Input Fields
2.SeminarDetail(Seminar_Code, SpeakerID, TagID, DateAndTime)
[At Razor View] - JQGrid Rows and Columns
These two tables are in one-to-many relationship.
Update 3
I am really sorry for making my question unclear again and again.
Now please read my update again.I tried my best to make you clear understand my question.
Index.cshtml Or First time display form which user can select any row and go to detail page to make update.But Actually, below razor is not complete yet. Because I need to add Edit buttons at every rows of jqgrid. That Edit button will redirect to another page that I called Detail.cshtml by parsing selected Code. I will update it later. It is not my main problem.
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Seminar List</h2>
<table id="list" class="scroll" cellpadding="0" cellspacing="0"></table>
<div id="pager" class="scroll" style="text-align:center;"></div>
@Html.ActionLink("Click here", "Detail") to add new data.
<script type="text/javascript">
jQuery(document).ready(function () {
jQuery("#list").jqGrid({
url: '/Seminar/ListingGridData/',
editurl: "/Seminar/MyEdit/",
datatype: 'json',
mtype: 'GET',
colNames: ['Seminar_Code', 'Title', 'Description', 'Room'],
colModel: [
{ name: 'Seminar_Code', index: 'Seminar_Code', width: 40, align: 'left', editable: false },
{ name: 'Title', index: 'Title', width: 40, align: 'left', editable: false },
{ name: 'Description', index: 'Description', width: 40, align: 'left', editable: false },
{ name: 'Room', index: 'Room', width: 40, align: 'left', editable: false }
],
pager: jQuery('#pager'),
rowNum: 10,
rowList: [5, 10, 20, 50],
sortname: 'Title',
sortorder: "asc",
viewrecords: true,
autowidth: true,
autoheight: true,
caption: 'Seminar List - Grid'
})
});
</script>
Every suggestion will be appreciated.
multiselect:trueuntil now. But may be later I will need it. – Frank Myat Thu Mar 11 '12 at 07:47