0

I am trying to add button instead of View column but i tried with formatter still button is not loading but records are coming for the rest of the columns. Below is my code:

$(function () {
    $("#grid").jqGrid({
        url: "/Location/LocationsList1",
        datatype: 'json',
        mtype: 'Get',
        colNames: ['Id', 'Country Name', 'State Name', 'City Name', 'Location Name','View'],
        colModel: [
            { key: true, hidden: true, name: 'Id', index: 'Id', editable: true },
            { key: false, name: 'CountryName', index: 'CountryName', editable: true },
            { key: false, name: 'StateName', index: 'StateName', editable: true },
            { key: false, name: 'CityName', index: 'CityName', editable: true },
            { key: false, name: 'Name', index: 'Name', editable: true },
            { key: false, name: 'View', index: 'View', editable: true,formatter:ViewButton }],
        pager: jQuery('#pager'),
        rowNum: 10,
        rowList: [10, 20, 30, 40],
        height: '100%',
        viewrecords: true,
        caption: 'Location',
        emptyrecords: 'No records to display',
        jsonReader: {
            root: "rows",
            page: "page",
            total: "total",
            records: "records",
            repeatitems: false,
            Id: "0"
        },

    });
});
function ViewButton(cellvalue, options, rowObject) {
    var rowid= options.rowid;
    var button = "<button class=\"viewLineItem\" id="+ rowid+">View Line   Item</button>"
    $('#' + rowid).die();
    $('#' + rowid).live('click', function (rowId) {
        alert("hi");
        alert(rowId);
    });
};

I am new to JqGrid and don't know how it works. Any guidance/Help will be appreciated.

Oleg
  • 220,925
  • 34
  • 403
  • 798
Steve
  • 352
  • 2
  • 6
  • 24

1 Answers1

0

The code has some problems

  1. options has no rowid property, but it has rowId property. You should change options.rowid to options.rowId
  2. The formatter will be called during building the HTML fragment of the grid body. No element of the grid exist at the moment on the page. Thus you can't use $('#' + rowid).live('click', ...); at the moment.
  3. The formatter have to return the HTML fragment, which will be placed in the corresponding cell (inside of <td>). One misses return button; at the end of the formatter.
  4. There are exist well-known name conversion in JavaScript. One should use functions, which starts with capital letter only if you define the constructor of the new class. You see that ViewButton will be displayed in the other color to distinguish classes from other function. You should rename ViewButton to viewButton to hold the standard name conversion of JavaScript.
  5. It's better don't specify index property in colModel. In the same way one should not include the properties with the defaul value, like key: false. To specify common property for many columns you can use cmTemplate property.
  6. One should reduce the number of global functions, because the functions will be considerd as the properties of window object.
  7. instead of usage hidden column with name: 'Id' one can specify id: 'Id' property of jsonReader. You use repeatitems: false property, which means that every item of input data has properties CountryName, StateName and so on. The default name of the id property (the rowid - the id of <tr> elements) is id, but you use Id instead. The property id: "Id" informs jqGrid about it.

The modified code could be about the following

$(function () {
    function viewButton(cellvalue, options, rowObject) {
        return "<button class=\"viewLineItem\" id=\"" +
            options.rowId + "\">View Line   Item</button>";
    }

    $("#grid").jqGrid({
        url: "/Location/LocationsList1",
        datatype: 'json',
        colNames: ['Id', 'Country Name', 'State Name', 'City Name', 'Location Name','View'],
        colModel: [
            { name: 'Id', key: true, hidden: true },
            { name: 'CountryName' },
            { name: 'StateName' },
            { name: 'CityName' },
            { name: 'Name' },
            { name: 'View', editable: false, formatter: viewButton }
        ],
        cmTemplate: { editable: true },
        pager: '#pager',
        rowNum: 10,
        rowList: [10, 20, 30, 40],
        height: '100%',
        viewrecords: true,
        caption: 'Location',
        emptyrecords: 'No records to display',
        jsonReader: { repeatitems: false, id: "Id" }
    });

    $("#jqGridA").click(function (e) {
        var $td = $(e.target).closest("tr.jqgrow>td"),
            rowid = $td.parent().attr("id"),
            p = $(this).jqGrid("getGridParam");

        if ($td.length > 0 && p.colModel[$td[0].cellIndex].name === "View") {
            alert(rowid);
        }
    });
});

