0

I'm using free-jqgrid 4.9.2 version.

I would like to show the edit form depends on logic from server side. SO i decided to place my logic using beforeShowForm method. But I'm not able to hide/close the edit form.

beforeShowForm method -

 beforeShowForm: function($form) {
   var rowId = jQuery(this).jqGrid('getGridParam', 'selrow');
   var rowData = jQuery(this).getRowData(rowId);
   //CALL SERVER SIDE & TEMPORARY LOGIC FOR NOW
   if (rowData.active == 0) {
     alert("Just diabling the model !");

     //LOGIC TO HIDE/CLOSE THE EDIT FORM ???

     //NOT WORKING - AS IT HIDES THE MODAL, WHEN I CLICK OTHER ROW EARLIER ROW DATA COMING !!
     //var idSelector = $.jgrid.jqID(this.p.id);
     //$.jgrid.hideModal("#FrmGrid_" +idSelector, {gbox: "#gbox_" + idSelector});

     //$form.hide(); NOT WORKING - this makes only form fields hide not complete dialog
     //$('#cData').trigger('click'); - NOT WORKING, WILL not because we are in beforeShowForm and will work in afterShowForm
     //$form.parent().find('#cData').trigger("click"); - NOT WORKING, WILL not because we are in beforeShowForm and will work in afterShowForm
     //jQuery('.ui-jqdialog-titlebar-close').trigger("click"); - WILL CLOSE ALL DIALOG, NOT RECOMMENDED !!
     //return [false,''];
   } else {
     //Don't do anything
   }
 },

Full jqGrid code -

