Ignore:
Timestamp:
May 4, 2011, 3:20:28 PM (6 years ago)
Author:
work@…
Message:
  • new rewritten table editor (gdt 0.0.40)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/views/studyWizard/common/_page_header.gsp

    r1808 r1809  
    2121<g:render template="common/tabs"/>
    2222<div class="content">
    23 <script type="text/javascript">
    24 function TableEditor() {
    25 }
    26 TableEditor.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 
    467 attachHelpTooltips();
    468 new TableEditor().init({
    469         tableIdentifier : 'div.tableEditor',
    470         rowIdentifier   : 'div.row',
    471         columnIdentifier: 'div.column',
    472         headerIdentifier: 'div.header'
    473 });
    474 </script>
Note: See TracChangeset for help on using the changeset viewer.