root/trunk/grails-app/views/studyWizard/common/_page_header.gsp @ 1808

Revision 1808, 11.9 KB (checked in by work@…, 3 years ago)

- developmental commit of table editor

  • Property svn:keywords set to Rev Author Date
Line 
1<%
2/**
3 * page header template
4 *
5 * This template is actually rendered by the AjaxflowTagLib using
6 * the following tags:
7 *
8 * <af:pageHeader>
9 *
10 * @author Jeroen Wesbeek
11 * @since  20101220
12 *
13 * Revision information:
14 * $Rev$
15 * $Author$
16 * $Date$
17 */
18%>
19<g:hiddenField name="do" value="" />
20<h1><g:if test="${(study && study.getFieldValue('title'))}">${study.title}</g:if><g:else>${pages[page - 1].title}</g:else> (page ${page} of ${pages.size()})</h1>
21<g:render template="common/tabs"/>
22<div class="content">
23<script type="text/javascript">
24function TableEditor() {
25}
26TableEditor.prototype = {
27    options : {
28        tableIdentifier     :   'div.table',
29        headerIdentifier    :   'div.header',
30        rowIdentifier       :   'div.row',
31        columnIdentifier    :   'div.column',
32                initialize                      :       0
33    },
34    tempSelectElement           : null,
35    tempSelectValue                     : '',
36        allSelected                             : false,
37
38    /**
39     * initialize object
40     * @param options
41     */
42    init: function(options) {
43        var that = this;
44
45        // set class parameters
46        if (options) {
47            $.each(options, function(key,value) {
48                that.options[key] = value;
49            });
50        }
51
52        // intitialize tables
53                $(this.options.tableIdentifier).each(function() {
54                        that.initializeTable($(this));
55                });
56    },
57
58        initializeTable: function(table) {
59                var that = this;
60
61                // handle key presses
62                this.attachInputElements(table);
63
64                // Bind table wide mouseclicks (lighter implementation than
65                // binding / unbinding select elements directly)
66                // This only works for mozilla browsers, not for ie and
67                 // webkit based browsers
68                if ($.browser.mozilla) {
69                        table.bind('click', function() {
70                                var element = $('select:focus');
71
72                                // did we select a select element?
73                                if (element.attr('type')) {
74                                        that.tempSelectElement  = element;
75                                        that.tempSelectValue    = $('option:selected',element).val();
76                                }
77                        });
78                        table.bind('mouseup', function() {
79                                var element = $('select:focus');
80                                var type        = element.attr('type');
81
82                                // did we select a select element?
83                                if (type) {
84                                        var column      = element.parent();
85                                        var row         = element.parent().parent();
86                                        var value       = $('option:selected',element).val();
87
88                                        // has the element changed?
89                                        if (that.tempSelectElement && element[0] == that.tempSelectElement[0] && that.tempSelectValue != value) {
90                                                // replicate data
91                                                that.replicateData(table,row,column,type,value);
92                                        }
93                                }
94                        });
95                }
96
97                // initialize selectable
98                table.selectable({
99                        filter: that.options.rowIdentifier,
100                        selected: function(event, ui) {
101                                that.cleanup(table);
102
103                                // on ie and webkit based browsers we need
104                                // to handle mouse clicks differently
105                                if (!$.browser.mozilla) {
106                                        that.attachSelectElementsInRow(table, ui.selected);
107                                }
108                        },
109                        unselected: function(event, ui) {
110                                that.cleanup(table);
111
112                                // on ie and webkit based browsers we need
113                                // to handle mouse clicks differently
114                                if (!$.browser.mozilla) {
115                                        that.detachColumnHandler(ui.unselected);
116                                }
117                        }
118                });
119
120                // add 'select all' buttons
121                this.addSelectAllButton(table);
122
123                // style the table
124                this.resizeTableColumns(table);
125
126                // make sure the header stays in view when scrolling up or down
127                this.keepHeaderInView(table);
128        },
129
130        /**
131         * handle keypresses anywhere inside this table
132         * @param table
133         */
134        attachInputElements: function(table) {
135                var that = this;
136
137                // bind keypresses anywhere in the table in
138                // 1. select elements
139                // 2. input elements
140                table.bind('keyup.tableEditor', function(e) {
141                        var element = $('input:focus,select:focus');
142                        var type        = element.attr('type');
143
144                        if (element.attr('type')) {
145                                var column      = element.parent();
146                                var row         = element.parent().parent();
147                                var value       = element.val();
148
149                                // replicate data
150                                that.replicateData(table,row,column,type,value);
151                        }
152                });
153        },
154
155        /**
156         * attach event handlers for select elements in row
157         * @param table
158         * @param row
159         */
160        attachSelectElementsInRow: function(table, row) {
161                var that = this;
162
163                // iterate through all select elements in the selected rows
164                $('select', row).each(function() {
165                        var element = $(this);
166                        var type        = element.attr('type');
167                        var column      = element.parent();
168                        var row         = element.parent().parent();
169
170                        element.bind('change.tableEditor',function() {
171                                // replicate data
172                                var value = $('option:selected',element).val();
173                                if (value) that.replicateData(table,row,column,type,value);
174                        });
175                });
176        },
177
178        /**
179         * detach event handlers for specific fields in row
180         * @param row
181         */
182        detachColumnHandler: function(row) {
183                $('select', row).each(function() {
184                        // unbind table editor event handlers
185                        $(this).unbind('.tableEditor');
186                });
187        },
188
189        /**
190         * get the column number of a particular column in a row
191         *
192         * @param row
193         * @param column
194         * @return int
195         */
196        getColumnNumber: function(row, column) {
197                var count = 0;
198                var columnNumber = 0;
199
200                // find which column number we are
201                row.children().each(function() {
202                        var childColumn = $(this);
203                        if (childColumn[0] == column[0]) {
204                                columnNumber = count;
205                        }
206                        count++;
207                });
208
209                return columnNumber;
210        },
211
212        /**
213         *
214         */
215        replicateData: function(table, row, column, type, value) {
216                var that                        = this;
217                var columnNumber        = this.getColumnNumber(row, column);
218                var inputSelector       = "";
219
220                // determine inputSelector
221                switch (type) {
222                        case('text'):
223                                inputSelector = 'input';
224                                break;
225                        case('select-one'):
226                                inputSelector = 'select';
227                                break;
228                        default:
229                                inputSelector = 'input';
230                                break;
231                }
232
233                // only replicate if source row is also selected
234                if (row.hasClass('ui-selected') || row.hasClass('table-editor-selected')) {
235                        console.log('replicating column '+columnNumber+' of type '+type+' : '+value);
236
237                        // find selected rows in this table
238                        $('.ui-selected, .table-editor-selected', table).each(function() {
239                                // don't replicate to source row
240                                if ($(this)[0] != row[0]) {
241                                        // find input elements
242                                        $(that.options.columnIdentifier + ':eq(' + (columnNumber-1) + ') ' + inputSelector, $(this)).each(function() {
243                                                // set value
244                                                $(this).val(value);
245                                        });
246                                }
247                        });
248                }
249        },
250
251        /**
252         * insert a select all button in the first column of the header row
253         * @param table
254         */
255        addSelectAllButton: function(table) {
256                var that = this;
257
258        // insert a 'select all' element in the top-left header column
259        var selectAllElement = $($(this.options.headerIdentifier + ':eq(0)', table ).find(':nth-child(1)')[0]);
260        if (selectAllElement) {
261            // set up the selectAll element
262            selectAllElement
263                .addClass('selectAll')
264                .html('&nbsp;&nbsp;&nbsp;')
265                .bind('mousedown',function() {
266                    that.selectAll(table);
267                });
268
269            // add a tooltip
270            selectAllElement.qtip({
271                content: 'leftMiddle',
272                position: {
273                    corner: {
274                        tooltip: 'leftMiddle',
275                        target: 'rightMiddle'
276                    }
277                },
278                style: {
279                    border: {
280                        width: 5,
281                        radius: 10
282                    },
283                    padding: 10,
284                    textAlign: 'center',
285                    tip: true,
286                    name: 'blue'
287                },
288                content: "Click to select all rows in this table",
289                show: 'mouseover',
290                hide: 'mouseout',
291                api: {
292                    beforeShow: function() {
293                        // not used at this moment
294                    }
295                }
296            });
297        }
298        },
299
300    /**
301     * select all rows in the table
302     * @param table
303     */
304        selectAll: function(table) {
305                var that = this;
306
307                // clean up the table
308                this.cleanup(table);
309
310                // select and bind row
311                $(this.options.rowIdentifier, table).each(function() {
312                        var row = $(this);
313                        row.addClass('table-editor-selected');
314
315                        // on ie and webkit based browsers we need
316                        // to handle mouse clicks differently
317                        if (!$.browser.mozilla) {
318                                that.attachSelectElementsInRow(table, row);
319                        }
320                });
321
322                // and set flag
323                this.allSelected = true;
324        },
325
326        /**
327         * check if the table needs cleanup
328         * @param table
329         */
330        cleanup: function(table) {
331                // check if all rows were selected
332                if (this.allSelected) {
333                        // yes, then we need to cleanup. If we only used the jquery-ui
334                        // selector we wouldn't have to do so as it cleans up after
335                        // itself. But as we cannot programatically hook into the selector
336                        // we have to clean up ourselves. Perform a table cleanup and
337                        // unbind every handler.
338                        this.deselectAll(table);
339                }
340        },
341
342    /**
343     * deselect all rows in the table
344     * Note that this conflicts with the jquery selectable, so this is
345     * NOT a user function, merely an 'underwater' function used for
346     * consistency
347     * @param table
348     */
349    deselectAll: function(table) {
350        var that = this;
351
352        // cleanup rows
353        $(this.options.rowIdentifier, table).each(function() {
354            var row = $(this);
355            row.removeClass('table-editor-selected');
356
357                        // on ie and webkit based browsers we need
358                        // to handle mouse clicks differently
359                        if (!$.browser.mozilla) {
360                                that.detachColumnHandler(row);
361                        }
362        });
363
364        // and unset flag
365        this.allSelected = false;
366    },
367
368    /**
369     * resize the table columns so that they lineup properly
370     * @param table
371         */
372    resizeTableColumns: function(table) {
373                var header      = $(this.options.headerIdentifier, table);
374                var width       = 20;           // default column width
375                var column      = 0;
376                var columns     = [];
377                var resized     = [];
378
379                // calculate total width of elements in header
380                header.children().each(function() {
381                        // calculate width per column
382                        var c = $(this);
383
384                        // if a column header contains help icons / helptext, make sure
385                        // to handle them before initializing the table otherwise the
386                        // widths are calculations are off...
387                        var columnWidth = c.outerWidth(true);
388
389            width += columnWidth;
390
391                        // remember column
392                        resized[ column ] = (c.attr('rel') == 'resized');
393                        columns[ column ] = c.width();
394                        column++;
395                });
396
397                console.log(columns);
398
399                // resize the header
400                header.css({ width: width + 'px' });
401
402                // set table row width and assume column widths are
403                // identical to those in the header (css!)
404                $(this.options.rowIdentifier, table).each(function() {
405                        var row = $(this);
406                        var column = 0;
407                        row.children().each(function() {
408                                var child = $(this);
409                                child.css({ width: columns[ column] + 'px' });
410                                if (resized[ column ]) {
411                                        $(':input', child).each(function() {
412                                                $(this).css({width: (columns[ column ] - 10) + 'px'});
413                                        });
414                                }
415                                column++;
416                        });
417                        row.css({ width: width + 'px' });
418                });
419
420                // add sliders?
421                if (header.width() > table.width()) {
422                        // yes, add a top and a bottom slider
423            this.addSlider(table, 'before');
424            this.addSlider(table, 'after');
425                }
426    },
427
428        /**
429         * add a slider to a table (either before or after the table)
430         * @param table
431         * @param location
432         */
433        addSlider: function(table, location) {
434                var that        = this;
435                var header      = $(this.options.headerIdentifier, table);
436                var sliderContainer = $(document.createElement('div'));
437
438                // add to table
439                sliderContainer.addClass('sliderContainer');
440
441                // where?
442                if (location == 'before') {
443                        table.before(sliderContainer);
444                } else {
445                        table.after(sliderContainer);
446                }
447
448                // initialize slider
449                sliderContainer.slider({
450                        value   : 1,
451                        min             : 1,
452                        max             : header.width() - table.width(),
453                        step    : 1,
454                        slide   : function(event, ui) {
455                                $(that.options.headerIdentifier + ', ' + that.options.rowIdentifier, table).css({ 'margin-left': ( 1 - ui.value ) + 'px' });
456                        }
457                });
458        },
459
460        keepHeaderInView: function(table) {
461        $('window').scroll(function() {
462                console.log('scrolling...');
463        });
464        }
465}
466
467attachHelpTooltips();
468new TableEditor().init({
469        tableIdentifier : 'div.tableEditor',
470        rowIdentifier   : 'div.row',
471        columnIdentifier: 'div.column',
472        headerIdentifier: 'div.header'
473});
474</script>
Note: See TracBrowser for help on using the browser.