0

Here is how I fill the JQgrid:

jQuery("#responseMessages").jqGrid(
                                   'addRowData',
                                   i+1,
                                   {
                                    distance:messages[i].distance,
                                    age:messages[i].age,
                                    message:messages[i].message,
                                    messageId:messages[i].messageId, 
                                    report:reportBtn
                                   }
                                  );

Now the reportBtn is actually HTML markup so it places a button in the last column, letting the user report a message, here's the markup for that:

var reportBtn = "<input style='height:22px;width:100px;' type='button' value='Report' onclick=\"\" />";

When I click report, I want it to give me the messageId from the row that it is in (messageId is the hidden column).

How would I do that?

Thanks!

EDIT:

function GetMessages()
        {
            $.ajax(
            {
                type: "POST",
                url: "<%= Url.Action("GetMessages", "Home") %>",
                success: function (result) {
                    var messages = result;
                    if (messages.length == 0)
                    {
                        $('#noMessagesAlert').show();
                    }
                    else
                    {
                        $('#noMessagesAlert').hide();
                        createGrid(messages);
                    }
                },
                error: function (error) {

                }
            });
        }

function createGrid(messages)
        {
            var myGrid = 
                jQuery("#responseMessages"),
                reportBtn = "<input style='height:22px;width:100px;' type='button' value='Report' />",
                mydata = messages,
                getColumnIndexByName = function(grid,columnName) {
                    var cm = grid.jqGrid('getGridParam','colModel');
                    for (var i=0,l=cm.length; i<l; i++) {
                        if (cm[i].name===columnName) {
                            return i; // return the index
                        }
                    }
                    return -1;
            };

            myGrid.jqGrid({
                data: mydata,
                datatype: 'local',
                height: 'auto',
                colModel: [
                    { name:'distance', index:'distance', label:'Distance', width:100 },
                    { name:'age', index:'age', label:'Age', width:75 },
                    { name:'message', index:'message', label:'Message', width:500 },
                    { name:'messageId', index:'messageId', key:true, hidden:true },
                    { name:'report', index:'report', label: 'Report', width:100,
                        formatter:function() { return reportBtn; } }
                ],
                loadComplete: function() {
                    var i=getColumnIndexByName(myGrid,'report');
                    // nth-child need 1-based index so we use (i+1) below
                    $("tbody > tr.jqgrow > td:nth-child("+(i+1)+") > input",myGrid[0]).click(function(e) {
                        var tr=$(e.target,myGrid[0].rows).closest("tr.jqgrow");
                        var x=window.confirm("Are you sure you want to report this message?")
                        if (x)
                        {
                            reportMessage(tr[0].id);
                        }
                        e.preventDefault();
                    });
                },
                rowNum:25, 
                rowList:[10,25,50],
                pager: '#pager'
            });
        }

So here's the path the code takes. GetMessages gets called from a button click, and then if it returns anything, createGrid gets called passing in the returned list of messages.

This works perfect the first time I do it. Now, if I just go and click that same button again, the grid doesn't update it's data (which should be different, because different data is coming back from the server). It just stays the same.

Why?

Scott
  • 4,066
  • 10
  • 38
  • 54

1 Answers1

1

You can implement your requirements in many way. I suggest use to use the way which I described in the answer. It use unobtrusive JavaScript style. Moreover because you use addRowData with i+1 value I suspect that you fill the grid in the loop which can be very slow with the large number of rows. The best is to use data parameter of jqGrid

var myGrid = jQuery("#list"),
    reportBtn = "<input style='height:22px;width:100px;' type='button' value='Report' />",
    mydata = [
        {messageId:"m10", message:"Bla bla", age:2, distance:123},
        {messageId:"m20", message:"Ha Ha",   age:3, distance:456},
        {messageId:"m30", message:"Uhhh",    age:2, distance:789},
        {messageId:"m40", message:"Wauhhh",  age:1, distance:012}
    ],
    getColumnIndexByName = function(grid,columnName) {
        var cm = grid.jqGrid('getGridParam','colModel');
        for (var i=0,l=cm.length; i<l; i++) {
            if (cm[i].name===columnName) {
                return i; // return the index
            }
        }
        return -1;
    };

