bludgeoning dojo grid headerMenu into something as flexible as we need is proving...
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 14 May 2009 00:23:24 +0000 (00:23 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 14 May 2009 00:23:24 +0000 (00:23 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@13157 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/web/js/dojo/openils/widget/GridColumnPicker.js
Open-ILS/web/js/ui/default/vandelay/vandelay.js
Open-ILS/web/templates/default/vandelay/inc/queue.tt2

index 8e6d100..ae1924d 100644 (file)
  */
 
 
-/**
- * Create a new menu that can be used as a grid column picker.  This version
- * takes advantage of Dojo's 1.2 headerMenu attribute for selecting which
- * columns to display.  As columns are chosen, they are updated on the server
- * with user settings.
- */
-
-if(!dojo._hasResource['openils.widget.GridColumnPicker']) {
+if(!dojo._hasResource["openils.widget.GridColumnPicker"]) {
     dojo.provide('openils.widget.GridColumnPicker');
-    dojo.require('dijit.Menu');
-    dojo.require('dojox.widget.PlaceholderMenuItem');
-    dojo.require('fieldmapper.Fieldmapper');
+
+    dojo.require('dijit.Dialog');
+    dojo.require('dijit.form.Button');
+    dojo.require('openils.User');
+    dojo.require('openils.Event');
     dojo.require('openils.Util');
+    dojo.require('fieldmapper.Fieldmapper');
+
+
+    dojo.declare('openils.widget.GridColumnPicker', null, {
+
+        USER_PERSIST_SETTING : 'ui.grid_columns',
+
+        constructor : function (authtoken, persistPrefix, grid, structure) {
+            this.dialog = this.buildDialog();
+            this.grid = grid;
+            this.structure = structure;
+            if(!structure) 
+                this.structure = this.grid.attr('structure');
+            this.dialogTable = this.dialog.domNode.getElementsByTagName('tbody')[0];
+            this.baseCellList = this.structure[0].cells[0].slice();
+            this.build();
+            this.authtoken = authtoken;
+            this.savedColums = null;
+            this.persistPrefix = persistPrefix;
+            this.setting = null;
+
+            var self = this;
+            this.grid.onHeaderContextMenu = function(e) { 
+                self.dialog.show(); 
+                dojo.stopEvent(e);
+            };
+        },
+
+        buildDialog : function() {
+            var self = this;
+            
+            // TODO i18n
+
+            var dialog = new dijit.Dialog({title : 'Column Picker'});
+            var table = dojo.create('table', {'class':'oils-generic-table', innerHTML : 
+                "<thead><tr><th width='33%'>Column</th><th width='33%'>Display</th><th width='33%'>Auto Width</th></tr></thead>" +
+                "<tbody><tr><td><div name='cancel_button'/></td><td><div name='save_button'/></td></tr></tbody></table>" });
+
+            dialog.domNode.appendChild(table);
+
+            var button = new dijit.form.Button({label:'Save'}, dojo.query('[name=save_button]', table)[0]);
+            button.onClick = function() { dialog.hide(); self.update(true); };
+
+            button = new dijit.form.Button({label:'Cancel'}, dojo.query('[name=cancel_button]', table)[0]);
+            button.onClick = function() { dialog.hide(); };
+
+            return dialog;
+        },
+
+        // builds the column-picker dialog table
+        build : function() {
+            var  cells = this._selectableCellList();
+            var str = '';
+            var rows = dojo.query('tr', this.dialogTable);
+
+            for(var i = 0; i < rows.length; i++) {
+                if(rows[i].getAttribute('picker'))
+                    this.dialogTable.removeChild(rows[i]);
+            }
+
+            rows = dojo.query('tr', this.dialogTable);
+            var lastChild = null;
+            if(rows.length > 0)
+                lastChild = rows[rows.length-1];
+
+            for(var i = 0; i < cells.length; i++) {
+                // setting table.innerHTML breaks stuff, so do it the hard way
+                var cell = cells[i];
+                tr = document.createElement('tr');
+                tr.setAttribute('picker', 'picker');
+                td1 = document.createElement('td');
+                td2 = document.createElement('td');
+                td3 = document.createElement('td');
+
+                ipt = document.createElement('input');
+                ipt.setAttribute('type', 'checkbox');
+                ipt.setAttribute('checked', 'checked');
+                ipt.setAttribute('ident', cell.field+''+cell.name);
+                ipt.setAttribute('name', 'selector');
 
-    dojo.declare(
-        'openils.widget.GridColumnPicker',
-        [dijit.Menu],
-        {
-
-            USER_PERSIST_SETTING : 'ui.grid_columns',
-
-            /**
-             * Load the fields from the grid and map them to the MenuItem's.  
-             * Load settings from server
-             */
-            init : function(args) {
-
-                this.grid = args.grid;
-                this.persistPrefix = args.prefix;
-                this.authtoken = args.authtoken;
-                this.cells = this.grid.structure[0].cells[0];
-                var self = this;
-
-                dojo.style(this.grid.domNode.id, 'visibility', 'hidden');
-
-                dojo.forEach(this.getChildren(),
-                    function(child) {
-                        dojo.forEach(self.cells,
-                            function(cell) {
-                                if(cell.name == child.attr('label')) {
-                                    if(cell.nonSelectable) {
-                                        console.log("removing child " + child.attr('label'));
-                                        self.removeChild(child);
-                                    } else {
-                                        child.field = {label:name, ident:cell.field};
-                                    }
-                                    return;
-                                }   
-                            }
-                        )
+                ipt2 = document.createElement('input');
+                ipt2.setAttribute('type', 'checkbox');
+                ipt2.setAttribute('ident', cell.field+''+cell.name);
+                ipt2.setAttribute('name', 'width');
+
+                if(this.setting) {
+                    // set the UI based on the loaded settings
+                    if(this._arrayHas(this.setting.columns, cell.field)) {
+                        if(this._arrayHas(this.setting.auto, cell.field))
+                            ipt2.setAttribute('checked', 'checked');
+                    } else {
+                        ipt.removeAttribute('checked');
                     }
-                );
-                this.load();
-            },
-
-            onClose : function() {
-                this.inherited('onClose',arguments);
-                this.persist();
-            },
-
-            /**
-             * Save new settings on the server
-             */
-            persist : function() {
-                var selected = [];
-                var autoFields = [];
-                dojo.forEach(this.getChildren(),
-                    function(child) {
-                        if(child.checked) {
-                            selected.push(child.field.ident)
+                }
+
+                td1.appendChild(document.createTextNode(cell.name));
+                td2.appendChild(ipt);
+                td3.appendChild(ipt2);
+                tr.appendChild(td1);
+                tr.appendChild(td2);
+                tr.appendChild(td3);
+                if(lastChild)
+                    this.dialogTable.insertBefore(tr, lastChild);
+                else
+                    this.dialogTable.appendChild(tr);
+            }
+        },
+
+        // update the grid based on the items selected in the picker dialog
+        update : function(persist) {
+            var newCellList = [];
+            var rows = dojo.query('[picker=picker]', this.dialogTable);
+
+            for(var j = 0; j < this.baseCellList.length; j++) {
+                var cell = this.baseCellList[j];
+                if(cell.selectableColumn) {
+                    for(var i = 0; i < rows.length; i++) {
+                        var row = rows[i];
+                        var selector = dojo.query('[name=selector]', row)[0];
+                        var width = dojo.query('[name=width]', row)[0];
+                        if(selector.checked && selector.getAttribute('ident') == cell.field+''+cell.name) {
+                            if(width.checked)
+                                cell.width = 'auto';
+                            else delete cell.width;
+                            newCellList.push(cell);
                         }
                     }
-                );
-                var setting = {};
-                setting[this.USER_PERSIST_SETTING+'.'+this.persistPrefix] = {'columns':selected, 'auto':autoFields};
-                fieldmapper.standardRequest(
-                    ['open-ils.actor', 'open-ils.actor.patron.settings.update'],
-                    {   async: true,
-                        params: [this.authtoken, null, setting],
-                        oncomplete: function(r) {
-                            openils.Util.readResponse(r);
-                        }
+                } else { // if it's not selectable, always show it
+                    newCellList.push(cell); 
+                }
+            }
+
+            this.structure[0].cells[0] = newCellList;
+            this.grid.setStructure(this.structure);
+            this.grid.update();
+
+            if(persist) this.persist();
+        },
+
+        _selectableCellList : function() {
+            var cellList = this.structure[0].cells[0];
+            var cells = [];
+            for(var i = 0; i < cellList.length; i++) {
+                var cell = cellList[i];
+                if(!cell.nonSelectable) cell.selectableColumn = true;
+                if(cell.selectableColumn) 
+                    cells.push({name:cell.name, field:cell.field}); 
+            }
+            return cells;
+        },
+
+        // save me as a user setting
+        persist : function() {
+            var cells = this.structure[0].cells[0];
+            var list = [];
+            var autos = [];
+            for(var i = 0; i < cells.length; i++) {
+                var cell = cells[i];
+                if(cell.selectableColumn) {
+                    list.push(cell.field);
+                    if(cell.width == 'auto')
+                        autos.push(cell.field);
+                }
+            }
+            var setting = {};
+            setting[this.USER_PERSIST_SETTING+'.'+this.persistPrefix] = {'columns':list, 'auto':autos};
+            fieldmapper.standardRequest(
+                ['open-ils.actor', 'open-ils.actor.patron.settings.update'],
+                {   async: true,
+                    params: [this.authtoken, null, setting],
+                    oncomplete: function(r) {
+                        var stat = r.recv().content();
+                        if(e = openils.Event.parse(stat))
+                            return alert(e);
                     }
-                );
-            },
-
-            /**
-             * Load existing settings from the server
-             */
-            load : function() {
-                var self = this;
-                fieldmapper.standardRequest(
-                    ['open-ils.actor', 'open-ils.actor.patron.settings.retrieve'],
-                    {   async: true,
-                        params: [this.authtoken, null, this.USER_PERSIST_SETTING+'.'+this.persistPrefix],
-                        oncomplete: function(r) { self._loadCallback(r); }
+                }
+            );
+        }, 
+
+        _arrayHas : function(arr, val) {
+            for(var i = 0; arr && i < arr.length; i++) {
+                if(arr[i] == val)
+                    return true;
+            }
+            return false;
+        },
+
+        _loadColsFromSetting : function(setting) {
+            this.setting = setting;
+            var newCellList = [];
+            for(var j = 0; j < this.baseCellList.length; j++) {
+                var cell = this.baseCellList[j];
+                if(cell.selectableColumn) {
+                    if(this._arrayHas(setting.columns, cell.field)) {
+                        newCellList.push(cell);
+                        if(this._arrayHas(setting.auto, cell.field))
+                            cell.width = 'auto';
+                        else delete cell.width;
                     }
-                );
-            },
-
-            _loadCallback : function(r) {
-                dojo.style(this.grid.domNode.id, 'visibility', 'visible');
-                if(settings = openils.Util.readResponse(r)) {
-                    dojo.forEach(this.getChildren(),
-                        function(child) {
-                            if(child.field) {
-                                if(!openils.Util.arrayContains(settings.columns, child.field.ident)) {
-                                    child.attr("checked", false);
-                                    child.onChange(child.checked);
-                                }
-                            }
-                        }
-                    );
+                }  else { // if it's not selectable, always show it
+                    newCellList.push(cell); 
                 }
-            },
+            }
 
-        } // class def
-    );
+            this.build();
+            this.structure[0].cells[0] = newCellList;
+            this.grid.setStructure(this.structure);
+            this.grid.update();
+        },
+
+        load : function() {
+            if(this.setting)
+                return this._loadColsFromSetting(this.setting);
+            var picker = this;
+            fieldmapper.standardRequest(
+                ['open-ils.actor', 'open-ils.actor.patron.settings.retrieve'],
+                {   async: true,
+                    params: [this.authtoken, null, this.USER_PERSIST_SETTING+'.'+this.persistPrefix],
+                    oncomplete: function(r) {
+                        var set = openils.Util.readResponse(r);
+                        if(set) {
+                            picker._loadColsFromSetting(set);
+                        } else {
+                            picker.build();
+                            picker.grid.setStructure(picker.structure);
+                            picker.grid.update();
+                        }
+                    }
+                }
+            );
+        },
+    });
 }
+
index 347463b..eaa3bdd 100644 (file)
@@ -630,18 +630,15 @@ function buildRecordGrid(type) {
         openils.Util.show('vl-bib-queue-grid-wrapper');
         openils.Util.hide('vl-auth-queue-grid-wrapper');
         vlQueueGrid = vlBibQueueGrid;
-        vlQueueGridMenu = vlBibQueueGridMenu;
     } else {
         openils.Util.show('vl-auth-queue-grid-wrapper');
         openils.Util.hide('vl-bib-queue-grid-wrapper');
         vlQueueGrid = vlAuthQueueGrid;
-        vlQueueGridMenu = vlAuthQueueGridMenu;
     }
 
 
     if(valLastQueueType != type) {
         valLastQueueType = type;
-        //resetVlQueueGridLayout();
         vlQueueGridLayout = vlQueueGrid.attr('structure');
         var defs = (type == 'bib') ? bibAttrDefs : authAttrDefs;
         attrDefMap[type] = {};
@@ -660,7 +657,8 @@ function buildRecordGrid(type) {
 
     dojo.forEach(vlQueueGridLayout[0].cells[0], 
         function(cell) { 
-            if(cell.field.match(/^\+/)) cell.nonSelectable=true;
+            if(cell.field.match(/^\+/)) 
+                cell.nonSelectable=true;
         }
     );
 
@@ -676,14 +674,11 @@ function buildRecordGrid(type) {
     if(vlQueueGridColumePicker[type]) {
         vlQueueGrid.update();
     } else {
-        vlQueueGrid.attr('structure', vlQueueGridLayout);
-        vlQueueGridMenu.init({
-            grid : vlQueueGrid, 
-            authtoken : authtoken, 
-            prefix : 'vandelay.queue.'+type
-        });
-        vlQueueGridMenu.load();
-        vlQueueGridColumePicker[type] = vlQueueGridMenu;
+
+        vlQueueGridColumePicker[type] =
+            new openils.widget.GridColumnPicker(
+                authtoken, 'vandelay.queue.'+type, vlQueueGrid, vlQueueGridLayout);
+        vlQueueGridColumePicker[type].load();
     }
 }
 
index 3e04f95..ed41d6b 100644 (file)
@@ -16,6 +16,7 @@
 
 <!-- queue grid navigation row -->
 <div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
+
     <table width='100%' style='margin-bottom:0px;'>
         <tr>
             <td align='left' valign='bottom'>
@@ -52,7 +53,8 @@
 
                         <span>&vandelay.limit.to.non.imported;</span>
                         <span class='filter_span'>
-                            <input dojoType='dijit.form.CheckBox' jsId='vlQueueGridShowNonImport' checked='checked' onchange='retrieveQueuedRecords();'/>
+                            <input dojoType='dijit.form.CheckBox' jsId='vlQueueGridShowNonImport' 
+                                checked='checked' onchange='retrieveQueuedRecords();'/>
                         </span>
 
                         <span>&vandelay.results.per.page;</span>
     </table>
 </div>
 
+
 <!-- Bib Queue Grid -->
 <div class='' id='vl-bib-queue-grid-wrapper' dojoType='dijit.layout.ContentPane'>
-    <div dojoType="openils.widget.GridColumnPicker" jsid="vlBibQueueGridMenu" style="display: none;" grid='vlBibQueueGrid'>
-        <div dojoType="dojox.widget.PlaceholderMenuItem" label="GridColumns"></div>
-    </div>
-    <table dojoType='dojox.grid.DataGrid' jsId='vlBibQueueGrid' query="{import_time:'*'}" headerMenu='vlBibQueueGridMenu' autoHeight='true' _style='height:600px;'>
+    <table dojoType='dojox.grid.DataGrid' jsId='vlBibQueueGrid' query="{id:'*'}" autoHeight='true'>
         <thead>
             <tr>
                 <th 
 
 <!-- Auth Queue Grid -->
 <div class='' id='vl-auth-queue-grid-wrapper' dojoType='dijit.layout.ContentPane'>
-    <div dojoType="openils.widget.GridColumnPicker" jsid="vlAuthQueueGridMenu" style="display: none;" grid='vlAuthQueueGrid'>
-        <div dojoType="dojox.widget.PlaceholderMenuItem" label="GridColumns"></div>
-    </div>
-    <table dojoType='dojox.grid.DataGrid' jsId='vlAuthQueueGrid' query="{id:'*'}" headerMenu='vlAuthQueueGridMenu'> 
+    <table dojoType='dojox.grid.DataGrid' jsId='vlAuthQueueGrid' query="{id:'*'}"> 
         <thead>
             <tr>
                 <th