1

Edited with working code as per Mark's answer below.

I'm really starting to loath MVC. I have been trying all day to get a simple grid to work, but I'm having more luck banging a hole in my desk with my head.

I'm trying to implement a search page that displays the results in a grid. There are 3 drop-down lists that the user can use to select search criteria. They must select at least one. After they have searched, the user will be able to select which records they want to export. So I will need to include checkboxes in the resulting grid. That's a future headache.

Using JqGrid and Search form - ASP.NET MVC as a reference I have been able to get the grid to appear on the page (a major achievement). But I can't get the data to populate.

BTW, jqGrid 4.4.4 - jQuery Grid

here is my view:

@model Models.ExportDatex

<script type="text/javascript">

  $(document).ready(function () {
    $('#btnSearch').click(function (e) {

        var selectedSchool = $('#ddlSchool').children('option').filter(':selected').text();
        var selectedStudent = $('#ddlStudent').children('option').filter(':selected').text();
        var selectedYear = $('#ddlYear').children('option').filter(':selected').text();
        var selectedOption = $('#exportOption_1').is(':checked');

        if (selectedSchool == '' && selectedStudent == '' && selectedYear == '') {
            alert('Please specify your export criteria.');
            return false;
        }

        selectedSchool = (selectedSchool == '') ? ' ' : selectedSchool;
        selectedStudent = (selectedStudent == '') ? ' ' : selectedStudent;
        selectedYear = (selectedYear == '') ? ' ' : selectedYear;

        var extraQueryParameters = {
            school: selectedSchool,
            student: selectedStudent,
            year: selectedYear,
            option: selectedOption
        };

        $('#searchResults').jqGrid({
            datatype: 'json',
            viewrecords: true,
            url: '@Url.Action("GridData")?' + $.param(extraQueryParameters),
            pager: '#searchResultPager',
            colNames: ['SchoolID', 'Student Name', 'Student ID', 'Apprenticeship', 'Result'],
            colModel: [
                { name: 'SchoolID' },
                { name: 'Student Name' },
                { name: 'StudentID' },
                { name: 'Apprenticeship' },
                { name: 'Result' }]
        }).trigger('reloadGrid', [{ page: 1 }]);
    });
  });

</script>

@using (Html.BeginForm("Index", "Datex", FormMethod.Post))
{
  <h2>Export to Datex</h2>
  <div class="exportOption">
    <span>
        @Html.RadioButtonFor(model => model.ExportOption, "true", new { id = "exportOption_1" })
        <label for="exportOption_1">VET Results</label>
    </span>
    <span>
        @Html.RadioButtonFor(model => model.ExportOption, "false", new { id = "exportOption_0" })
        <label for="exportOption_0">VET Qualifications</label>
    </span>
</div>

<div class="exportSelectionCriteria">
    <p>Please specify the criteria you want to export data for:</p>

    <table>
        <tr>
            <td>School:</td>
            <td>@Html.DropDownListFor(model => model.SchoolID, Model.Schools, new { id = "ddlSchool" })</td>
        </tr>
        <tr>
            <td>Student: </td>
            <td>@Html.DropDownListFor(model => model.StudentID, Model.Students, new { id = "ddlStudent" })</td>
        </tr>
        <tr>
            <td>Year Completed:
            </td>
            <td>
                @Html.DropDownListFor(model => model.YearCompleted, Model.Years, new { id = "ddlYear" })
            </td>
        </tr>
    </table>
    <table id="searchResults"></table>
    <div id="searchResultPager"></div>
  </div>
  <div class="exportSearch">
    <input type="button" value="Search" id="btnSearch" />
    <input type="submit" value="Export" id="btnExport" />
  </div>
}

Here is my Controller. As we don't have a database yet, I am just hardcoding some results while using an existing table from a different DB to provide record IDs.

[HttpGet]
public JsonResult GridData(string sidx, string sord, int? page, int? rows, string school, string student, string year, string option)
{
  using (SMIDbContainer db = new SMIDbContainer())
  {
      var ds = (from sch in db.SCHOOLs
                where sch.Active.HasValue
                && !sch.Active.Value
                && sch.LEVEL_9_ORGANISATION_ID > 0
                select sch).ToList();

      var jsonData = new
      {
          total = 1,
          page = 1,
          records = ds.Count.ToString(),
          rows = (
          from tempItem in ds
          select new
          {
              cell = new string[]{
                  tempItem.LEVEL_9_ORGANISATION_ID.ToString(),
                  tempItem.SCHOOL_PRINCIPAL,
                  "40161",
                  "No",
                  "Passed (20)"
              }
          }).ToArray()
      };
      return Json(jsonData, JsonRequestBehavior.AllowGet);
  }
}
Community
  • 1
  • 1