$(document).ready(
  function() {

    /**
     * Initiate i18n bundle
     */
    var localeProp = jQuery.i18n.prop;

    var baseColumnTemplate = {
      width: 120,
      searchoptions: {
        sopt: ['cn', 'eq', 'ne', 'bw', 'bn', 'nc', 'ew', 'en']
      }, //for Search/Filter functionality - specify the search options
      editoptions: {
        edittype: 'text',
        size: 30
      },
      editrules: {
        required: false,
        custom: true,
        custom_func: onlyAlphabetCheck
      }
    }
    var selectColumnTemplate = {
        width: 100,
        stype: "select", //if stype is enabled then sopt will not work - stype is needed only when search should have select option
        edittype: "select",
        formatter: "select"
      }
      /**
       * Application User Details tab
       */
    var $grid = $("#userGrid").jqGrid({
      //sortable: true,//Columns reordering need to be disabled for frozen column working
      //scroll: 1,//true scrolling rows - paging is not working when we enable scrolling. give fixed height then this will go good.. :)
      url: 'list_user_detail',
      datatype: 'json',
      colNames: [localeProp('userdetail.table.column.id'),
        localeProp('userdetail.table.column.username'),
        localeProp('userdetail.table.column.password'),
        localeProp('userdetail.table.column.active'),
        localeProp('userdetail.table.column.firstname'),
        localeProp('userdetail.table.column.lastname'),
        localeProp('userdetail.table.column.department'),
        localeProp('userdetail.table.column.email'),
        localeProp('userdetail.table.column.dob'),
        localeProp('userdetail.table.column.country'),
        localeProp('userdetail.table.column.role'),
        ""
      ],
      cmTemplate: {
        resizable: false,
        align: 'center',
        sortable: true,
        editable: true
      },
      colModel: [{
        name: 'id',
        width: 80,
        sorttype: 'integer',
        searchoptions: {
          sopt: ['eq', 'ne', 'le', 'lt', 'gt', 'ge'] //for filter functionality - specify the search options
        },
        editoptions: {
          readonly: true,
          size: 5
        }
      }, {
        name: "username",
        template: baseColumnTemplate,
        editrules: {
          required: true,
          custom_func: usernameCheck
        },
        formoptions: {
          label: localeProp('userdetail.table.form.label.username')
        }
      }, {
        name: "password",
        template: baseColumnTemplate,
        hidden: true,
        hidedlg: true, //to remove this column from column chooser as well
        //editrules are set as part of form edit validation so we can mark required for all mandatory fields
        editrules: {
          required: true,
          edithidden: true,
          custom_func: passwordCheck
        },
        formoptions: {
          label: localeProp('userdetail.table.form.label.password')
        }
      }, {
        name: "active",
        template: selectColumnTemplate,
        editoptions: {
          value: ":;1:Yes;0:No" //Default 0
        },
        cellattr: function(rowId, val, rawObject) {
          if (val == 1) {
            return " class='ui-state-useractive'";
          } else if (val == 0) {
            return " class='ui-state-userinactive'";
          }
        }
      }, {
        name: "firstname",
        template: baseColumnTemplate

      }, {
        name: "lastname",
        template: baseColumnTemplate

      }, {
        name: "department",
        template: baseColumnTemplate
      }, {
        name: "email",
        template: baseColumnTemplate,
        width: 220,
        editrules: {
          required: true,
          custom_func: emailCheck
        },
        formoptions: {
          label: localeProp('userdetail.table.form.label.email')
        }
      }, {
        name: "birthday",
        width: 120,
        searchoptions: {
          sopt: ['cn', 'eq', 'ne', 'bw', 'bn', 'nc', 'ew', 'en'],
          dataInit: function(e) {
            $(e).datepicker({
              dateFormat: 'dd-mm-yy',
              maxDate: new Date()
            });
          }
        }, //for Search/Filter functionality - specify the search options
        editoptions: {
          size: 10,
          dataInit: function(e) {
            $(e).datepicker({
              dateFormat: 'dd-mm-yy',
              maxDate: new Date()
            });
          }
        }
      }, {
        name: "country",
        template: baseColumnTemplate
      }, {
        name: "role",
        template: selectColumnTemplate,
        editoptions: {
          value: ":;ADMIN:Admin;USER:User" //Default User
        }
      }, {
        name: "oldPassword",
        width: 10,
        hidden: true,
        hidedlg: true //to remove this column from column chooser as well
      }],
      pager: true,
      iconSet: "fontAwesome",
      rowNum: 8,
      rownumbers: false, //Row numbers
      rowList: [8, 12, 20],
      height: 'auto',
      width: 'auto', //Autowidth
      loadonce: true,
      sortable: true,
      sortname: 'No',
      sortorder: 'desc',
      viewrecords: true,
      shrinkToFit: false,
      ignoreCase: true, //Case insensitive search
      gridview: true, //renders data more faster??
      //viewsortcols: true,//easily show what columns are sortable - With this sorting not working.
      caption: localeProp('userdetail.table.caption'),
      editurl: "edit_user_detail",
      multiselect: false,
      toppager: true, //Toolbar option
      cloneToTop: true //Toolbar option

    });

    // Navigator tab inside pager grid
    $grid.jqGrid('navGrid', '#userPager', {
      //General options
      edit: false,
      add: false,
      del: false,
      search: false,
      view: false,
      refresh: false,
      cloneToTop: true //Must for top tool bar - this will close all the pager items in top tool bar.
    });

    /*Search/Filter toolbar*/
    $grid.jqGrid('filterToolbar', {
      searchOperators: true,
      searchOnEnter: false,
      jqModal: false,
      multipleSearch: true,
      multipleGroup: true,
      recreateFilter: true,
      closeOnEscape: true,
      overlay: 0,
      stringResult: true
    });

    //Top Toolbar options & Buttons
    //before adding any buttons remove all the items copied/cloned from the bottom pager
    //TO make sure that buttons are placed in entire grid width
    $("#userGrid_toppager_center,#userGrid_toppager_right").hide();

    //Toolbar button to add a config
    $grid.jqGrid('navButtonAdd', '#userGrid_toppager', {
      caption: localeProp('userdetail.table.button.adduser'),
      title: localeProp('userdetail.table.title.add'),
      buttonicon: 'fa-user-plus',
      onClickButton: function() {
        jQuery(this).jqGrid('editGridRow', "new", {
          //Add options
          height: 'auto',
          width: 'auto',
          modal: true,
          addCaption: localeProp('userdetail.table.button.adduser'),
          processData: localeProp('application.common.message.processing'),
          recreateForm: true,
          reloadAfterSubmit: false,
          closeOnEscape: true,
          bottominfo: localeProp('application.common.message.mandatoryfields'),
          bSubmit: localeProp('application.common.button.save'),
          afterShowForm: function($form) {
            $form.closest(".ui-jqdialog").closest(".ui-jqdialog").position({
              my: 'center',
              at: 'center',
              of: window
            });
          },
          afterSubmit: refreshData, // Need to refresh the data in the table to reflect the primary key added to this table.
          closeAfterAdd: true
        });
      }
    });

    //Toolbar button to edit a config
    $grid.jqGrid('navButtonAdd', '#userGrid_toppager', {
      caption: localeProp('userdetail.table.button.edituser'),
      title: localeProp('userdetail.table.title.edit'),
      buttonicon: 'fa-users',
      onClickButton: function() {
        var gr = jQuery(this).jqGrid('getGridParam', 'selrow');
        if (gr != null)
          jQuery(this).jqGrid('editGridRow', gr, {
            //Edit options
            height: 'auto',
            width: 'auto',
            modal: true,
            editCaption: localeProp('userdetail.table.button.edituser'),
            processData: localeProp('application.common.message.processing'),
            recreateForm: true,
            bottominfo: localeProp('application.common.message.mandatoryfields'),
            bSubmit: localeProp('application.common.button.save'),
            reloadAfterSubmit: false,
            closeOnEscape: true,
            closeAfterEdit: true,
            afterShowForm: function($form) {
              $form.closest(".ui-jqdialog").closest(".ui-jqdialog").position({
                my: 'center',
                at: 'center',
                of: window
              });
            },
            beforeShowForm: function($form) {
              var rowId = jQuery(this).jqGrid('getGridParam', 'selrow');
              var rowData = jQuery(this).getRowData(rowId);
              //CALL SERVER SIDE & TEMPORARY LOGIC FOR NOW
              if (rowData.active == 0) {
                alert("Just diabling the model !");

                //LOGIC TO HIDE/CLOSE THE EDIT FORM ???

                //NOT WORKING - AS IT HIDES THE MODAL, WHEN I CLICK OTHER ROW EARLIER ROW DATA COMING !!
                //var idSelector = $.jgrid.jqID(this.p.id);
                //$.jgrid.hideModal("#FrmGrid_" +idSelector, {gbox: "#gbox_" + idSelector});

                //$form.hide(); NOT WORKING - this makes only form fields hide not complete dialog
                //$('#cData').trigger('click'); - NOT WORKING, WILL not because we are in beforeShowForm and will work in afterShowForm
                //$form.parent().find('#cData').trigger("click"); - NOT WORKING, WILL not because we are in beforeShowForm and will work in afterShowForm
                //jQuery('.ui-jqdialog-titlebar-close').trigger("click"); - WILL CLOSE ALL DIALOG, NOT RECOMMENDED !!
                //return [false,''];
              } else {
                //Don't do anything
              }
            },
            afterSubmit: refreshData // Need to refresh the data in the table to reflect the hashed password
          });
        else {
          $.jgrid.info_dialog.call(
            this,
            localeProp('userdetail.table.dialog.message.caption'), // dialog title
            localeProp('userdetail.table.dialog.message.selectrow'), // text inside of dialog
            localeProp('application.common.button.close'), // text in the button
            {
              left: 500,
              top: 250
            }

          );
        }
      }
    });

    //Toolbar button to delete a user
    $grid.jqGrid('navButtonAdd', '#userGrid_toppager', {
      caption: localeProp('userdetail.table.button.deleteuser'),
      title: localeProp('userdetail.table.title.delete'),
      buttonicon: 'fa-user-times',
      onClickButton: function() {
        var gr = jQuery(this).jqGrid('getGridParam', 'selrow');
        if (gr != null)
          jQuery(this).jqGrid('delGridRow', gr, {
            reloadAfterSubmit: false,
            closeOnEscape: true
          });
        else {
          $.jgrid.info_dialog.call(
            this,
            localeProp('userdetail.table.dialog.message.caption'), // dialog title
            localeProp('userdetail.table.dialog.message.selectrow'), // text inside of dialog
            localeProp('application.common.button.close'), // text in the button
            {
              left: 500,
              top: 250
            }
          );
        }
      }
    });

    //Column chooser button in top toolbar
    $grid.jqGrid('navButtonAdd', '#userGrid_toppager', {
      caption: localeProp('application.common.button.columns'),
      title: localeProp('userdetail.table.title.choosecolumn'),
      buttonicon: 'fa-columns',
      onClickButton: function() {
        jQuery(this).jqGrid('columnChooser');
      }
    });

    //Button to toggle toolbar search/filter option
    $grid.jqGrid('navButtonAdd', "#userGrid_toppager", {
      caption: localeProp('application.common.button.search'),
      title: localeProp('userdetail.table.title.search'),
      buttonicon: 'fa-toggle-on',
      onClickButton: function() {
        $grid[0].toggleToolbar();
      }
    });

    //Refresh Button as auto refresh not exists for user detail
    $grid.jqGrid('navButtonAdd', '#userGrid_toppager', {
      caption: localeProp('application.common.button.refresh'),
      title: localeProp('userdetail.table.title.refreshuserdetail'),
      buttonicon: 'fa fa-cog fa-spin',
      onClickButton: function() {
        refreshData();
      }
    });

    //Frozen columns - NOT needed as of now as no. of columns are limited.
    //$grid.jqGrid('setFrozenColumns');

    //Grid resize
    $grid.jqGrid('gridResize', {
      minWidth: 550,
      maxWidth: 1300,
      minHeight: 80,
      maxHeight: 350
    });

    /**
     * Function to refresh the data after a new row inserted in DB. If
     * not then when we update the same row again, because of no primary
     * key reflected in client side, a fresh row will be inserted. Also
     * if we are refreshing the grid, then immediate delete of this row
     * will fail because again primary key(i.e. id) not reflected in the
     * client side
     *
     * NOT SURE IS THERE ANY OTHER BETTER WAY TO DO THIS !!!!
     */
    function refreshData() {
      $grid.jqGrid("setGridParam", {
        datatype: 'json',
        url: 'list_user_detail',
        page: 1
      }).trigger("reloadGrid");
      return [true, '']; //TO make sure that control goes back to jqGrid inbuild configs like closeafterAdd etc.
    }

    //Username Validation checks !!
    function usernameCheck(value) {
      if (checkLength(value, 6, 50) && checkRegexp(value, /^[a-z]([0-9a-z_.])+$/i)) {
        return [true, "", ""];
      } else {
        return [false, localeProp('userdetail.validation.message.username'), ""];
      }
    }

    //Password Validation checks !!
    function passwordCheck(value) {
      if (checkLength(value, 6, 60)) {
        return [true, "", ""];
      } else {
        return [false, localeProp('userdetail.validation.message.password'), ""];
      }
    }

    //Firstname & Lastname Validation checks !!
    function onlyAlphabetCheck(value) {
      if (checkLength(value, 1, 50) && checkRegexp(value, /^[a-z]([a-z ])+$/i)) {
        return [true, "", ""];
      } else {
        return [false, localeProp('userdetail.validation.message.firstname'), ""];
      }
    }

    //Email Validation checks !!
    function emailCheck(value) {
      if (checkLength(value, 6, 100) && checkRegexp(value, /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i)) {
        return [true, "", ""];
      } else {
        return [false, localeProp('userdetail.validation.message.email'), ""];
      }
    }

    //Birthday Validation checks !!
    function birthdayCheck(value) {
      var now = new Date();
      if (value < now) {
        return [true, "", ""];
      } else {
        return [false, localeProp('userdetail.validation.message.dob'), ""];
      }
    }

    /*Check length of particular field*/
    function checkLength(o, min, max) {
      if (o.length > max || o.length < min) {
        return false;
      } else {
        return true;
      }
    }

    /*Check regex/format of particular field*/
    function checkRegexp(o, regexp) {
      if (!(regexp.test(o))) {
        return false;
      } else {
        return true;
      }
    }


  });
