Show
Ignore:
Timestamp:
04-05-11 15:20:28 (3 years ago)
Author:
work@…
Message:

- new rewritten table editor (gdt 0.0.40)

Files:
1 modified

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>