1

free jqgrid shows orders. Posted orders should have yellow background and only open action button. Unposted orders have white background, standard delete and custom post action button.

colmodel for actions column:

{"hidden":false,"label":"Activity","name":"_actions","search":false,"width":94
,"sortable":false,"formatter":"actions","viewable":false,"formatoptions":{"editbutton":false,"onSuccess":function (jqXHR) { jqXHRFromOnSuccess=jqXHR;return true;}
,"delbutton":true,"delOptions":{"url":"http://localhost:52216/admin/Grid/Delete?_entity=DoklstlT","afterComplete":function (response, postdata, formid) { 
summarefresh($grid);
$grid[0].focus(); 
}
}}},

posted state is detemined by boolean Kinnitatud column :

{"label":null,"name":"Kinnitatud","index":"Kinnitatud","editoptions":{"value":"True:False","readonly":"readonly","disabled":"disabled"},"template":"booleanCheckboxFa","editable":true,"width":0,"classes":null,"hidden":true,"searchoptions":{"sopt":["eq","ne"],"value":":Free;true:Yes;false:No"},"dataEvents":[{"type":"focus","fn":function(e) {if(typeof e.target.ischanged=='undefined') {e.target.ischanged=false}}
},"",{"type":"click","fn":function(e) {dataChanged(e.target)}
},{"type":"blur","fn":function(e) {summarefresh()}
}]}],

in other grid posted state is determined by Kinkuup column which is not filled for unposted documents:

{"template":DateTemplate
,"label":null,"name":"Kinkuup","index":"Kinkuup","editoptions":{"dataInit":null,"size":10,"readonly":"readonly","disabled":"disabled"},"searchoptions":{"dataInit":initDateSearch
,"size":10,"attr":{"size":10}},"width":0,"classes":null,"hidden":true,"dataEvents":[]}],

Both columns can hidden or visible in grid. depending on user preferences.