Sundar
  • 119
  • 1
  • 16

1 Answers1

1

First of all jqGrid call beforeShowForm before the edit for mill be shown and it shows the for directly before the call of beforeShowForm. If means that calling of $.jgrid.hideModal inside of beforeShowForm is too early. Instead of that one can do this inside of afterShowForm callback.

I looked through the code which you posted and it seems to me that neither hiding of the form inside of beforeShowForm nor inside of afterShowForm callback would be the best choice. What you currently do is the calling of navGrid with edit: false and add: false options. You add "Add" and "Edit" buttons later and you calls editGridRow directly inside of onClickButton directly after getting id of selected row.

Thus I suggest you to move the logic with closing the form in onClickButton callback. It's better to test that the selected row corresponds all your custom criteria (active !== 0) and call editGridRow only in the case. It will make closing of add/edit form unneeded.

One more implementation idea you can find in the old answer and in this one. What you can do is hiding or disabling the "Add" or "Edit" buttons based on your custom criteria. For example one can implement onSelectRow callback which enable/disables/hide/show the "Add" or "Edit" based on the value from active column. If no row is selected then Edit/Delete buttons could be disabled or hidden. To simplify working with the buttons I would recommend you to assign id to very button by using id option of navButtonAdd.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Many thanks Oleg.. your feedback is valid. It's my stupidity that i didn't thought about that. On your other idea.. yes I checked that as well .. and will practice that as well sometime this week. My aim is to implement locking of order in 2 ways and give a configuration to choose what customer want. 1. Preventing the edit form not available if a row is locked.. and 2nd one implement concurrency locking with row-version as you suggested in an another post. – Sundar Oct 05 '15 at 10:33