0

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

JqGrid Code or View Layer Implementation

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.

Community
  • 1
  • 1
Frank Myat Thu
  • 4,341
  • 9
  • 65
  • 112
  • Some more details about your jqGrid code would clear some questions. For example which columns in grids you have editable? Do you use `multiselect: true`? I don't full understand your requirements. Why you need to send from jqGrid to controller the data which the server already has? What one typically need to send is only the `id` of master grid, the `id` of detailed grid and the values of all editable fields in the detailed grid. The full information from the View models (`Seminar` and `SeminarDetail`) you can get by ids. Do you know how to send `id` of the maser of submitting in detail grid? – Oleg Mar 10 '12 at 10:55
  • @Oleg I am sorry that my question is not so clear. So I modified it. Please see my question again. Thank – Frank Myat Thu Mar 11 '12 at 07:44
  • @Oleg , I assume that you will know which columns in grids are editable by seeing my updated question. I have not used multiselect:true until now. But may be later I will need it. – Frank Myat Thu Mar 11 '12 at 07:47
  • @Oleg, You ask me that why I need to send from jqGrid to controller the data which the server already has. Because ,according to my business requirment , all of my new + updated data (which is updated only at client-site) have to save only when user click submit button. It means that no data will go to sever if user doesn't click submit button which is outside of jqgrid. – Frank Myat Thu Mar 11 '12 at 07:55
  • @Oleg, To be honested, I am new to JQGrid and asp.net MVC. So I don't know the solution for your question. Do you know how to send id of the maser of submitting in detail grid? – Frank Myat Thu Mar 11 '12 at 07:57
  • @Oleg, Let me get more suggestion please. – Frank Myat Thu Mar 11 '12 at 08:33
  • I looked through your code and still have some questions. In your code there are no master grid which will be filled by calling of `ListingGridData`. Instead of that you included the form with the same data. Do you want to have some kind of filtering? It seems to me that the implementation will be much easier if you would use [searching toolbar](http://www.trirand.com/jqgridwiki/doku.php?id=wiki:toolbar_searching) on the master grid and will have both master and grid in *one view*. Additionally you can use `dataUrl` with `buildSelect` instead of `AllTags` and `AllSpeakers`. – Oleg Mar 11 '12 at 10:27
  • Look UPDATED part of [the answer](http://stackoverflow.com/a/4102155/315935) about the usage of `dataUrl` with `buildSelect`. Do you use Entity Framework or LINQ to SQL? If you have `id` and need to have full model you can use `.Single(x => x.Seminar_Code == id)` to get it. [One more answer](http://stackoverflow.com/a/7392816/315935) can be also helpful for you. It shows how to implement Autocomplete. In the way you can make more easy to work with searching by Specker, seminar Title and so on. – Oleg Mar 11 '12 at 10:36
  • @Oleg, Thank again for your help. But I am sure that my question could not make you clear. Sorry about that. – Frank Myat Thu Mar 11 '12 at 14:48
  • @Oleg, According to your question "In your code there are no master grid which will be filled by calling of ListingGridData. Instead of that you included the form with the same data. Do you want to have some kind of filtering?", I assume that I need to make clear more. – Frank Myat Thu Mar 11 '12 at 14:51
  • @Oleg, Actually, I am not making filtering form design. I assume why you think like that is you found Seminar_Code field not only at Form Input Fields but also at JQGrid Columns. Why I make like that is this key is relation key between two tables. – Frank Myat Thu Mar 11 '12 at 14:55
  • @Oleg , please read my jqgrid code again, please. You will found that I don't make filtering form style. It is really CRUD form design. Thank for your help. – Frank Myat Thu Mar 11 '12 at 14:58
  • @Oleg, I really appreciate your suggestion about dataUrl with buildSelect. It is really help me. – Frank Myat Thu Mar 11 '12 at 15:02
  • Sorry, but I don't understand how the form can be the master grid. Typically in Master/Detaild scenario you have simple markup with two empty `` elements which will be converted in grid by JavaScript code. In the `onSelectRow` callback of the master grid you call `$("#details")trigger("reloadGrid")`. The `postData` option of detailed grid can be like `postData: {masterId: function () {return $("#master").jqGrid("getGridParam", "selrow");}}`. It is simplified schema only.
    – Oleg Mar 11 '12 at 16:37
  • Yes, you are right @Oleg. For Master/Detail scenario we need to have 2 grids one for master, and other for detail , I completely accept your suggestion.Likewise, I have 2 webpages. The first one is Master Grid Listing form which user can select any row he like and double click and come to my current page. I assume that what make you confuse is I did not post my first view file yet. Please see my update again. I will post my first View Page which use JGgrid as for Listing purpose which user can select any row and go to detail page. – Frank Myat Thu Mar 12 '12 at 03:39

0 Answers0