Custom actions buttons are created in loadComplete for all rows:

       loadComplete: function() {
            var iCol = getColumnIndexByName($(this),'_actions');
            $(this).children("tbody").children("tr.jqgrow")
               .children("td:nth-child("+(iCol+1)+")")
               .each(function() {

                   $("<div>",
                     {
                         title: "Confirm (F2)",
                         mouseover: function() {
                             $(this).addClass('ui-state-hover');
                         },
                         mouseout: function() {
                             $(this).removeClass('ui-state-hover');
                         },
                         click: function(e) {
                             resetSelection();
                             idsOfSelectedRows = [$(e.target).closest("tr.jqgrow").attr("id")];
                             $("#grid").jqGrid('setSelection', $(e.target).closest("tr.jqgrow").attr("id"), false);
                             $('#grid_postbutton').click();
                         }
                     }
                ) 
                 .addClass("ui-pg-div ui-inline-post")
                 .append('<span class="fa ui-state-default fa-fw fa-lock"></span>')
                 .prependTo($(this).children("div"));


                   $("<div>",
                       {
                           title: "Open (Enter)",
                           mouseover: function() {
                               $(this).addClass('ui-state-hover');
                           },
                           mouseout: function() {
                               $(this).removeClass('ui-state-hover');
                           },
                           click: function(e) {
                               openDetail($(e.target).closest("tr.jqgrow").attr("id"));
                           }
                       }
                    )
                     .addClass("ui-pg-div ui-inline-open")
                     .append('<span class="fa ui-state-default fa-folder-open-o"></span>')
                     .prependTo($(this).children("div"));

               }); 

After that buttons are conditionally removed using code from How to remove action buttons from posted rows in free jqgrid using Fontawesome checkbox formatter , row editing is conditionally disabled and background changed.

   disableRows('Kinkuup', false);
   disableRows('Kinnitatud', true);


 var disableRows = function (rowName, isBoolean) {
    var iCol = getColumnIndexByName($grid, rowName),
              cRows = $grid[0].rows.length,
              iRow,
              row,
              className,
              isPosted,
              mycell,
              mycelldata,
              cm = $grid.jqGrid('getGridParam', 'colModel'),
              iActionsCol = getColumnIndexByName($grid, '_actions'), l,
              isPostedStr;
    l = cm.length;
    for (iRow = 0; iRow < cRows; iRow = iRow + 1) {
        row = $grid[0].rows[iRow];
        className = row.className;
        if ($(row).hasClass('jqgrow')) {
            isPostedStr = $.unformat.call($grid[0], row.cells[iCol],
          { rowId: row.id, colModel: cm[iCol] }, iCol);
            //if (cm[iCol].convertOnSave) {
            //    isPosted = cm[iCol].convertOnSave.call(this, {
            //        newValue: isPostedStr,
            //        cm: cm[iCol],
            //        oldValue: isPostedStr,
            //        id: row.id,
            //        //item: $grid.jqGrid("getLocalRow", row.id),
            //        iCol: iCol
            //    });
            //}
            isPosted = isPostedStr !== "False" && isPostedStr.trim() !== "";

            if (isPosted) {
                if ($.inArray('jqgrid-postedrow', className.split(' ')) === -1) {
                    // todo: how to disable actions buttons and form editing:
                    row.className = className + ' jqgrid-postedrow not-editable-row';
                    $(row.cells[iActionsCol]).attr('editable', '0');
                    $(row.cells[iActionsCol]).find(">div>div.ui-inline-del").hide();
                    $(row.cells[iActionsCol]).find(">div>div.ui-inline-post").hide();
                    $(row.cells[iActionsCol]).find(">div>div.ui-inline-edit").hide();
                }
            }
        }
    }
};

How to use free jqgrid actions options to simplify this code ?

How to create uniform way to hide both standard edit and delete and user defined actions buttons? Hiding standard buttons still requires DOM modification even if custom button creating can conditionally disabled using callback. Maybe to define all actions buttons in same way. Maybe it can done using existing rowattr or cellattr callbacks or introducing new one.

Currently row is et to read only in code below using

row.className = className + ' jqgrid-postedrow not-editable-row';
$(row.cells[iActionsCol]).attr('editable', '0');

Is it reasonable to thant this so that diableRows can completely removed ? Maybe rowattr() can used instead of this.

Community
  • 1
  • 1
Andrus
  • 26,339
  • 60
  • 204
  • 378

1 Answers1

1

I made some changes in formatter: "actions" to simplify implementing of your scenario. The demo shows how to use new features. It displays the grid like on the picture below

enter image description here

The demo defines Action columns in colModel as

{ name: "act", template: "actions", align: "left", width: 58 }, // 58 = 2 + 18*3 + 2

and it uses actionsNavOptions (one can use formatoptions alternatively) to configure the options of formatter: "actions":

actionsNavOptions: {
    editbutton: false,
    custom: [
        { action: "open", position: "first",
            onClick: function (options) {
                alert("Open, rowid=" + options.rowid);
            } },
        { action: "post", position: "first",
            onClick: function (options) {
                alert("Post, rowid=" + options.rowid);
            } }
    ],
    posticon: "fa-lock",
    posttitle: "Confirm (F2)",
    openicon: "fa-folder-open-o",
    opentitle: "Open (Enter)",
    isDisplayButtons: function (options, rowData) {
        if (options.rowData.closed) { // or rowData.closed
            return { post: { hidden: true }, del: { display: false } };
        }
    }
}

Array custom defined action name, position and the onClick callback. To define the icon and the title (the tooltip) of the custom button one should specify the options close to the options of navigator bar. The properties which specify the icon class will be constructed from the action name (open and post in the example above) and the suffix "icon" in the same way will be defined the value of title attribute for the button.

The callback isDisplayButtons allows to inform jqGrid about displaying of the buttons based on the data of the row and the rowid. The options parameter is the same options which you knows from custom formatter. options.rowId is the rowid for example. The latest version of free jqGrid (post 4.8) extended the options by including rowData. You can see that the second parameter of isDisplayButtons is already rowData. The main difference between options.rowData and rowData if the format of data. In case of usage XML input rowData parameter is XML item of input data. On the other side the option options.rowData is object with properties like name properties in colModel. Especially in case of usage loadonce: true scenario with XML data the usage of options.rowData have advantages. In the above demo options.rowData and rowData are identical.

The callback isDisplayButtons should return object with the same properties as the action names { post: {...}, open: {...}, del: {...}, edit: {...}, save: {...}, cancel: {} }. The properties of every such object can be

  • hidden: true - means including the button in the column but making it hidden. One can show the button later. The save and cancel buttons are hidden by default.
  • display: false - means don't include the button at all. Returning del: {display: false} for example have the same effect like the option delbutton: false, but del: {display: false} works only for one row.
  • noHovering: true can be used to remove hovering effect (onmouseover="jQuery(this).addClass('ui-state-hover');" onmouseout="jQuery(this).removeClass('ui-state-hover');") from the specified action button.
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thank you. It is working. Is it reasonable to replace lines in loadComplete `row.className = className + ' jqgrid-postedrow not-editable-row'; $(row.cells[iActionsCol]).attr('editable', '0');` with rowattr to remove loop over rows entirely? – Andrus Apr 20 '15 at 21:16
  • I use remote json data. `rowData.closed` is undefined. `options.rowData.closed` contains correct string value True or False so I can use options.rowData.closed – Andrus Apr 20 '15 at 21:22
  • @Andrus: It's definitively reasonable. `rowattr` is always better as the loop in `loadComplete`. I recommend you to read [the answer](http://stackoverflow.com/a/29747090/315935) which I posted recently. It seems to me very close to your last question. – Oleg Apr 20 '15 at 21:25
  • Buttons needs to be defined in two places: inside arrays and in separate two properties. Keeping them is sync is unnessecarilty complicated. Why not to move icon and title properties inside array and use fixed names. In this case button can defined in single place: `{ action: "open", title: "open", icon: "fa-folder-open-o", onClick: function (options) { alert("Open, rowid=" + options.rowid); } },` – Andrus Apr 21 '15 at 05:10
  • Maybe `isDisplayButtons` callback should also made separate for every button and moved into array. This can simplify code if multiple buttons with different display conditions are used. – Andrus Apr 21 '15 at 05:26
  • @Andrus: `isDisplayButtons` allows to hide or remove the standard buttons "Edit", "Delete", "Save", "Cancel" on the row basis. It's the reason why I chosen one `isDisplayButtons` callback. I will thought one more about the best configuration parameters which would be more easy to understand and to use. Thanks for the feedback. – Oleg Apr 21 '15 at 05:32
  • @ReynierPM: Look at https://jsfiddle.net/OlegKi/aw47ytqz/2/ where I added `localReader: { id: "Id" }`, modified the code of `isDisplayButtons` and added the call of `navButtonAdd` at the end of the code. – Oleg Jan 16 '18 at 18:08