Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - qcdatabase.com

Pages: [1]
1
I was trying to track down this error so i beautified pqgrid.min.js and saved it as grid.max.js.
When trying to export to CSV, I get the following output to the chrome console:
Uncaught TypeError: Cannot read property 'hidden' of undefined                                                             grid.max.js:10281
    at e.cExport.getCsvHeader (grid.max.js:10281)
    at e.cExport.getCSVContent (grid.max.js:10290)
    at e.cExport.Export (grid.max.js:10150)
    at e.(/app/db/anonymous function).(anonymous function).n.exportData (http://localhost/app/db/paramquery/grid.max.js:10105:18)
    at e.(/app/db/anonymous function).(anonymous function).listener (http://localhost/app/db/grid.php?table=no_pkg_drawings:151:27)
    at HTMLButtonElement.<anonymous> (grid.max.js:6159)
    at HTMLButtonElement.dispatch (jquery-1.9.1.min.js:3)
    at HTMLButtonElement.v.handle (jquery-1.9.1.min.js:3)

// beautified grid.max.js
        },
        getCsvHeader: function(t, e, n, r) {
            for (var i, o, a, l = this, s = [], d = [], c = 0; e > c; c++) {
                for (var u = t[c], h = null, f = 0, p = u.length; p > f; f++) i = n[f], i.hidden || i.copy === !1 || (o = u[f], c > 0 && o == t[c - 1][f] ? s.push("") : h && f > 0 && o == h ? s.push("") : (a = l.getTitle(o, f), a = a ? a.replace(/\"/g, '""') : "", h = o, s.push('"' + a + '"')));
                d.push(s.join(r)), s = []
            }
            return d
        },




This seems like a bug. Here is my export code just in case I am doing something wrong.
// jsZip scripts from the SDK
<script src="paramquery/jsZip-2.5.0/jszip.min.js"></script>
<script src="paramquery/jsZip-2.5.0/fileSaver.js"></script>

// toolbar property/object
toolbar: {
   items: [
      {    type: 'select',
         attr: 'id="export_format"',
         options: [{
                  xlsx: 'Export to Excel',
                  csv: 'Export as CSV',
                  htm: 'Export as HTML',
                  json: 'Export as JSON'}]},
      { type: 'button', label: "Export", icon: 'ui-icon-arrowthickstop-1-s',
         listener: function () {
            $grid.pqGrid("refresh");
            var format = $("#export_format").val(),                           
               blob = this.exportData({
                  format: format,                               
                  render: true
               });
            if(typeof blob === "string"){                           
               blob = new Blob([blob]);
            }
            saveAs(blob, "'.$this->tableTitle.' export."+ format );
         }
      },
      { type: 'separator' },
      { type: "<span class=\"feedback\"></span>" }
   ]
},

2
Thanks for the response. I know it is an unusual ask. If anyone else has this need and is interested, I came up with a script for creating a parallel edit history.  It basically just saves ajax request objects to global undo_array and redo_array. When a user clicks the undo link, the ui.updateList is reversed so that the newRow and oldRow objects are switched with each other. This is done just before submitting them. When they are submitted to the server again from the undo_array, the object is un shifted to the redo_array before newRow and oldRow are switched.

The below script will allow updating all data on every edit and then reversing your changes without affecting the changes made by other users.

// utilities JavaScript file
/* Globals */
var $grid,
   undo_array    = [],
   redo_array    = [];
/* Extensions */
Date.prototype.toDateInputValue = (function() {
    var local = new Date(this);
      local.setMinutes(this.getMinutes() - this.getTimezoneOffset());
    return local.toJSON().slice(0,10);
});
Date.prototype.toTimestamp = (function() {
    var local = new Date(this);
      local.setMinutes(this.getMinutes() - this.getTimezoneOffset());
    return local.toJSON().replace('T',' ').slice(0,19);
});
feed = function(arg = ''){
   $('.feedback').html(arg);
};
undo = function(){
   if(undo_array.length){
      var use_obj      = {},
         shift_obj    = undo_array.shift();          // Pull the last request which was saved to here.
      redo_array.unshift(shift_obj);               // Move it to the redo_array untouched.
      var changes      = JSON.parse(shift_obj.list);   // Open up the stringified list property in order to flip newRow with oldRow properties.
      /* ONLY break down and re-organize list.updateList for now */
      if('updateList' in changes && changes.updateList.length){
         for(var i=0; i<changes.updateList.length; i++){
            if('oldRow' in changes.updateList && 'rowData' in changes.updateList){
               var newRowInfo = JSON.parse(JSON.stringify(changes.updateList.oldRow));
               var oldRowInfo = JSON.parse(JSON.stringify(changes.updateList.oldRow));
               changes.updateList.newRow = oldRowInfo;
               changes.updateList.oldRow = newRowInfo;
            }
         }
      }
      use_obj.table    = JSON.parse(JSON.stringify(shift_obj.table));
      use_obj.par    = JSON.parse(JSON.stringify(shift_obj.par));
      use_obj.list   = JSON.stringify(changes);
      post_to_model(use_obj,true);
      feed('...undoing changes');
   }else{
      feed('No UNDO information found.');
   }
   /*   NOTE:
      FORMAT OF ARG OBJECT AS SUBMITTED TO THIS FUNCTION FROM PAGE SCRIPT.
      CREATE SIMILAR OBJECT FOR UNDO ARRAY. DO NOT UN-COMMENT!
      var send_data = {
         table:    \''.$this->table.'\',
         par:    \''.$this->par.'\',
         list: JSON.stringify({
            updateList: ui.updateList,
            addList:    ui.addList,
            deleteList: ui.deleteList
         })
      };
   */

};
redo = function(){
   if(redo_array.length){
      post_to_model(redo_array.shift(),false,true);
      feed('...redoing');
   }else{
      feed('<span class="ui-icon ui-icon-warning"></span> No REDO information found.');
   }
};
post_to_model = function(arg = {}, is_undo = false){
   $('.undo_link').add('.redo_link').remove();
   var t_name   = $('#t_container').find('input').first().attr('name');
   var t_val   = $('#t_container').find('input').first().val();
   arg[t_name + ""] = t_val;
   arg.autodatetime    = new Date().toTimestamp();

   /* Load changes into undo array */
   if(!is_undo){ // Skip this step if the data submitted to the form is from the undo_array
      var und_obj       = {};
         und_obj.table    = 'table' in arg?    JSON.parse(JSON.stringify(arg.table)):    '';
         und_obj.par    = 'par' in arg?    JSON.parse(JSON.stringify(arg.par)):    '';
         und_obj.list    = JSON.stringify(JSON.parse(arg.list));
         undo_array.unshift(und_obj);
   }
   console.log('undo_array',undo_array);
   console.log('redo_array',redo_array);
   /* END Load undo array */
   
   $.ajax({
      url: 'grid_update.php',
      data: arg,
      dataType: "json",
      type: "POST",
      async: true,
      beforeSend: function (jqXHR, settings) {
         feed('Saving...');
      },
      success: function(feedback){
         $("#grid_container").pqGrid("refreshDataAndView");
         var grid = $grid.pqGrid("getInstance").grid;
         reset_undo_redo();
         feed(feedback.feedback);
      },
      error: function(XMLHttpRequest, textStatus, errorThrown){
         console.log(XMLHttpRequest,"Status: " + textStatus,"Error: " + errorThrown);
      },
      complete: function(){
         /* Global */
         $grid.pqGrid("commit",{type: 'update'});
      }
   });
};
reset_undo_redo = function(){
   var undoer = false, redoer = false;
   if(undo_array.length){
      undoer = $('<a class="undo_link pull-right ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-primary" style="margin-left:20px;"> <span class="ui-button-text">Undo (' + undo_array.length + ')</span></a>');
      undoer.click(undo);
   }
   if(redo_array.length){
      redoer = $('<a class="redo_link pull-right ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-primary" style="margin-left:20px;"> <span class="ui-button-text">Redo (' + redo_array.length + ')</span></a>');
      redoer.click(redo);
   }
   if(redoer){
      $('.pq-toolbar').append(redoer);
   }else{
      $('.pq-toolbar').append('<a class="undo_link pull-right ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-primary" style="margin-left:20px;opacity:0.4;"><span class="ui-button-text">Redo (0)</span></a>');
   }
   if(undoer){
      $('.pq-toolbar').append(undoer);
   }else{
      $('.pq-toolbar').append('<a class="undo_link pull-right ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-primary" style="margin-left:20px;opacity:0.4;"><span class="ui-button-text">Undo (0)</span></a>');
   }
};
$(document).keydown(function(e) {
   js_ticker      = 0;
   switch(e.keyCode){
      /* Z */
      case 90:
            if(e.ctrlKey){
               e.preventDefault();
               $('.undo_link').trigger('click');
            }
         break;
      /* Y */
      case 89:
            if(e.ctrlKey){
               e.preventDefault();
               $('.redo_link').trigger('click');
            }
         break;
      default:;
   }     
});   

// Script

var colModel = [{title: "Job name",dataIndx: "job_name", minWidth: 180, dataType: "stringi"... and so on.
var obj = {
   toolbar: {
      items: [
         {
            type: "<span class=\"feedback\"></span>"
         }
      ]
   },
   create: function(evt, ui) {
      var opts = [];
      for (var i = 0; i < colModel.length; i++) {
         var column = colModel;
         if (column.hidden !== true) {
            opts.push(column.dataIndx);
         }
      }
      $(".columnSelector").val(opts);
   },
   height: 550,
   resizable: true,
   rowBorders: false,
   editor: {
      type: 'textbox'
   },
   virtualX: true,
   editorKeyDown: function(evt, ui) {
      if (evt.keyCode == 13) { //enter key.
         evt.originalEvent.keyCode = 40; //disguise down key.
      }
   },
   numberCell: {
      show: true
   },
   trackModel: {
      on: true
   }, //to turn on the track changes.   
   historyModel: {
      checkEditableAdd: true
   },
   editModel: {
      allowInvalid: true,
      saveKey: $.ui.keyCode.ENTER,
      uponSave: 'next'
   },
   editor: {
      select: true
   },
   title: '<b>Table</b>',
   stripeRows: true,
   change: function(evt, ui) {
      //debugger;
      if (ui.source == 'commit' || ui.source == 'rollback' || !("updateList" in ui)) {
         alert("ERROR: Could not format edit data. Please refresh this page.");
         return;
      }
      if (ui.addList.length || ui.updateList.length || ui.deleteList.length) {
         var send_data = {
            table: 'hydro',
            par: '0',
            list: JSON.stringify({
               updateList: ui.updateList,
               addList: ui.addList,
               deleteList: ui.deleteList
            })
         };
         post_to_model(send_data);
      }
   },
   filterModel: {
      on: true,
      mode: "AND",
      header: true
   },
   colModel: colModel,
   dataModel: {
      location: "remote",
      sorting: "local",
      dataType: "JSON",
      method: "GET",
      rPP: 100000,
      recIndx: "id",
      url: "grid_json.php?table=hydro&par=0",
      getData: function(dataJSON) {
         return {
            data: dataJSON
         };
      }
   },
   load: function(evt, ui) {
      var grid = $grid.pqGrid('getInstance').grid;
      var data = grid.option('dataModel').data;
      $(this).pqTooltip();
      var ret = grid.isValid({
         data: data,
         allowInvalid: false
      });
   },
   refresh: function() {
      $("#grid_container")
         .find("button.delete_btn")
         .button({
            icons: {
               primary: 'ui-icon-scissors'
            }
         })
         .unbind("click")
         .bind("click", function(evt) {
            var $tr = $(this).closest("tr");
            var rowIndx = $grid.pqGrid("getRowIndx", {
               $tr: $tr
            }).rowIndx;
            $grid.pqGrid("deleteRow", {
               rowIndx: rowIndx
            });
         });
   }
};
$(function() {
   $grid = $("#grid_container").pqGrid(obj);
   setTimeout(function() {
      reset_undo_redo();
   }, 0);
});

3
Hello, I just bought the pro version and I love what you guys have built here.

My code below is loosely based on the Inline-editing/Auto-save demo (I simplified it for this post). We will have multiple admins who will be editing this data throughout the workday. I would like the data to be refreshed at each edit to show the work of other users . I also want to preserve the undo/redo functionality.

In my code below I call $("#grid_container").pqGrid("refreshDataAndView"); at each successful update to the data. Under the history: method the console will log the ui object showing num_undo:1 and then immediatly showing num_undo:0. If I comment out the $("#grid_container").pqGrid("refreshDataAndView"); line of code the undo/redo function works perfectly. Am I refreshing the data in the wrong way? Is there a way to have both features?

//FROM CHROME CONSOLE
{type: "add",      canUndo: true,    canRedo: undefined,    num_undo: 1,     num_redo: 0}
{type: "reset",    canUndo:false,    canRedo: false,           num_undo: 0,     num_redo: 0}


//MY CODE
feed = function(arg = "") {
    $('.feedback').html(arg);
};
var $grid,
    colModel = [
        { title: "Job name",dataIndx: "job_name",minWidth: 180,dataType: "stringi"},
        {
            title: "Package name",
            dataIndx: "pkg_name",
            minWidth: 180,
            dataType: "stringi",
            filter: {
                type: "textbox",
                condition: "begin",
                listeners: ["keyup"]
            }
        },
        {title: "type",dataIndx: "pkg_type",minWidth: 36,dataType: "stringi"},
        {title: "Package description",dataIndx: "description",minWidth: 220,dataType: "stringi"]},
        {title: "Spec",dataIndx: "spec",minWidth: 100,dataType: "stringi"]}
    ],
    obj = {
      toolbar: {
          items: [
              {
                  type: 'button',
                  icon: 'ui-icon-arrowreturn-1-s',
                  label: 'Undo',
                  cls: 'changes',
                  listener: {
                      "click": function(evt, ui) {
                          $grid.pqGrid("history", {
                              method: 'undo'
                          });
                      }
                  },
                  options: {
                      disabled: true
                  }
              },
              {
                  type: 'button',
                  icon: 'ui-icon-arrowrefresh-1-s',
                  label: 'Redo',
                  listener: {
                      "click": function(evt, ui) {
                          $grid.pqGrid("history", {
                              method: 'redo'
                          });
                      }
                  },
                  options: {
                      disabled: true
                  }
              },
              {
                  type: 'separator'
              },
              {
                  type: "<span class=\"feedback\"></span>"
              }
          ]
      },
    create: function(evt, ui) {
        var opts = [];
        for (var i = 0; i < colModel.length; i++) {
            var column = colModel;
            if (column.hidden !== true) {
                opts.push(column.dataIndx);
            }
        }
        $(".columnSelector").val(opts);
    },
    height: 550,
    resizable: true,
    editor: {
        type: 'textbox'
    },
    editorKeyDown: function(evt, ui) {
        if (evt.keyCode == 13) {
            evt.originalEvent.keyCode = 40;
        }
    },
    numberCell: {
        show: true
    },
    trackModel: {
        on: true
    }, //to turn on the track changes.   
    historyModel: {
        checkEditableAdd: true
    },
    editModel: {
        allowInvalid: true,
        saveKey: $.ui.keyCode.ENTER,
        uponSave: 'next'
    },
    editor: {
        select: true
    },
    title: "<b>Hydro log</b>",
    change: function(evt, ui) {
        if (ui.source == 'commit' || ui.source == 'rollback' || !("updateList" in ui)) {
            alert("ERROR: Could not format edit data. Please refresh this page.");
            return;
        }
        var grid = $grid.pqGrid('getInstance').grid;
        var t_name = $('#t_container').find('input').first().attr('name');
        var t_val = $('#t_container').find('input').first().val();
        if (ui.addList.length || ui.updateList.length || ui.deleteList.length) {
            var send_data = {
                table: 'hydro',
                par: '0',
                list: JSON.stringify({
                    updateList: ui.updateList,
                    addList: ui.addList,
                    deleteList: ui.deleteList
                })
            };
            send_data[t_name + ""] = t_val;
            $.ajax({
                url: 'grid_update.php',
                data: send_data,
                dataType: "json",
                type: "POST",
                async: true,
                beforeSend: function(jqXHR, settings) {
                    feed('Saving...');
                },
                success: function(feedback) {
                    $("#grid_container").pqGrid("refreshDataAndView"); // If I comment this out, the undo/redo functionality works fine.
                    feed(feedback.feedback);
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    console.log(XMLHttpRequest, "Status: " + textStatus, "Error: " + errorThrown);
                },
                complete: function() {
                    $grid.pqGrid("commit", {
                        type: 'update'
                    });
                }
            });
        }
    },
    history: function(evt, ui) {
        console.log(ui);
        if (ui.canUndo != null) {
            $("button.changes", $grid).button("option", {
                disabled: !ui.canUndo
            });
        }
        if (ui.canRedo != null) {
            $("button:contains('Redo')", $grid).button("option", "disabled", !ui.canRedo);
        }
        $("button:contains('Undo')", $grid).button("option", {
            label: 'Undo (' + ui.num_undo + ')'
        });
        $("button:contains('Redo')", $grid).button("option", {
            label: 'Redo (' + ui.num_redo + ')'
        });
    },
    colModel: colModel,
    dataModel: {
        location: "remote",
        sorting: "local",
        dataType: "JSON",
        method: "GET",
        rPP: 100000,
        recIndx: "id",
        url: "grid_json.php?table=hydro",
        getData: function(dataJSON) {
            return {
                data: dataJSON
            };
        }
    },
    load: function(evt, ui) {
        var grid = $grid.pqGrid('getInstance').grid;
        var data = grid.option('dataModel').data;
        $(this).pqTooltip();
        var ret = grid.isValid({
            data: data,
            allowInvalid: false
        });
    },
    refresh: function() {
        $("#grid_container")
            .find("button.delete_btn")
            .button({
                icons: {
                    primary: 'ui-icon-scissors'
                }
            })
            .unbind("click")
            .bind("click", function(evt) {
                var $tr = $(this).closest("tr");
                var rowIndx = $grid.pqGrid("getRowIndx", {
                    $tr: $tr
                }).rowIndx;
                $grid.pqGrid("deleteRow", {
                    rowIndx: rowIndx
                });
            });
    }
};
$(function() {
    $grid = $("#grid_container").pqGrid(obj);
});

4
That worked. Thanks for the quick response!

5
Hey, You guys did a great job with this grid system. I have tested and/or bought a few others but this is the best one by far.
I had the same issue as user sam.shah. I have the Paramquery Pro evaluation version I downloaded about a week ago. Still learning the API.
Here is my chrome console log and my script for initiating my table (embedded in PHP so ignore the escaped single quotes).
// chrome console log
Uncaught ReferenceError: o is not defined...........................................pqgrid.min.js:4590
    at t.paramquery.cRefresh.onWindowResize (pqgrid.min.js:4590)
    at dispatch (jquery.min.js:3)
    at v.handle (jquery.min.js:3)
    at Object.trigger (jquery.min.js:3)
    at jquery.min.js:4
    at Function.each (jquery.min.js:3)
    at init.each (jquery.min.js:3)
    at init.trigger (jquery.min.js:4)
    at HTMLBodyElement.<anonymous> (pqgrid.min.js:4479)
    at pqgrid.min.js:218

// my script
$(function () {
   $.get(\'grid_json.php\',function(data,status){
      var obj = {
         numberCell:{resizable:true,title:"#",width:30,minWidth:30},
         editable: true,
         editor: {type: \'textbox\'},
         title: "'.$this->tableTitle.'",
         resizable:true,
         virtualX: true,
         virtualY: true,
         hwrap: false,
         wrap: false,
         toolbar: {
            items: [
            {
               type: \'select\',
               label: \'Format: \',               
               attr: \'id="export_format"\',
               options: [{ xlsx: \'Excel\', csv: \'Csv\', htm: \'Html\', json: \'Json\'}]
            },
            {
               type: \'button\',
               label: "Export",
               icon: \'ui-icon-arrowthickstop-1-s\',
               listener: function () {
                  var format = $("#export_format").val(),                           
                     blob = this.exportData({format: format,render: true});
                  if(typeof blob === "string"){                           
                     blob = new Blob([blob]);
                  }
                  saveAs(blob, "QC Database '.$this->tableTitle.' partial export."+ format );
               }
            }]
         },
         filterModel: { on: true, mode: "AND", header: true },
         colModel:  '.$this->colModel.',
         dataModel: {
                     data: JSON.parse(data),
                     location: "remote",
                     sorting: "local",
                     paging: "local",
                     dataType: "JSON",
                     method: "GET",
                     curPage: 1,
                     rPP: 100000,
                     sortIndx: 1,
                     sortDir: "up",
                     getUrl: function () {
                        return { url: "grid_json.php" }
                     },
                     getData: function (dataJSON) {
                        return { data: dataJSON };               
                     }
                  }
      };
      
      /* paramquery init */
      var $grid = $("#grid_container").pqGrid(obj); 
      
   }).always(function(){
      $("#grid_container").pqGrid("refresh");
   });
});

Pages: [1]