jqGrid: change background color of row based on row cell value by column name
Asked Answered
A

2

9

jqGrid has column named Posted. It can be positioned in different positions depending how grid is configured by customer but is always prssent.

I need to change background color of rows if Posted column has value True

I tried colmodel below but alert(rdata.Posted) displays always undefined.

How to change backgound color of row if Posted column in this row has value true ?

I looked into lot of Oleg and other solutions for changing background color but they are using hard coded column number.

colModel: [

{"cellattr":function(rowId, tv, rawObject, cm, rdata) {  
if (rdata.Posted)
    return 'class="jqgrid-readonlycolumn"';
    return '';
      }
  ,"label":"Klient","name":"Klient_nimi","classes":null,"hidden":false},


{"label":null,"name":"Posted","editable":true,"width":0,
"classes":null,"hidden":true}],
...

Update

In update2 Oleg recommends to use rowattr. I need to hide inlined delete button and custom post button in actions column also. I'm usijng code below in loadComplete. How to implement this using rowattr ?

var LoadCompleteHandler = function () {
    var iCol = getColumnIndexByName($grid, 'Kinnitatud'),
      postedDateCol = getColumnIndexByName($grid, 'Kinkuup'),
      cRows = $grid[0].rows.length,
      iRow,
      row,
      className,
      isPosted,
      mycell,
      mycelldata,
      i, count,
      cm = $grid.jqGrid('getGridParam', 'colModel'),
      l,
      iActionsCol = getColumnIndexByName($grid, '_actions');
    l = cm.length;
    if (iCol > 0 || postedDateCol > 0) {
        for (iRow = 0; iRow < cRows; iRow = iRow + 1) {
            row = $grid[0].rows[iRow];
            className = row.className;
            isPosted = false;
            if ($.inArray('jqgrow', className.split(' ')) > 0) { // $(row).hasClass('jqgrow')
                if (iCol > 0) {
                    isPosted = $(row.cells[iCol]).find(">div>input:checked").length > 0;
                }
                if (postedDateCol > 0) {
                    mycell = row.cells[postedDateCol];
                    mycelldata = mycell.textContent || mycell.innerText;
                    isPosted = mycelldata.replace(/^\s+/g, "").replace(/\s+$/g, "") !== "";
                }

                if (isPosted) {
                    if ($.inArray('jqgrid-postedrow', className.split(' ')) === -1) {
                        row.className = className + ' jqgrid-postedrow';
                        $(row.cells[iActionsCol]).find(">div>div.ui-inline-del").hide();
                        $(row.cells[iActionsCol]).find(">div>div.ui-inline-post").hide();
                    }
                }
            }
        }
    }
Adp answered 4/7, 2011 at 19:1 Comment(0)
A
13

The main ideas to change the background color of the row you will find here and here. I recommend you to read this answer which discussed different advantages and disadvantages of different approaches.

To get column index from the column name you can use following simple function:

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

The function getColumnIndexByName($("#list"), 'MyColumnName') will get you the index in colModel of the 'MyColumnName' column.

To change the background color you can follow the example

loadComplete: function() {
    $("tr.jqgrow:odd").addClass('myAltRowClass');
}

from the answer, but instead of ':odd' filter you can write the filter yourself using jQuery.filter. Inside of the filter you can use :nth-child() to access the data from the corresponding <td> element (see here)

UPDATED: You can do the following (very close to the code from the another answer):

loadComplete: function() {
    var iCol = getColumnIndexByName($(this),'closed'),
        cRows = this.rows.length, iRow, row, className;

    for (iRow=0; iRow<cRows; iRow++) {
        row = this.rows[iRow];
        className = row.className;
        if ($.inArray('jqgrow', className.split(' ')) > 0) {
            var x = $(row.cells[iCol]).children("input:checked");
            if (x.length>0) {
                if ($.inArray('myAltRowClass', className.split(' ')) === -1) {
                    row.className = className + ' myAltRowClass';
                }
            }
        }
    }
}

The corresponding demo is here. You will see the following:

enter image description here

By the way if the 'Closed' column will be hidden everything will continue to work as before.

UPDATED 2: The answer describe how to use rowattr callback to simplify the solution and to have the best performance (in case of gridview: true).

Actinomycin answered 4/7, 2011 at 20:3 Comment(17)
thank you. Colmodel is defined as {formatter:"checkbox",label:null,name:"Posted",editable:true,classes:null,hidden:true}. I tried to get value using $("tbody > tr.jqgrow > td:nth-child("+(i+1)+")", grid[0]) but this returns strange array. How to get posted column value ?Adp
@Andrus: Do you want to find all rows where in the "Posted" column the checkbox is checked and mark the rows with background color (add the "jqgrid-readonlycolumn" class)?Actinomycin
Yes. Posted column is usually hidden (can switched on by user) so maybe checkbox is not rendered in this case. True / False values are passed from server as json to this column. I want to change background color for rows where Posted column value is TrueAdp
@Andrus: I made for you the demo which do what you need. See UPDATED part of my answer.Actinomycin
Thank you very much. It works. I marked it as answer and voted your response up. In another table I have column Kinkuup containing posting date or empty if not posted {"editoptions":{"maxlength":10,"size":10,"dataInit":function(element) { $(element).datepicker({dateFormat: 'dd.mm.yyyy' }) }},"label":null,"name":"Kinkuup","editable":true,"width":0,"classes":null,"hidden":true} . How to check is this column empty or not for changing row background for non empty value ? Your code works for checkbox only.Adp
@Andrus: You are welcome! You use voting of comments. To vote the answer one need click large arrow which are above the place where you accept the answer. About your question: you can use row.cells[iCol].textContent || row.cells[iCol].innerText to get the text contain from the cell.Actinomycin
thank you. alert shows that empty date value is space but check against space didnt work. I was able to check for empty date only using posted =row.cells[postedDateCol].textContent.toString().trim() != "" Can this check shortened? I upvoted 5 your answers to my questions.Adp
@Andrus: Sorry, but in what language is the statement posted =row.cells[postedDateCol].textContent.toString().trim() != "" written? I suggest that you use something var mycell=row.cells[postedDateCol], mycelldata = mycell.textContent || mycell.innerText; if (mycelldata === "") {/*do something in case of empty data*/}. The mycell will be DOM element of <td>. Some web browsers support only textContent property. Another browsers support only innerText property. So the mycelldata will get browser independent the cell contain as a string datatype. You don't need call toString().Actinomycin
@Andrus: If you need trim the text from the cell you can use different ways, but trim method not exist (or at least not in all implementation of JavaScript). It exist in JavaScript 1.8.1 (Firefox 3.5 and later), and the ECMAScript 5 standard, but not everywhere. You can use replace method, define trim method like described here or use more complex version (see here or here for example)Actinomycin
or you can do mycelldata = mycell.html()Telepathy
@Shaded2: mycell is not jQuery object. It's DOM object. So one can do mycelldata = $(mycell).text() (not html()) of cause, but it is slowly as mycelldata = mycell.textContent || mycell.innerText;.Actinomycin
@Oleg. I tried to use this in one application by calling it from loadcomplete . alert in this loop shows that row.className contains altRowClass name. However jqgrid row background does not change. How to find the reason and make it to change row background?Adp
@Oleg: row.className = 'jqgrow ui-row-ltr myAltRowClass'; works but row.className = 'ui-widget-content jqgrow ui-row-ltr myAltRowClass'; does not change background. How to fix this?Adp
@Andrus: It could be important where you define myAltRowClass. Look at the demo described in the answer and do the same in your project.Actinomycin
@Oleg: Thank you very much. I moved myAltRowClass definition to Site.Master and it works. Why it does not work from Site.css file ?Adp
@Oleg: I updated question based on your rowattr recomendation in answerAdp
@Andrus: modification of cells added by formatter "actions" is not the same as adding some attributes to the row (to <tr> element). In the case rowattr will not help you. Instead of that you can try to use custom formatter instead of formatter "actions". Inside of the custom formatter you can call formatter "actions" and modify the text returned by formatter "actions". I suppose that in the way one can effectively implement your requirements.Actinomycin
D
0

I think the answer is right here: http://www.trirand.net/forum/default.aspx?g=posts&m=2678

Let me know if this is wat you need.

Best Regards.

Apolo

Dunnite answered 4/7, 2011 at 19:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.