Sam Banks
  • 85
  • 13

1 Answers1

1

Is the JSON you are passing back to the grid valid? Are you passing back the information that the jqGrid needs? Why setup your jqGrid inside of an ajax call instead of inside your $(document).ready(function () { ?

Here is an example of the portion of code I use to format my json for jqGrid:

 var jsonData = new
            {
                total = (totalRecords + rows - 1) / rows,
                page = page,
                records = totalRecords,                
                rows = (
                    from tempItem in pagedQuery
                    select new
                    {
                        cell = new string[] {
                            tempItem.value1,
                            tempItem.value2, ........

                     }
               }).ToArray()
      };
      return Json(jsonData, JsonRequestBehavior.AllowGet);

If you want to make your user search first, you can on the client side, set the jqgrid datatype: local and leave out the url. Then after your user does whatever you want them to do you can have the jqGrid go out and fetch the data, via something like:

 $('#gridName').jqGrid('setGridParam', { datatype: 'json', url: '/Controller/getGridDataAction' }).trigger('reloadGrid', [{ page: 1}]);

If you want to pass in the search data, or other values to the controller/action that is providing the data to the jqGrid you can pass it via the postData: option in the jqGrid. To set that before going out you can set it via the setGridParam option as shown above via postData: { keyName: pairData}.

MVC and jqGrid work great...there are a ton of examples on stackoverflow and Oleg's answers are a vast resource on exactly what you are trying to do. No hole in desk via head banging required!

Mark
  • 3,123
  • 4
  • 20
  • 31
  • I suspect that the problem may well be the json data format. I've changed my code to match what you suggested, but now instead of displaying the empty grid after searching, it just displays a vertical line. – Sam Banks Mar 01 '13 at 01:13
  • A very line? Post up your JSON that is going to your jqGrid. – Mark Mar 01 '13 at 01:15
  • sorry, vertical line. But you saw it before I fixed it. – Sam Banks Mar 01 '13 at 01:15
  • and is your JSON valid? with all the info the grid would need? – Mark Mar 01 '13 at 01:21
  • {"total":1,"page":1,"records":"8", "rows":[ {"cell":["38","email@address.net","40161","No","Passed (20)"]}, {"cell":["81","email@address.net","40161","No","Passed (20)"]}, {"cell":["82","email@address.net","40161","No","Passed (20)"]}, {"cell":["206","email@address.net","40161","No","Passed (20)"]}, {"cell":["253","email@address.net","40161","No","Passed (20)"]}, {"cell":["997","email@address.net","40161","No","Passed (20)"]}, {"cell":["998","email@address.net","40161","No","Passed (20)"]}, {"cell":["999","email@address.net","40161","No","Passed (20)"]} ]} – Sam Banks Mar 01 '13 at 01:27
  • Looks good to me, I would suggest going back to basics on your grid, as it looks like you are setting it up weird... I would follow the setup I laid out above unless you really have a use case for doing otherwise. – Mark Mar 01 '13 at 01:35
  • My grid is as basic as I can make it :) In $(document).ready() it is defined as $('#searchResults').jqGrid({ datatype: 'local' }); Then on the button click I specify the datatype, url, and viewrecords=true and trigger the reload. – Sam Banks Mar 01 '13 at 02:09
  • Ah well I was still going on the code you have posted above with the weird $.ajax setup. Again I would take it more basic and have your jqGrid setup on $(document).ready, etc... it really shouldn't be that hard to get a basic grid up and running. – Mark Mar 01 '13 at 02:18
  • It won't let me post my current code in a new response for another 3 hours (because my rep's too low). and I don't want to remove my original code in case someone points out "you're missing a full stop" and suddenly everything works... – Sam Banks Mar 01 '13 at 02:21
  • Gotcha, well like I said...you got the server peice going as far as the JSON goes, so the client side should be easy...I would think stripping it back to the basics and building it up would have it working in no time. – Mark Mar 01 '13 at 02:24
  • My current document ready script - var tempParms = {school: ' ',student: ' ',year: ' ',option: 'true'}; $('#searchResults').jqGrid({ datatype: 'json', url: '@Url.Action("GridData")?' + $.param(tempParms), viewrecords: true });. I can see it hit the server, and get a response, but no grid is displayed. The client has a telerik licence, I might go see if it includes their kendo ui product. – Sam Banks Mar 01 '13 at 02:30
  • Holy crap. specifying colNames & colModel makes the grid work. Thanks for your help Mark – Sam Banks Mar 01 '13 at 02:46