Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking from a column value in jqGrid to a new page using GET

I have created a jqGrid that contains some fields such as:

job_id, name, etc

What I am trying to do is make so that when the click on the value in the job_id column, it will redirect them to:

job.php?job_id=(value that they clicked on)

I started by trying to use the following as my colModel:

{ name:'job_id', index:'job_id', edittype:'select', formatter:'showlink',
  formatoptions:{baseLinkUrl:'job.php'}, width:50, align:'center' }

But what this results in is a redirection to:

job.php?job_id=(row_id)

I did some searching, and found a post by the developer of the open source version of this software who suggested using the following colModel and additional JS:

{ name:'job_id', index:'job_id', edittype:'select', formatter:'showlink',
  formatoptions:{baseLinkUrl:'#'}, width:50, align:'center' }

loadComplete: function() {
    var myGrid = $("#home_list");
    var ids = myGrid.getDataIDs();
    for (var i = 0, idCount = ids.length; i < idCount; i++) {
        $("#"+ids[i]+" a",myGrid[0]).click(function(e) {
            var hash=e.currentTarget.hash;// string like "#?id=0"
            if (hash.substring(0,5) === '#?id=') {
                var id = hash.substring(5,hash.length);
                var text = this.textContent;
                location.href="job.php?id="+text;
            }
            e.preventDefault();
        });
    }   
}

But this is not compatible with IE. In addition to this, when displaying a large number of rows in the jqGrid, it takes a extremely long time to load, say 5 seconds + for 500 rows.

I'm going to keep working on this, but is this something that anyone else has done?

like image 755
Linnay Avatar asked Feb 15 '11 23:02

Linnay


1 Answers

You used code example from my old answer so I decide I should answer on you question.

I agree with the critic about performance of the code of the loadComplete. So +1 from me for your question. The construct $("#"+ids[i]+" a", myGrid[0]) inside of long loop can work very slowly. One can easy fix the problem if one will use the following

var getColumnIndexByName = function (columnName) {
    var cm = $(this).jqGrid("getGridParam", "colModel"), l = cm.length, i;
    for (i = 0; i < l; i++) {
        if (cm[i].name === columnName) {
            return i; // return the index
        }
    }
    return -1;
};

var myGrid = $("#list");
myGrid.jqGrid({
    ...
    loadComplete: function () {
        var i = getColumnIndexByName.call(this, 'Subcategory');
        // nth-child need 1-based index so we use (i+1) below
        $("tbody>tr.jqgrow>td:nth-child(" + (i+1) + ")>a", this).click(function (e) {
            var hash=e.currentTarget.hash;// string like "#?id=0"
            if (hash.substring(0,5) === '#?id=') {
                var id = hash.substring(5, hash.length);
                var text = this.textContent || this.innerText;
                alert("clicked the row with id='"+id+"'. Link contain '"+text+"'");
                location.href = "http://en.wikipedia.org/wiki/" + text;
            }
            e.preventDefault();
        });
    }
});

You can see that the improved version of the demo works exactly as the original demo. To show the performance of the method on 1000 rows I created one more demo. One can see that the new method works quickly.

Now back to your main problem. The best performance we will receive if you write your custom formatter and unformatter instead of the usage of the predefined formatter showlink. The code can be about following:

formatter: function (cellvalue, options, rowObject) {
    return "<a href=\"job.php?job_id=" + rowObject.job_id + "\">" + cellvalue + "</a>";
},
unformat: function (cellvalue, options, cellobject) {
   return cellobject.job_id;
}

The exact code depend on which datatype you use, whether you use loadonce:true or not and which jsonReader you use. It can be for example, that rowObject is array in your case and you have to use array index of the corresponding data field (like rowObject[4]) instead of rowObject.job_id.

UPDATED: I think the best implementation way will be the usage of onCellSelect or beforeSelectRow instead of binding click event to every element in the column. I recommend to read the following answers for details: this one, another one and one more old answer.

like image 91
Oleg Avatar answered Dec 21 '22 23:12

Oleg