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();
                    }
                }
            }
        }
    }
Andrus
  • 22,189
  • 50
  • 171
  • 330

2 Answers2

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).

Community
  • 1
  • 1
Oleg
  • 217,934
  • 30
  • 386
  • 757
  • 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 ? – Andrus Jul 06 '11 at 12:33
  • @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)? – Oleg Jul 06 '11 at 12:51
  • 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 True – Andrus Jul 06 '11 at 13:21
  • 1
    @Andrus: I made for you the demo which do what you need. See UPDATED part of my answer. – Oleg Jul 06 '11 at 14:34
  • 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. – Andrus Jul 06 '11 at 15:47
  • @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. – Oleg Jul 06 '11 at 17:28
  • 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. – Andrus Jul 06 '11 at 17:55
  • 2
    @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 ``. 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()`. – Oleg Jul 06 '11 at 19:20
  • 1
    @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](http://en.wikipedia.org/wiki/Trim_(programming)#JavaScript) or use more complex version (see [here](http://blog.stevenlevithan.com/archives/faster-trim-javascript) or [here](http://blog.stevenlevithan.com/archives/faster-trim-javascript) for example) – Oleg Jul 06 '11 at 19:27
  • or you can do mycelldata = mycell.html() – Darren Cato Aug 17 '11 at 21:52
  • @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;`. – Oleg Aug 17 '11 at 22:10
  • @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? – Andrus Nov 12 '11 at 22:22
  • @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? – Andrus Nov 12 '11 at 22:31
  • 1
    @Andrus: It could be important *where* you define `myAltRowClass`. Look at [the demo](http://www.ok-soft-gmbh.com/jqGrid/SimpleLocalGridChangeRowBackgroundBasedOnCheckboxes.htm) described in the answer and do the same in your project. – Oleg Nov 12 '11 at 22:46
  • @Oleg: Thank you very much. I moved myAltRowClass definition to Site.Master and it works. Why it does not work from Site.css file ? – Andrus Nov 13 '11 at 09:44
  • @Oleg: I updated question based on your rowattr recomendation in answer – Andrus May 13 '12 at 19:05
  • @Andrus: modification of cells added by formatter "actions" is not the same as adding some attributes to the row (to `` 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. – Oleg May 13 '12 at 19:15
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