Changeset 1809

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

- new rewritten table editor (gdt 0.0.40)

Location:
trunk
Files:
9 modified

Legend:

Unmodified
Added
Removed
  • trunk/application.properties

    r1801 r1809  
    11#Grails Metadata file 
    2 #Thu Apr 28 16:01:26 CEST 2011 
     2#Wed May 04 15:17:10 CEST 2011 
    33app.build.display.info=0 
    44app.build.svn.revision=1079 
     
    1313plugins.db-util=0.4 
    1414plugins.famfamfam=1.0.1 
    15 plugins.gdt=0.0.39 
     15plugins.gdt=0.0.40 
    1616plugins.gdtimporter=0.3.4 
    1717plugins.grom=0.2.2 
  • 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> 
  • trunk/grails-app/views/studyWizard/pages/_assay_groups.gsp

    r1430 r1809  
    6161                </g:each> 
    6262                </div> 
    63                 <div class="sliderContainer"> 
    64                         <div class="slider" ></div> 
    65                 </div> 
    6663        </g:if> 
    6764 
  • trunk/grails-app/views/studyWizard/pages/_assays.gsp

    r1566 r1809  
    5656                        </g:each> 
    5757                        </div> 
    58                         <div class="sliderContainer"> 
    59                                 <div class="slider"></div> 
    60                         </div> 
    6158                </g:each> 
    6259        </g:if> 
  • trunk/grails-app/views/studyWizard/pages/_events.gsp

    r1782 r1809  
    138138                        </g:each> 
    139139                        </div> 
    140                         <div class="sliderContainer"> 
    141                                 <div class="slider"></div> 
    142                         </div> 
    143140                </g:each> 
    144141        </g:if> 
  • trunk/grails-app/views/studyWizard/pages/_groups.gsp

    r1430 r1809  
    7676                </g:each> 
    7777        </div> 
    78         <div class="sliderContainer"> 
    79                 <div class="slider" ></div> 
    80         </div> 
    8178 
    8279</af:page> 
  • trunk/grails-app/views/studyWizard/pages/_samples.gsp

    r1591 r1809  
    8585                </g:each> 
    8686                </div> 
    87                 <div class="sliderContainer"> 
    88                         <div class="slider" ></div> 
    89                 </div> 
    9087                </g:if>  
    9188 
     
    140137                        </g:each> 
    141138                        </div> 
    142                         <div class="sliderContainer"> 
    143                                 <div class="slider" ></div> 
    144                         </div> 
    145139                </g:each> 
    146140        </g:if> 
  • trunk/grails-app/views/studyWizard/pages/_subjects.gsp

    r1793 r1809  
    6060                        </g:each> 
    6161                        </div> 
    62                         <div class="sliderContainer"> 
    63                                 <div class="slider" ></div> 
    64                         </div> 
    6562                </g:each> 
    6663        </g:if> 
  • trunk/web-app/js/studywizard.js

    r1807 r1809  
    2626 
    2727        // handle and initialize table(s) 
    28         /* 
    29         handleWizardTable(); 
    3028        new TableEditor().init({ 
    3129                tableIdentifier : 'div.tableEditor', 
     
    3432                headerIdentifier: 'div.header' 
    3533        }); 
    36         */ 
    3734 
    3835        // initialize the ontology chooser 
     
    158155} 
    159156 
    160 // if the wizard page contains a table, the width of 
    161 // the header and the rows is automatically scaled to 
    162 // the cummalative width of the columns in the header 
    163 function handleWizardTable() { 
    164         var that = this; 
    165         var wizardTables = $('div.tableEditor'); 
    166  
    167         wizardTables.each(function() { 
    168                 var wizardTable = $(this); 
    169                 var sliderContainer = (wizardTable.next().attr('class') == 'sliderContainer') ? wizardTable.next() : null; 
    170                 var header = wizardTable.find('div.header'); 
    171                 var width = 20; 
    172                 var column = 0; 
    173                 var columns = []; 
    174                 var resized = []; 
    175  
    176                 // calculate total width of elements in header 
    177                 header.children().each(function() { 
    178                         // calculate width per column 
    179                         var c = $(this); 
    180                         var columnWidth = c.width(); 
    181                         var paddingWidth = parseInt(c.css("padding-left"), 10) + parseInt(c.css("padding-right"), 10); 
    182                         var marginWidth = parseInt(c.css("margin-left"), 10) + parseInt(c.css("margin-right"), 10); 
    183                         var borderWidth = parseInt(c.css("borderLeftWidth"), 10) + parseInt(c.css("borderRightWidth"), 10); 
    184  
    185                         // add width... 
    186                         if (paddingWidth) columnWidth += paddingWidth; 
    187                         if (marginWidth) columnWidth += marginWidth; 
    188                         if (borderWidth) columnWidth += borderWidth; 
    189                         width += columnWidth; 
    190  
    191                         // remember column 
    192                         resized[ column ] = (c.attr('rel') == 'resized'); 
    193                         columns[ column ] = c.width(); 
    194                         column++; 
    195                 }); 
    196  
    197                 // resize the header 
    198                 header.css({ width: width + 'px' }); 
    199  
    200                 // set table row width and assume column widths are 
    201                 // identical to those in the header (css!) 
    202                 wizardTable.find('div.row').each(function() { 
    203                         var row = $(this); 
    204                         var column = 0; 
    205                         row.children().each(function() { 
    206                                 var child = $(this); 
    207                                 child.css({ width: columns[ column] + 'px' }); 
    208                                 if (resized[ column ]) { 
    209                                         $(':input', child).each(function() { 
    210                                                 $(this).css({width: (columns[ column ] - 10) + 'px'}); 
    211                                         }); 
    212                                 } 
    213                                 column++; 
    214                         }); 
    215                         row.css({ width: width + 'px' }); 
    216                 }); 
    217  
    218                 // got a slider for this table? 
    219                 if (sliderContainer) { 
    220                         // handle slider 
    221                         if (header.width() < wizardTable.width()) { 
    222                                 // no, so hide it 
    223                                 sliderContainer.hide(); 
    224                         } else { 
    225                                 sliderContainer.slider({ 
    226                                         value   : 1, 
    227                                         min      : 1, 
    228                                         max      : header.width() - wizardTable.width(), 
    229                                         step    : 1, 
    230                                         slide: function(event, ui) { 
    231                                                 wizardTable.find('div.header, div.row').css({ 'margin-left': ( 1 - ui.value ) + 'px' }); 
    232                                         } 
    233                                 }); 
    234                         } 
    235                 } 
    236         }); 
    237 } 
    238  
     157// obsolete, left here for backwards compatibility 
     158function handleWizardTable() {} 
    239159 
    240160/*************************************************