]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/dojo/openils/widget/GridColumnPicker.js
bludgeoning dojo grid headerMenu into something as flexible as we need is proving...
[working/Evergreen.git] / Open-ILS / web / js / dojo / openils / widget / GridColumnPicker.js
1 /* ---------------------------------------------------------------------------
2  * Copyright (C) 2008  Georgia Public Library Service
3  * Bill Erickson <erickson@esilibrary.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * ---------------------------------------------------------------------------
15  */
16
17
18 if(!dojo._hasResource["openils.widget.GridColumnPicker"]) {
19     dojo.provide('openils.widget.GridColumnPicker');
20
21     dojo.require('dijit.Dialog');
22     dojo.require('dijit.form.Button');
23     dojo.require('openils.User');
24     dojo.require('openils.Event');
25     dojo.require('openils.Util');
26     dojo.require('fieldmapper.Fieldmapper');
27
28
29     dojo.declare('openils.widget.GridColumnPicker', null, {
30
31         USER_PERSIST_SETTING : 'ui.grid_columns',
32
33         constructor : function (authtoken, persistPrefix, grid, structure) {
34             this.dialog = this.buildDialog();
35             this.grid = grid;
36             this.structure = structure;
37             if(!structure) 
38                 this.structure = this.grid.attr('structure');
39             this.dialogTable = this.dialog.domNode.getElementsByTagName('tbody')[0];
40             this.baseCellList = this.structure[0].cells[0].slice();
41             this.build();
42             this.authtoken = authtoken;
43             this.savedColums = null;
44             this.persistPrefix = persistPrefix;
45             this.setting = null;
46
47             var self = this;
48             this.grid.onHeaderContextMenu = function(e) { 
49                 self.dialog.show(); 
50                 dojo.stopEvent(e);
51             };
52         },
53
54         buildDialog : function() {
55             var self = this;
56             
57             // TODO i18n
58
59             var dialog = new dijit.Dialog({title : 'Column Picker'});
60             var table = dojo.create('table', {'class':'oils-generic-table', innerHTML : 
61                 "<thead><tr><th width='33%'>Column</th><th width='33%'>Display</th><th width='33%'>Auto Width</th></tr></thead>" +
62                 "<tbody><tr><td><div name='cancel_button'/></td><td><div name='save_button'/></td></tr></tbody></table>" });
63
64             dialog.domNode.appendChild(table);
65
66             var button = new dijit.form.Button({label:'Save'}, dojo.query('[name=save_button]', table)[0]);
67             button.onClick = function() { dialog.hide(); self.update(true); };
68
69             button = new dijit.form.Button({label:'Cancel'}, dojo.query('[name=cancel_button]', table)[0]);
70             button.onClick = function() { dialog.hide(); };
71
72             return dialog;
73         },
74
75         // builds the column-picker dialog table
76         build : function() {
77             var  cells = this._selectableCellList();
78             var str = '';
79             var rows = dojo.query('tr', this.dialogTable);
80
81             for(var i = 0; i < rows.length; i++) {
82                 if(rows[i].getAttribute('picker'))
83                     this.dialogTable.removeChild(rows[i]);
84             }
85
86             rows = dojo.query('tr', this.dialogTable);
87             var lastChild = null;
88             if(rows.length > 0)
89                 lastChild = rows[rows.length-1];
90
91             for(var i = 0; i < cells.length; i++) {
92                 // setting table.innerHTML breaks stuff, so do it the hard way
93                 var cell = cells[i];
94                 tr = document.createElement('tr');
95                 tr.setAttribute('picker', 'picker');
96                 td1 = document.createElement('td');
97                 td2 = document.createElement('td');
98                 td3 = document.createElement('td');
99
100                 ipt = document.createElement('input');
101                 ipt.setAttribute('type', 'checkbox');
102                 ipt.setAttribute('checked', 'checked');
103                 ipt.setAttribute('ident', cell.field+''+cell.name);
104                 ipt.setAttribute('name', 'selector');
105
106                 ipt2 = document.createElement('input');
107                 ipt2.setAttribute('type', 'checkbox');
108                 ipt2.setAttribute('ident', cell.field+''+cell.name);
109                 ipt2.setAttribute('name', 'width');
110
111                 if(this.setting) {
112                     // set the UI based on the loaded settings
113                     if(this._arrayHas(this.setting.columns, cell.field)) {
114                         if(this._arrayHas(this.setting.auto, cell.field))
115                             ipt2.setAttribute('checked', 'checked');
116                     } else {
117                         ipt.removeAttribute('checked');
118                     }
119                 }
120
121                 td1.appendChild(document.createTextNode(cell.name));
122                 td2.appendChild(ipt);
123                 td3.appendChild(ipt2);
124                 tr.appendChild(td1);
125                 tr.appendChild(td2);
126                 tr.appendChild(td3);
127                 if(lastChild)
128                     this.dialogTable.insertBefore(tr, lastChild);
129                 else
130                     this.dialogTable.appendChild(tr);
131             }
132         },
133
134         // update the grid based on the items selected in the picker dialog
135         update : function(persist) {
136             var newCellList = [];
137             var rows = dojo.query('[picker=picker]', this.dialogTable);
138
139             for(var j = 0; j < this.baseCellList.length; j++) {
140                 var cell = this.baseCellList[j];
141                 if(cell.selectableColumn) {
142                     for(var i = 0; i < rows.length; i++) {
143                         var row = rows[i];
144                         var selector = dojo.query('[name=selector]', row)[0];
145                         var width = dojo.query('[name=width]', row)[0];
146                         if(selector.checked && selector.getAttribute('ident') == cell.field+''+cell.name) {
147                             if(width.checked)
148                                 cell.width = 'auto';
149                             else delete cell.width;
150                             newCellList.push(cell);
151                         }
152                     }
153                 } else { // if it's not selectable, always show it
154                     newCellList.push(cell); 
155                 }
156             }
157
158             this.structure[0].cells[0] = newCellList;
159             this.grid.setStructure(this.structure);
160             this.grid.update();
161
162             if(persist) this.persist();
163         },
164
165         _selectableCellList : function() {
166             var cellList = this.structure[0].cells[0];
167             var cells = [];
168             for(var i = 0; i < cellList.length; i++) {
169                 var cell = cellList[i];
170                 if(!cell.nonSelectable) cell.selectableColumn = true;
171                 if(cell.selectableColumn) 
172                     cells.push({name:cell.name, field:cell.field}); 
173             }
174             return cells;
175         },
176
177         // save me as a user setting
178         persist : function() {
179             var cells = this.structure[0].cells[0];
180             var list = [];
181             var autos = [];
182             for(var i = 0; i < cells.length; i++) {
183                 var cell = cells[i];
184                 if(cell.selectableColumn) {
185                     list.push(cell.field);
186                     if(cell.width == 'auto')
187                         autos.push(cell.field);
188                 }
189             }
190             var setting = {};
191             setting[this.USER_PERSIST_SETTING+'.'+this.persistPrefix] = {'columns':list, 'auto':autos};
192             fieldmapper.standardRequest(
193                 ['open-ils.actor', 'open-ils.actor.patron.settings.update'],
194                 {   async: true,
195                     params: [this.authtoken, null, setting],
196                     oncomplete: function(r) {
197                         var stat = r.recv().content();
198                         if(e = openils.Event.parse(stat))
199                             return alert(e);
200                     }
201                 }
202             );
203         }, 
204
205         _arrayHas : function(arr, val) {
206             for(var i = 0; arr && i < arr.length; i++) {
207                 if(arr[i] == val)
208                     return true;
209             }
210             return false;
211         },
212
213         _loadColsFromSetting : function(setting) {
214             this.setting = setting;
215             var newCellList = [];
216             for(var j = 0; j < this.baseCellList.length; j++) {
217                 var cell = this.baseCellList[j];
218                 if(cell.selectableColumn) {
219                     if(this._arrayHas(setting.columns, cell.field)) {
220                         newCellList.push(cell);
221                         if(this._arrayHas(setting.auto, cell.field))
222                             cell.width = 'auto';
223                         else delete cell.width;
224                     }
225                 }  else { // if it's not selectable, always show it
226                     newCellList.push(cell); 
227                 }
228             }
229
230             this.build();
231             this.structure[0].cells[0] = newCellList;
232             this.grid.setStructure(this.structure);
233             this.grid.update();
234         },
235
236         load : function() {
237             if(this.setting)
238                 return this._loadColsFromSetting(this.setting);
239             var picker = this;
240             fieldmapper.standardRequest(
241                 ['open-ils.actor', 'open-ils.actor.patron.settings.retrieve'],
242                 {   async: true,
243                     params: [this.authtoken, null, this.USER_PERSIST_SETTING+'.'+this.persistPrefix],
244                     oncomplete: function(r) {
245                         var set = openils.Util.readResponse(r);
246                         if(set) {
247                             picker._loadColsFromSetting(set);
248                         } else {
249                             picker.build();
250                             picker.grid.setStructure(picker.structure);
251                             picker.grid.update();
252                         }
253                     }
254                 }
255             );
256         },
257     });
258 }
259