]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/fm_table.js
1e6891d92abb46abb10c23cc941c52db523f9349
[Evergreen.git] / Open-ILS / web / opac / common / js / fm_table.js
1 /* 
2         Fieldmapper object table
3 */
4
5 var ID_GEN = 1;
6
7
8
9 function drawFMObjectTable( args ) {
10
11         var destination = args.dest;
12         var obj = args.obj;
13
14         if( typeof destination == 'string' ) 
15                 destination = $(destination);
16         var builder = new FMObjectBuilder(obj, args);
17
18         destination.appendChild(builder.build());
19         return builder;
20 }
21
22
23 /* Constructor for the builder object */
24 function FMObjectBuilder( obj, args ) {
25         this.obj                = obj;
26         this.table      = elem('table');
27         this.thead      = elem('thead');
28         this.tbody      = elem('tbody');
29         this.thead_tr = elem('tr');
30         this.subtables = [];
31         this.display = args.display;
32         this.selectCol = args.selectCol;
33         this.selectColName = args.selectColName;
34         this.selectAllName = args.selectAllName;
35         this.selectNoneName = args.selectNoneName;
36         this.rows = [];
37         if(!this.display) this.display = {};
38
39         this.table.appendChild(this.thead);
40         this.table.appendChild(this.tbody);
41         this.thead.appendChild(this.thead_tr)
42
43         addCSSClass(this.table, 'fm_table');
44         addCSSClass(this.table, 'sortable');
45         this.table.id = 'fm_table_' + (ID_GEN++);
46 }
47
48
49 FMObjectBuilder.prototype.getSelected = function() {
50         var objs = [];
51         for( var i = 0; i < this.rows.length; i++ ) {
52                 var r = $(this.rows[i]);
53                 if( $n(r,'selected') && $n(r,'selected').checked )
54                         objs.push(this.obj[i]);
55         }
56         return objs;
57 }
58
59 /* Builds the table */
60 FMObjectBuilder.prototype.build = function() {
61         var o = this.obj;
62
63         if( instanceOf(this.obj, Array) ) 
64                 o = this.obj[0];
65         else this.obj = [this.obj];
66
67         if( o ) {
68
69                 this.setKeys(o);
70                 if( this.selectCol ) {
71                         var obj = this;
72                         var td = elem('td',null,this.selectColName);
73
74                         var all = elem('a',{href:'javascript:void(0);','class':'fm_select_link' }, this.selectAllName);
75                         var none = elem('a',{href:'javascript:void(0);', 'class':'fm_select_link'}, this.selectNoneName);
76
77                         all.onclick = function(){obj.selectAll()};
78                         none.onclick = function(){obj.selectNone()};
79
80                         td.appendChild(all);
81                         td.appendChild(none);
82                         this.thead_tr.appendChild(td);
83                 }
84                 for( var i = 0; i < this.keys.length; i++ ) 
85                         this.thead_tr.appendChild(elem('td',null,this.keys[i]));
86         
87                 for( var i = 0; i < this.obj.length; i++ ) 
88                         this.buildObjectRow(this.obj[i]);
89         }
90
91         return this.table;
92 }
93
94
95 FMObjectBuilder.prototype.selectAll = function() {
96         for( var i = 0; i < this.rows.length; i++ ) {
97                 var r = $(this.rows[i]);
98                 $n(r,'selected').checked = true;
99         }
100 }
101
102 FMObjectBuilder.prototype.selectNone = function() {
103         for( var i = 0; i < this.rows.length; i++ ) {
104                 var r = $(this.rows[i]);
105                 $n(r,'selected').checked = false;
106         }
107 }
108
109
110 /* */
111 FMObjectBuilder.prototype.setKeys = function(o) {
112         var sortme = false;
113         if( this.display[o.classname] ) {
114                 this.keys = this.display[o.classname].fields;
115                 this.bold = this.display[o.classname].bold;
116         }
117
118         if(!this.keys && FM_TABLE_DISPLAY[o.classname])
119                 this.keys = FM_TABLE_DISPLAY[o.classname].fields;
120
121         if(!this.bold && FM_TABLE_DISPLAY[o.classname])
122                 this.bold = FM_TABLE_DISPLAY[o.classname].bold;
123
124         if(!this.keys) {
125                 this.keys = fmclasses[o.classname];
126                 sortme = true;
127         }
128
129         if(sortme) this.keys = this.keys.sort();
130 }
131
132 /* use this method to insert object rows after the table has been rendered */
133 FMObjectBuilder.prototype.add = function(obj) {
134         this.obj.push(obj);
135         this.buildObjectRow(obj);
136 }
137
138 /* Inserts one row into the table to represent a single object */
139 FMObjectBuilder.prototype.buildObjectRow = function(obj) {
140         var row = elem('tr');
141         row.id = 'fm_table_' + (ID_GEN++);
142         this.rows.push(row.id);
143
144         if(this.selectCol) {
145                 var td = elem('td');
146                 td.appendChild(elem('input',{type:'checkbox',name:'selected'}));
147                 row.appendChild(td);
148         }
149
150         for( var i = 0; i < this.keys.length; i++ ) {
151                 var td = elem('td');    
152                 var data = obj[this.keys[i]]();
153                 data = this.munge(data);
154                 this.fleshData(td, data, this.keys[i]);
155                 row.appendChild(td);
156         }
157         this.tbody.appendChild(row);
158 }
159
160 FMObjectBuilder.prototype.munge = function(data) {
161         if(!data) return;
162         if(typeof data == 'string') {
163                 if( data.match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/) ) {
164                         data = data.replace(/T/,' ');
165                         data = data.replace(/:\d{2}-.*/,'');
166                 }
167         }
168         return data;
169 }
170
171
172 FMObjectBuilder.prototype.dataName = function(data) {
173         var name;
174         if( this.display[data.classname] ) 
175                 name = this.display[data.classname].name;
176
177         if(!name && FM_TABLE_DISPLAY[data.classname])
178                 name = FM_TABLE_DISPLAY[data.classname].name;
179
180         if(!name) name = 'id';
181
182         return data[name]();
183         return name;
184 }
185
186
187 FMObjectBuilder.prototype.fleshData = function(td, data, key) {
188         if(data == null) data = '';
189
190         if( typeof data == 'object' ) {
191                 var atext;
192
193                 if( data._isfieldmapper ) 
194                         atext = this.dataName(data);
195
196                 else if (instanceOf(data, Array) )
197                         atext = data.length;
198
199                 if( atext ) {
200
201                         var master = this;
202                         var expand = function () { 
203                                 var buildme = true;
204                                 var row = td.parentNode.nextSibling;
205                                 if( row && row.getAttribute('subrow') == key) buildme = false;
206                                 master.hideSubTables();
207                                 if(buildme) master.buildSubTable(td, data, key);
208                         };
209
210                         var a = elem('a',{href:'javascript:void(0);'});
211                         a.onclick = expand;
212                         a.appendChild(text(atext));
213                         td.appendChild(a);
214
215                 } else {
216                         td.appendChild(text(''));
217                 }
218
219         } else {
220                 if( this.bold && grep(this.bold,function(i){return (i==key)}) ) {
221                         var span = elem('span',{'class':'fm_table_bold'}, data);
222                         td.appendChild(span);
223                 } else {
224                         td.appendChild(text( data ));
225                 }
226         }
227 }
228
229 FMObjectBuilder.prototype.hideSubTables = function() {
230
231         /* clear out any existing subrows */
232         for( var i = 0; i < this.tbody.childNodes.length; i++ ) {
233                 var r = this.tbody.childNodes[i];
234                 if( r.getAttribute('subrow') )
235                         this.tbody.removeChild(r);
236         }
237
238         /* un-style any selected tds */
239         var tds = this.tbody.getElementsByTagName('td');
240         for( i = 0; i < tds.length; i++ )
241                 removeCSSClass( tds[i], 'fm_selected' );
242 }
243
244 FMObjectBuilder.prototype.buildSubTable = function(td, obj, key) {
245
246         var left = parseInt(td.offsetLeft);
247         var div = elem('div');
248         var row = elem('tr');
249         var subtd= elem('td');
250
251         if( td.parentNode.nextSibling ) 
252                 this.tbody.insertBefore(row, td.parentNode.nextSibling);
253         else
254                 this.tbody.appendChild(row);
255
256         row.appendChild(subtd);
257         row.setAttribute('subrow', key);
258         subtd.appendChild(div);
259
260         addCSSClass(td, 'fm_selected');
261         subtd.setAttribute('colspan',this.keys.length);
262         if(this.selectCol)
263                 subtd.setAttribute('colspan',this.keys.length + 1);
264
265         subtd.setAttribute('style', 'width: 100%; padding-left:'+left+'px;');
266         var builder = drawFMObjectTable({dest:div, obj:obj, display:this.display});
267         builder.table.setAttribute('style', 'width: auto;');
268         addCSSClass(builder.table, 'fm_selected');
269
270         var newleft = left - (builder.table.clientWidth / 2) + (td.clientWidth / 2);
271
272         if( newleft < left ) {
273                 if( newleft < 0 ) newleft = 0;
274                 newleft = parseInt(newleft);
275                 var style = subtd.getAttribute('style');
276                 style = style.replace(new RegExp(left), newleft);
277                 subtd.setAttribute('style', style);
278         }
279 }
280
281
282
283