The last part of the above code ($("#jqGridA").click(...);) register one click handler for the whole grid. If the user clicks on any cell then the event handler will be called because of event bubbling. The e.target gives as the DOM element, which was clicked (for example the <button>). By using closest we can go to the outer <td> element, which parent is the row (<tr>) of the grid. The .attr("id") of the row is the rowid. Such binding works more effectively as binding click handler to every button inside of the grid.

By the way jqGrid has already one click event handler. One can use beforeSelectRow callback, because it will be called inside of the click handler. One should only don't forget to return true from the beforeSelectRow callback to inform jqGrid that you allow to select the row. The callback beforeSelectRow has already rowid as the first parameter, which simplify our code a little. The final code will be

$(function () {
    function viewButton(cellvalue, options, rowObject) {
        return "<button class=\"viewLineItem\" id=\"" +
            options.rowId + "\">View Line   Item</button>";
    }

    $("#grid").jqGrid({
        url: "/Location/LocationsList1",
        datatype: 'json',
        colNames: ['Id', 'Country Name', 'State Name', 'City Name', 'Location Name','View'],
        colModel: [
            { name: 'CountryName' },
            { name: 'StateName' },
            { name: 'CityName' },
            { name: 'Name' },
            { name: 'View', editable: false, formatter: viewButton }
        ],
        cmTemplate: { editable: true },
        pager: '#pager',
        rowNum: 10,
        rowList: [10, 20, 30, 40],
        height: '100%',
        viewrecords: true,
        caption: 'Location',
        emptyrecords: 'No records to display',
        jsonReader: { repeatitems: false, id: "Id" },
        beforeSelectRow: function (rowid, e) {
            var $td = $(e.target).closest("tr.jqgrow>td"),
                p = $(this).jqGrid("getGridParam");

            if ($td.length > 0 && p.colModel[$td[0].cellIndex].name === "View") {
                alert(rowid);
            }
        }
    });
});
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thank you Oleg..That works great..Do you have any idea about implementing sorting and searching in grid without ajax post call to controller in JQGrid – Steve Oct 25 '16 at 05:20
  • 1
    @Steve: You are welcome! The server should just return the array of **all** items (from `url`) and you should add `loadonce: true` option of jqGrid. In case of usage my fork of jqGrid ([free jqGrid](https://github.com/free-jqgrid/jqGrid)) you can use additionally `forceClientSorting: true` option, which allows to sort (by `sortname` and `sortorder`) and to filter (by `postData.filters`) the data returned from the server **before** the first page of returned data is displayed. See [the demo](http://www.ok-soft-gmbh.com/jqGrid/OK/formEditOnDoubleClick-jqueryui-fa1.htm) as an example. – Oleg Oct 25 '16 at 07:49
  • @Steve: The performance of **local** paging, sorting and filtering is very good. You can see on [the demo](http://www.ok-soft-gmbh.com/jqGrid/OK/performane-13-40000-20-free-jqgrid.htm) how much time takes sorting, filtering or paging of the grid with 40000 rows, 13 columns displayed in 20 rows per page. – Oleg Oct 25 '16 at 07:52
  • `loadonce:true` works for me.Thanks for that..but for this i have to load all the data at once..actually i was trying to use `.ToPagedList` in my query but it was returning only first 10 records and as the pager was disabled to fetch 2nd page of 10 records so not able to work with pager in this case :( – Steve Oct 25 '16 at 09:20
  • @Steve: I don't full understand your problem. How many totally rows should be displayed in the grid? You can see in my last comment that 1000 or 40000 rows can be loaded and filtered quickly enough. Why loading of all the data is the problem? If you have really a lot of data (millions of items) then you have to implement **server side paging, sorting and filtering**. Displaying unfiltered data in the grid (the first 20 from 10 millions) gives the user no practical information. `.ToPagedList` is unclear for me. It you have server side problems you should open new question with the C# code. – Oleg Oct 25 '16 at 09:38