myGrid.jqGrid({
    data: mydata,
    datatype: 'local',
    colModel: [
        { name:'report', index:'report', width:108,
          formatter:function() { return reportBtn; } },
        { name:'messageId', index:'messageId', key:true, width:50, hidden:true },
        { name:'age', index:'age', label:'Age', width:50, sorttype:'int', align:'center' },
        { name:'message', index:'message', label:'Message', width:110 },
        { name:'distance', index:'distance', label:'Distance', width:80, sorttype:'int', align:'center' }
    ],
    sortname: 'age',
    sortorder: "desc",
    loadComplete: function() {
        var i=getColumnIndexByName(myGrid,'report');
        // nth-child need 1-based index so we use (i+1) below
        $("tbody > tr.jqgrow > td:nth-child("+(i+1)+") > input",myGrid[0]).click(function(e) {
            var tr=$(e.target,myGrid[0].rows).closest("tr.jqgrow");
            alert("clicked the row with the messageId='"+tr[0].id+"'");
            e.preventDefault();
        });
    },
    viewrecords: true,
    rownumbers: true,
    //multiselect:true,
    height: "100%",
    pager: '#pager',
    caption: "How to create Unobtrusive button"
});

the demo you can see live here.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • thanks, i dicepher this but i think this is the right answer. – Scott Apr 09 '11 at 14:26
  • Hey man, using this, if I try to fill the grid more than once, it doesn't fill. It will only fill after I refresh the page and do it. – Scott Apr 09 '11 at 15:03
  • @Scott: Sorry, I don't understand what you mean. Which kind of grid filling you mean? If one click on sorting column for example in the demo http://www.ok-soft-gmbh.com/jqGrid/UnobtrusiveButtons.htm the grid will be new filled. Could you post URL of the page where you have the problem or the post the code which you now use? – Oleg Apr 09 '11 at 15:24
  • @Scott: There are problems in general organization of your code. You should create the grid **only once**. Moreover I don't understand why you need separate `$.ajax` at all. Look at "UPDATED" part of [this answer](http://stackoverflow.com/questions/5500805/asp-net-mvc-2-0-implementation-of-searching-in-jqgrid/5501644#5501644) with [the demo project](http://www.ok-soft-gmbh.com/jqGrid/jqGridDemo.zip) in ASP.NET MVC 2.0 for VS2008 (in VS2010 it can be even a little more easy). You should create jqGrid once and if needed use only `$("#responseMessages").trigger("reloadGrid")`. – Oleg Apr 09 '11 at 16:13
  • @Scott: You can test the number of messages returned from the server inside of `loadComplete: function(data) {/*here*/}` function. Instead of `error` of `$.ajax` you should use `loadError` of jqGrid. I recommend you use also sorting, paging and filtering/searching on the server side. Just follow example which I posted. Do you also use ASP.NET MVC? Which access to the database you use? Entity Framework is the most easy in the implementation with jqGrid. – Oleg Apr 09 '11 at 16:18
  • I don't think you are understanding exactly how I'm filling the grid. – Scott Apr 09 '11 at 17:58
  • reloadData isn't working, loadJsonData doesn't work, nothing works – Scott Apr 09 '11 at 18:03
  • @Scott: I understand as so: you call `GetMessages` action of your `Home` controller. If the returned data are not empty you create local jqGrid. Is it not so? – Oleg Apr 09 '11 at 18:06
  • @Scott: What is `reloadData` or `loadJsonData`? You don't posted the code of the functions. – Oleg Apr 09 '11 at 18:07
  • GetMessages on the home controller though takes in other parameters. Not just ones that have to do with the grid. So I can't just tell the JQgrid to get it's data from that URL. I need to pass other things in to get it – Scott Apr 09 '11 at 18:12
  • @Scott: If you can't make any changes on the server side you can follow [the answer](http://stackoverflow.com/questions/2835957/jquery-with-asp-net-mvc-calling-ajax-enabled-web-service/2836817#2836817) and include `jsonReader` which read `List` returned by the `GetMessages` action. If you do can modify the server code you can add **additional** `GetMessagesForjqGrid` action which read jqGrid parameters and returned back the page of sorted data. – Oleg Apr 09 '11 at 18:21
  • @Scott: Just try with the additional parameter `jsonReader: {repeatitems: false,id: "messageId", root: function (obj) { return obj; }, page: function (obj) { return 1; }, total: function (obj) { return 1; }, records: function (obj) { return obj.length; }}` and use `GetMessages` in the `url` – Oleg Apr 09 '11 at 18:29