www/include/scripts/table.js

Code
Comments
Other
Rev Date Author Line
2306 22 May 06 jari 1 /* $Id$
417 19 Apr 05 nicklas 2   ------------------------------------------------------------------
3675 16 Aug 07 jari 3   Copyright (C) 2005 Nicklas Nordborg
4889 06 Apr 09 nicklas 4   Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg, Martin Svensson, Gregory Vincic
3675 16 Aug 07 jari 5   Copyright (C) 2007 Johan Enell, Nicklas Nordborg
417 19 Apr 05 nicklas 6
2304 22 May 06 jari 7   This file is part of BASE - BioArray Software Environment.
2304 22 May 06 jari 8   Available at http://base.thep.lu.se/
417 19 Apr 05 nicklas 9
417 19 Apr 05 nicklas 10   BASE is free software; you can redistribute it and/or
417 19 Apr 05 nicklas 11   modify it under the terms of the GNU General Public License
4476 05 Sep 08 jari 12   as published by the Free Software Foundation; either version 3
417 19 Apr 05 nicklas 13   of the License, or (at your option) any later version.
417 19 Apr 05 nicklas 14
417 19 Apr 05 nicklas 15   BASE is distributed in the hope that it will be useful,
417 19 Apr 05 nicklas 16   but WITHOUT ANY WARRANTY; without even the implied warranty of
417 19 Apr 05 nicklas 17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
417 19 Apr 05 nicklas 18   GNU General Public License for more details.
417 19 Apr 05 nicklas 19
417 19 Apr 05 nicklas 20   You should have received a copy of the GNU General Public License
4510 11 Sep 08 jari 21   along with BASE. If not, see <http://www.gnu.org/licenses/>.
417 19 Apr 05 nicklas 22   ------------------------------------------------------------------
417 19 Apr 05 nicklas 23
417 19 Apr 05 nicklas 24   JavaScript functions for the Table taglib.
417 19 Apr 05 nicklas 25
417 19 Apr 05 nicklas 26   @author Nicklas
417 19 Apr 05 nicklas 27   @version 2.0
417 19 Apr 05 nicklas 28 */
7419 03 Nov 17 nicklas 29 'use strict';
7419 03 Nov 17 nicklas 30
6182 23 Oct 12 nicklas 31 var Table = function()
417 19 Apr 05 nicklas 32 {
6183 24 Oct 12 nicklas 33   // Hold parsed column definitions -- initialized lazily when Table.getColumnDefs is called
6183 24 Oct 12 nicklas 34   var columnDefs = [];
417 19 Apr 05 nicklas 35
6182 23 Oct 12 nicklas 36   var table = {};
6182 23 Oct 12 nicklas 37   var internal = {};
6182 23 Oct 12 nicklas 38   
417 19 Apr 05 nicklas 39   /**
6182 23 Oct 12 nicklas 40     Initialize all control elements in the table, such as
6182 23 Oct 12 nicklas 41     sorting, filtering, pageing, etc.
6182 23 Oct 12 nicklas 42   */
6182 23 Oct 12 nicklas 43   internal.initTable = function(element, autoInit)
6182 23 Oct 12 nicklas 44   {
6182 23 Oct 12 nicklas 45     if (autoInit != 'table') return;
6182 23 Oct 12 nicklas 46     var tableId = element.id;
6182 23 Oct 12 nicklas 47     var tableFrm = document.forms[tableId];
6220 10 Jan 13 nicklas 48     var itemType = Data.get(element, 'item-type');
6220 10 Jan 13 nicklas 49     var attributes = {'table-id': tableId, 'item-type': itemType};
6182 23 Oct 12 nicklas 50     
7894 08 Dec 20 nicklas 51     // Set flag to enable 'please wait...' overlay if re-loading takes time
7894 08 Dec 20 nicklas 52     Data.set(tableFrm, 'enable-please-wait', 1000); // Display a message after 1s
7894 08 Dec 20 nicklas 53     
6182 23 Oct 12 nicklas 54     // Add 'click' handler to page navigator
6182 23 Oct 12 nicklas 55     // A single handler is added to the main div and relies 
6182 23 Oct 12 nicklas 56     // on event bubbling from the actual targets
6183 24 Oct 12 nicklas 57     var navigator = element.getElementsByClassName('table-navigator');
6183 24 Oct 12 nicklas 58     for (var i = 0; i < navigator.length; i++)
6183 24 Oct 12 nicklas 59     {
6183 24 Oct 12 nicklas 60       Events.addEventHandler(navigator[i], 'click', Table.navigatorOnClick);
6183 24 Oct 12 nicklas 61     }
6182 23 Oct 12 nicklas 62     
6182 23 Oct 12 nicklas 63     // Limit the 'rowsperpage' field to numbers and submit the form if ENTER is pressed
6182 23 Oct 12 nicklas 64     var rowsPerPage = tableFrm.rowsperpage;
6197 02 Nov 12 nicklas 65     if (rowsPerPage)
6197 02 Nov 12 nicklas 66     {
6197 02 Nov 12 nicklas 67       Events.addEventHandler(rowsPerPage, 'keypress', Events.integerOnly);
6197 02 Nov 12 nicklas 68       Events.doOnEnter(rowsPerPage, Forms.submit);
6197 02 Nov 12 nicklas 69     }
6182 23 Oct 12 nicklas 70     
6182 23 Oct 12 nicklas 71     // Add event handler for the 'view/preset' selection list
6183 24 Oct 12 nicklas 72     // and icons for clearing the filter and show hidden columns with a filter
6197 02 Nov 12 nicklas 73     if (tableFrm.presetselector)
6197 02 Nov 12 nicklas 74     {
6220 10 Jan 13 nicklas 75       Events.addEventHandler(tableFrm.presetselector, 'change', table.presetOnChange);
6220 10 Jan 13 nicklas 76       Events.addEventHandler(tableId+'.clearfilter', 'click', table.clearFilterOnClick, attributes);
6220 10 Jan 13 nicklas 77       Events.addEventHandler(tableId+'.showcolumns', 'click', table.showColumnsOnClick, attributes);
6197 02 Nov 12 nicklas 78     }
6182 23 Oct 12 nicklas 79     
6182 23 Oct 12 nicklas 80     // Add 'click' handlers to column headers for sorting
6182 23 Oct 12 nicklas 81     var sort = element.getElementsByClassName('table-sort');
6182 23 Oct 12 nicklas 82     for (var i = 0; i < sort.length; i++)
6182 23 Oct 12 nicklas 83     {
6220 10 Jan 13 nicklas 84       Events.addEventHandler(sort[i], 'click', table.sortOnClick, attributes);
6182 23 Oct 12 nicklas 85     }
6182 23 Oct 12 nicklas 86     
7083 01 Mar 16 nicklas 87     // Add 'drag-drop' handlers for moving columns
7083 01 Mar 16 nicklas 88     var cols = element.getElementsByClassName('table-col-draggable');
7083 01 Mar 16 nicklas 89     for (var i = 0; i < cols.length; i++)
7083 01 Mar 16 nicklas 90     {
7083 01 Mar 16 nicklas 91       var dropTarget = cols[i];
7083 01 Mar 16 nicklas 92       Data.set(dropTarget, 'column-index', i);
7083 01 Mar 16 nicklas 93       Events.addEventHandler(dropTarget, 'dragstart', table.beginColumnDrag, attributes);
7083 01 Mar 16 nicklas 94       Events.addEventHandler(dropTarget, 'dragover', table.checkColumnDropTarget);
7083 01 Mar 16 nicklas 95       Events.addEventHandler(dropTarget, 'dragleave', table.leaveColumnDropTarget);
7083 01 Mar 16 nicklas 96       Events.addEventHandler(dropTarget, 'drop', table.columnDropped);
7083 01 Mar 16 nicklas 97       Events.addEventHandler(dropTarget, 'dragend', table.endColumnDrag);
7085 02 Mar 16 nicklas 98       
7085 02 Mar 16 nicklas 99       // Right-clicking should bring up a menu with selection of columns
7085 02 Mar 16 nicklas 100       Events.addEventHandler(dropTarget, 'mouseup', table.showColumnSelectionMenu);
7085 02 Mar 16 nicklas 101       Events.addEventHandler(dropTarget, 'contextmenu', table.showColumnSelectionMenu);
7083 01 Mar 16 nicklas 102     }
7083 01 Mar 16 nicklas 103     
7084 01 Mar 16 nicklas 104     // Add 'hide column' handler to column headers
7084 01 Mar 16 nicklas 105     var cols = element.getElementsByClassName('table-col-hide');
7084 01 Mar 16 nicklas 106     for (var i = 0; i < cols.length; i++)
7084 01 Mar 16 nicklas 107     {
7084 01 Mar 16 nicklas 108       Events.addEventHandler(cols[i], 'click', table.hideColumnOnClick, attributes);
7084 01 Mar 16 nicklas 109     }
7084 01 Mar 16 nicklas 110     
6182 23 Oct 12 nicklas 111     // Submit form when clicked or ENTER is pressed 
6182 23 Oct 12 nicklas 112     var submit = element.getElementsByClassName('table-submit');
6182 23 Oct 12 nicklas 113     for (var i = 0; i < submit.length; i++)
6182 23 Oct 12 nicklas 114     {
6182 23 Oct 12 nicklas 115       var field = submit[i];
6182 23 Oct 12 nicklas 116       var type = field.type;
6182 23 Oct 12 nicklas 117       if (type == 'radio' || type == 'checkbox')
6182 23 Oct 12 nicklas 118       {
6182 23 Oct 12 nicklas 119         // Radio and checkboxes react to 'click'
7892 07 Dec 20 nicklas 120         Events.addEventHandler(field, 'click', Forms.submit);
6182 23 Oct 12 nicklas 121       }
6182 23 Oct 12 nicklas 122       else if (type == 'text')
6182 23 Oct 12 nicklas 123       {
6182 23 Oct 12 nicklas 124         // Text fields react to ENTER key
7892 07 Dec 20 nicklas 125         Events.doOnEnter(field, Forms.submit);
6182 23 Oct 12 nicklas 126       }
6182 23 Oct 12 nicklas 127       else if (type == 'select-one')
6182 23 Oct 12 nicklas 128       {
6182 23 Oct 12 nicklas 129         // Selection list react to 'onchange'
7892 07 Dec 20 nicklas 130         Events.addEventHandler(field, 'change', Forms.submit);
6182 23 Oct 12 nicklas 131       }
6182 23 Oct 12 nicklas 132     }
6220 10 Jan 13 nicklas 133     
6834 08 Apr 15 nicklas 134     // Add 'click' handler to the 'Toggle all' icon
6834 08 Apr 15 nicklas 135     var tableCheck = element.getElementsByClassName('table-check');
6834 08 Apr 15 nicklas 136     for (var i = 0; i < tableCheck.length; i++)
6834 08 Apr 15 nicklas 137     {
6834 08 Apr 15 nicklas 138       Buttons.addClickHandler(tableCheck[i], table.checkUncheckOnClick, attributes);
6834 08 Apr 15 nicklas 139       if (i == 0) element.tableCheck = tableCheck[i];
6834 08 Apr 15 nicklas 140     }
6220 10 Jan 13 nicklas 141     
6697 29 Jan 15 nicklas 142     // Add 'click' handler to the 'Add filter row' and 'Remove filter rows' icons
6699 30 Jan 15 nicklas 143     var filterRowActions = element.getElementsByClassName('table-filter-row-action');
6699 30 Jan 15 nicklas 144     for (var i = 0; i < filterRowActions.length; i++)
6697 29 Jan 15 nicklas 145     {
6699 30 Jan 15 nicklas 146       Buttons.addClickHandler(filterRowActions[i], table.filterRowActionOnClick, attributes);
6697 29 Jan 15 nicklas 147     }
6697 29 Jan 15 nicklas 148     
6220 10 Jan 13 nicklas 149     // Add 'click' handlers to all main table items
6220 10 Jan 13 nicklas 150     // This must be different from the regular item click handler
6220 10 Jan 13 nicklas 151     // since we must also support returning selected items from a
6220 10 Jan 13 nicklas 152     // popup dialog (the regular click handler only supports navigating
6220 10 Jan 13 nicklas 153     // to the 'view' or 'edit' page.
6220 10 Jan 13 nicklas 154     var items = element.getElementsByClassName('table-item');
6220 10 Jan 13 nicklas 155     for (var i = 0; i < items.length; i++)
6220 10 Jan 13 nicklas 156     {
6220 10 Jan 13 nicklas 157       var item = items[i];
6220 10 Jan 13 nicklas 158       Buttons.addClickHandler(item, table.mainItemOnClick, attributes);
6220 10 Jan 13 nicklas 159     }
6220 10 Jan 13 nicklas 160     
6220 10 Jan 13 nicklas 161     // Add 'click' handler to all 'Marked for removal' trashcan icons
6220 10 Jan 13 nicklas 162     // This will delete the clicked item permanently
6220 10 Jan 13 nicklas 163     var items = element.getElementsByClassName('table-delete-item');
6220 10 Jan 13 nicklas 164     for (var i = 0; i < items.length; i++)
6220 10 Jan 13 nicklas 165     {
6220 10 Jan 13 nicklas 166       var item = items[i];
6220 10 Jan 13 nicklas 167       Buttons.addClickHandler(item, Buttons.deleteItemPermanently, attributes);
6220 10 Jan 13 nicklas 168     }
6221 10 Jan 13 nicklas 169
6221 10 Jan 13 nicklas 170     // Add 'click' handler to all 'Shared item' icons
6221 10 Jan 13 nicklas 171     // This will open the Share popup dialog 
6221 10 Jan 13 nicklas 172     var items = element.getElementsByClassName('table-share-item');
6221 10 Jan 13 nicklas 173     for (var i = 0; i < items.length; i++)
6221 10 Jan 13 nicklas 174     {
6221 10 Jan 13 nicklas 175       var item = items[i];
6221 10 Jan 13 nicklas 176       Buttons.addClickHandler(item, Buttons.shareItem, attributes);
6221 10 Jan 13 nicklas 177     }
7943 04 May 21 nicklas 178     
7943 04 May 21 nicklas 179     // Add handler for detecting when a sticky-col is stuck
7943 04 May 21 nicklas 180     // The area is defined by the <tbl:data> element
7943 04 May 21 nicklas 181     // If there is a "row-index" column we must apply a margin since the
7943 04 May 21 nicklas 182     // sticky-col:s will stick to the right of the row-index column.
7943 04 May 21 nicklas 183     var stickyCols = element.getElementsByClassName('sticky-col');
7943 04 May 21 nicklas 184     var data = element.getElementsByClassName('data');
7943 04 May 21 nicklas 185     if (stickyCols.length > 0 && data.length > 0)
7943 04 May 21 nicklas 186     {
7943 04 May 21 nicklas 187       // Need to run this later since the table may be hidden and leftCol=0
7943 04 May 21 nicklas 188       Doc.addFinalizer(
7943 04 May 21 nicklas 189         function()
7943 04 May 21 nicklas 190         {
7943 04 May 21 nicklas 191           var rowIndex = element.getElementsByClassName('row-index');
7943 04 May 21 nicklas 192           var leftPos = rowIndex.length > 0 ? Doc.getElementPosition(rowIndex[0]).right : 0;
7943 04 May 21 nicklas 193           if (leftPos > 0)
7943 04 May 21 nicklas 194           {
7943 04 May 21 nicklas 195             var leftPos1 = leftPos-1;
7943 04 May 21 nicklas 196             for (var i = 0; i < stickyCols.length; i++)
7943 04 May 21 nicklas 197             {
7943 04 May 21 nicklas 198               stickyCols[i].style.left = leftPos1+'px';
7943 04 May 21 nicklas 199             }
7943 04 May 21 nicklas 200           }
7943 04 May 21 nicklas 201           
7943 04 May 21 nicklas 202           var observer = new IntersectionObserver(internal.handleStickyCol, 
7943 04 May 21 nicklas 203             {
7943 04 May 21 nicklas 204               root: data[0],
7943 04 May 21 nicklas 205               rootMargin: '0px 0px 0px -'+(leftPos)+'px',
7943 04 May 21 nicklas 206               threshold: 1.0
7943 04 May 21 nicklas 207             });
7943 04 May 21 nicklas 208           observer.table = element;
7943 04 May 21 nicklas 209           observer.observe(stickyCols[0]);
7943 04 May 21 nicklas 210         });
7943 04 May 21 nicklas 211     }
6182 23 Oct 12 nicklas 212   }
6182 23 Oct 12 nicklas 213   Doc.addElementInitializer(internal.initTable);
6182 23 Oct 12 nicklas 214   
7943 04 May 21 nicklas 215   internal.handleStickyCol = function(entries, observer)
7943 04 May 21 nicklas 216   {
7943 04 May 21 nicklas 217     for (var i = 0; i < entries.length; i++)
7943 04 May 21 nicklas 218     {
7943 04 May 21 nicklas 219       var e = entries[i];
7943 04 May 21 nicklas 220       Doc.addOrRemoveClass(observer.table, 'stuck-left', e.intersectionRatio < 1 && e.boundingClientRect.x < e.intersectionRect.x);
7943 04 May 21 nicklas 221       Doc.addOrRemoveClass(observer.table, 'stuck-right', e.intersectionRatio < 1 && e.boundingClientRect.right > e.intersectionRect.right);
7943 04 May 21 nicklas 222     }
7943 04 May 21 nicklas 223   }
7943 04 May 21 nicklas 224   
6182 23 Oct 12 nicklas 225   /**
7085 02 Mar 16 nicklas 226     Event handler for showing a column selection menu 
7085 02 Mar 16 nicklas 227     when right-clicking a column header.
7085 02 Mar 16 nicklas 228   */
7085 02 Mar 16 nicklas 229   table.showColumnSelectionMenu = function(event)
7085 02 Mar 16 nicklas 230   {
7085 02 Mar 16 nicklas 231     var frm = document.forms['reggie'];
7085 02 Mar 16 nicklas 232     // Context menu on 'right' mouse button
7085 02 Mar 16 nicklas 233     // Can't just check the button since two events are sent ('mouseup' and 'contextmenu')
7085 02 Mar 16 nicklas 234     var showContext = event.type == 'contextmenu' && event.button == 2;
7085 02 Mar 16 nicklas 235     
7085 02 Mar 16 nicklas 236     if (showContext)
7085 02 Mar 16 nicklas 237     {
7085 02 Mar 16 nicklas 238       event.preventDefault(); // Prevents the default right-click menu from appearing
7085 02 Mar 16 nicklas 239       
7085 02 Mar 16 nicklas 240       var tableId = Data.get(event.currentTarget, 'table-id');
7085 02 Mar 16 nicklas 241       var afterColumnId = Data.get(event.currentTarget, 'column-id');
7085 02 Mar 16 nicklas 242       
7085 02 Mar 16 nicklas 243       var ctxMenu = Doc.element(tableId+'-select-visible-columns');
7162 30 May 16 nicklas 244       var filterDiv = Doc.element(tableId+'-select-visible-columns-filter');
7162 30 May 16 nicklas 245       var noMatchDiv = Doc.element(tableId+'-select-visible-columns-nomatch');
7162 30 May 16 nicklas 246
7085 02 Mar 16 nicklas 247       if (!ctxMenu)
7085 02 Mar 16 nicklas 248       {
7085 02 Mar 16 nicklas 249         // Create the <div> with the menu items
7085 02 Mar 16 nicklas 250         // One per table (in the rare case that there is more than one per page)
7085 02 Mar 16 nicklas 251         ctxMenu = document.createElement('div');
7085 02 Mar 16 nicklas 252         ctxMenu.className = 'menu vertical bg-filled-100 table-select-columns';
7085 02 Mar 16 nicklas 253         ctxMenu.id = tableId+'-select-visible-columns';
7162 30 May 16 nicklas 254         ctxMenu.tabIndex = 0;
7085 02 Mar 16 nicklas 255         document.body.appendChild(ctxMenu);
7162 30 May 16 nicklas 256         
7162 30 May 16 nicklas 257         // Submit changes when ENTER key is pressed
7162 30 May 16 nicklas 258         ctxMenu.form = document.forms[tableId];
7162 30 May 16 nicklas 259         Events.doOnEnter(ctxMenu, Forms.submit)
7162 30 May 16 nicklas 260   
7085 02 Mar 16 nicklas 261         var colDefs = table.getColumnDefs(tableId);
7162 30 May 16 nicklas 262         var activateFilter = colDefs.length > 30;
7162 30 May 16 nicklas 263         if (activateFilter)
7162 30 May 16 nicklas 264         {
7162 30 May 16 nicklas 265           // Add a filter <div>
7162 30 May 16 nicklas 266           filterDiv = document.createElement('div');
7162 30 May 16 nicklas 267           filterDiv.className = 'menuitem column-filter bottomborder';
7162 30 May 16 nicklas 268           filterDiv.id = tableId+'-select-visible-columns-filter';
7162 30 May 16 nicklas 269           ctxMenu.appendChild(filterDiv);
7162 30 May 16 nicklas 270           // Need to catch both events to handle {backspace} correctly in IE
7162 30 May 16 nicklas 271           Events.addEventHandler(ctxMenu, 'keypress', table.filterColumnSelectionMenu);
7162 30 May 16 nicklas 272           Events.addEventHandler(ctxMenu, 'keydown', table.filterColumnSelectionMenu);
7162 30 May 16 nicklas 273
7162 30 May 16 nicklas 274           // Add 'no matching columns' <div>
7162 30 May 16 nicklas 275           noMatchDiv = document.createElement('div');
7162 30 May 16 nicklas 276           noMatchDiv.className = 'menuitem';
7162 30 May 16 nicklas 277           noMatchDiv.innerHTML = 'No matching columns';
7162 30 May 16 nicklas 278           noMatchDiv.id = tableId+'-select-visible-columns-nomatch';
7162 30 May 16 nicklas 279         }
7162 30 May 16 nicklas 280         
7162 30 May 16 nicklas 281         var allCols = document.createElement('div');
7162 30 May 16 nicklas 282         allCols.className = 'table-all-columns';
7162 30 May 16 nicklas 283         ctxMenu.appendChild(allCols);
7162 30 May 16 nicklas 284         
7085 02 Mar 16 nicklas 285         var hasAnnotationSeparator = false;
7085 02 Mar 16 nicklas 286         for (var i = 0; i < colDefs.length; i++)
7085 02 Mar 16 nicklas 287         {
7085 02 Mar 16 nicklas 288           var col = colDefs[i];
7952 12 May 21 nicklas 289           if (!col.alwaysShow && !col.alwaysHide)
7085 02 Mar 16 nicklas 290           {
7085 02 Mar 16 nicklas 291             if (col.isAnnotation != hasAnnotationSeparator)
7085 02 Mar 16 nicklas 292             {
7085 02 Mar 16 nicklas 293               // Insert separator when switching 
7085 02 Mar 16 nicklas 294               // between regular and annotation columns
7085 02 Mar 16 nicklas 295               hasAnnotationSeparator = col.isAnnotation;
7085 02 Mar 16 nicklas 296               var sep = document.createElement('div');
7085 02 Mar 16 nicklas 297               sep.className = 'menuseparator';
7162 30 May 16 nicklas 298               allCols.appendChild(sep);
7085 02 Mar 16 nicklas 299             }
7085 02 Mar 16 nicklas 300             
7162 30 May 16 nicklas 301             var html = '<span class="padding">';
7085 02 Mar 16 nicklas 302             html += '&nbsp;</span>'+Strings.encodeTags(col.title);
7085 02 Mar 16 nicklas 303             
7085 02 Mar 16 nicklas 304             var mnuItem = document.createElement('div');
7162 30 May 16 nicklas 305             mnuItem.className = 'menuitem interactable table-col' + (col.visible?' visible-column':'');
7085 02 Mar 16 nicklas 306             mnuItem.title = col.title;
7162 30 May 16 nicklas 307             mnuItem.filterText = col.title.toLowerCase();
7085 02 Mar 16 nicklas 308             mnuItem.innerHTML = html;
7085 02 Mar 16 nicklas 309             Data.set(mnuItem, 'column-id', col.id);
7085 02 Mar 16 nicklas 310             Data.set(mnuItem, 'table-id', tableId);
7085 02 Mar 16 nicklas 311             Data.set(mnuItem, 'after-column-id', afterColumnId);
7085 02 Mar 16 nicklas 312             Events.addEventHandler(mnuItem, 'click', table.showOrHideSelectedColumn);
7162 30 May 16 nicklas 313             allCols.appendChild(mnuItem);
7085 02 Mar 16 nicklas 314           }
7085 02 Mar 16 nicklas 315         }
7162 30 May 16 nicklas 316         
7162 30 May 16 nicklas 317         if (activateFilter) ctxMenu.appendChild(noMatchDiv);
7085 02 Mar 16 nicklas 318       }
7085 02 Mar 16 nicklas 319       else
7085 02 Mar 16 nicklas 320       {
7085 02 Mar 16 nicklas 321         // If the menu already has been created we 
7085 02 Mar 16 nicklas 322         // only need to update the 'after-column-id' attribute
7162 30 May 16 nicklas 323         var menuItems = ctxMenu.getElementsByClassName('table-col');
7085 02 Mar 16 nicklas 324         for (var i = 0; i < menuItems.length; i++)
7085 02 Mar 16 nicklas 325         {
7163 30 May 16 nicklas 326           var item = menuItems[i];
7163 30 May 16 nicklas 327           Data.set(item, 'after-column-id', afterColumnId);
7163 30 May 16 nicklas 328           item.innerHTML = '<span class="padding">&nbsp;</span>'+Strings.encodeTags(item.title);
7163 30 May 16 nicklas 329           Doc.show(item);
7085 02 Mar 16 nicklas 330         }
7085 02 Mar 16 nicklas 331       }
7085 02 Mar 16 nicklas 332       
7162 30 May 16 nicklas 333       if (filterDiv) filterDiv.innerHTML = 'Type to filter columns';
7162 30 May 16 nicklas 334       if (noMatchDiv) Doc.hide(noMatchDiv);
7162 30 May 16 nicklas 335       
7085 02 Mar 16 nicklas 336       // Position the menu near the mouse
7085 02 Mar 16 nicklas 337       var winPos = App.getWindowPosition();
7085 02 Mar 16 nicklas 338       var alignToRight = event.clientX + 200 > winPos.width;
7085 02 Mar 16 nicklas 339       Menu.showTopMenu(ctxMenu, alignToRight ? winPos.width-event.clientX : event.clientX, event.clientY, alignToRight);
7162 30 May 16 nicklas 340       ctxMenu.filterText = '';
7162 30 May 16 nicklas 341       ctxMenu.focus();
7085 02 Mar 16 nicklas 342     }
7085 02 Mar 16 nicklas 343   }
7085 02 Mar 16 nicklas 344   
7162 30 May 16 nicklas 345   // Reacts to keys and either insert or delete a character from the filter field
7162 30 May 16 nicklas 346   table.filterColumnSelectionMenu = function(event)
7162 30 May 16 nicklas 347   {
7162 30 May 16 nicklas 348     var target = event.currentTarget;
7162 30 May 16 nicklas 349     if (event.keyCode == 8)
7162 30 May 16 nicklas 350     {
7162 30 May 16 nicklas 351       // Backspace delete one character
7162 30 May 16 nicklas 352       target.filterText = target.filterText.substring(0, target.filterText.length-1);
7162 30 May 16 nicklas 353       event.preventDefault();
7162 30 May 16 nicklas 354     }
7162 30 May 16 nicklas 355     else if (event.charCode > 0)
7162 30 May 16 nicklas 356     {
7162 30 May 16 nicklas 357       // Add the typed character to the filter
7162 30 May 16 nicklas 358       target.filterText += String.fromCharCode(event.charCode);
7162 30 May 16 nicklas 359     }
7162 30 May 16 nicklas 360     else
7162 30 May 16 nicklas 361     {
7162 30 May 16 nicklas 362       return;
7162 30 May 16 nicklas 363     }
7162 30 May 16 nicklas 364     
7162 30 May 16 nicklas 365     // Update the displayed filter text
7162 30 May 16 nicklas 366     Doc.element(target.id+'-filter').innerHTML = Strings.encodeTags(target.filterText || 'Type to filter columns');
7162 30 May 16 nicklas 367     
7162 30 May 16 nicklas 368     var items = target.getElementsByClassName('table-col');
7162 30 May 16 nicklas 369     var numMatching = 0;
7162 30 May 16 nicklas 370     var filterText = target.filterText.toLowerCase();
7162 30 May 16 nicklas 371     for (var i = 0; i < items.length; i++)
7162 30 May 16 nicklas 372     {
7162 30 May 16 nicklas 373       var item = items[i];
7163 30 May 16 nicklas 374       var startIndex = item.filterText.indexOf(filterText);
7163 30 May 16 nicklas 375       if (startIndex >= 0)
7162 30 May 16 nicklas 376       {
7162 30 May 16 nicklas 377         numMatching++;
7162 30 May 16 nicklas 378         Doc.show(item);
7163 30 May 16 nicklas 379         var endIndex = startIndex+filterText.length;
7163 30 May 16 nicklas 380         var html = '<span class="padding">&nbsp;</span>';
7163 30 May 16 nicklas 381         if (endIndex > startIndex)
7163 30 May 16 nicklas 382         {
7163 30 May 16 nicklas 383           html += Strings.encodeTags(item.title.substring(0, startIndex));
7163 30 May 16 nicklas 384           html += '<b>'+Strings.encodeTags(item.title.substring(startIndex, endIndex))+'</b>';
7163 30 May 16 nicklas 385           html += Strings.encodeTags(item.title.substring(endIndex));
7163 30 May 16 nicklas 386         }
7163 30 May 16 nicklas 387         else
7163 30 May 16 nicklas 388         {
7163 30 May 16 nicklas 389           html += Strings.encodeTags(item.title);
7163 30 May 16 nicklas 390         }
7163 30 May 16 nicklas 391         item.innerHTML = html;
7162 30 May 16 nicklas 392       }
7162 30 May 16 nicklas 393       else
7162 30 May 16 nicklas 394       {
7162 30 May 16 nicklas 395         Doc.hide(item);
7162 30 May 16 nicklas 396       }
7162 30 May 16 nicklas 397     }
7162 30 May 16 nicklas 398     Doc.showHide(target.id+'-nomatch', numMatching==0);
7162 30 May 16 nicklas 399   }
7162 30 May 16 nicklas 400   
7085 02 Mar 16 nicklas 401   /**
7085 02 Mar 16 nicklas 402     Event handler invoked when selecting a column from the 
7085 02 Mar 16 nicklas 403     context menu. If the selected column is visible it is hidden,
7085 02 Mar 16 nicklas 404     otherwise it is inserted after the column that was clicked
7085 02 Mar 16 nicklas 405     to bring up the context menu.
7085 02 Mar 16 nicklas 406   */
7085 02 Mar 16 nicklas 407   table.showOrHideSelectedColumn = function(event)
7085 02 Mar 16 nicklas 408   {
7085 02 Mar 16 nicklas 409     var tableId = Data.get(event.currentTarget, 'table-id');
7085 02 Mar 16 nicklas 410     var afterColumnId = Data.get(event.currentTarget, 'after-column-id');
7085 02 Mar 16 nicklas 411     var columnId = Data.get(event.currentTarget, 'column-id');
7085 02 Mar 16 nicklas 412     
7085 02 Mar 16 nicklas 413     var visibleCols = table.getVisibleColumnIdsAsArray(tableId);
7085 02 Mar 16 nicklas 414     var index = visibleCols.indexOf(columnId);
7085 02 Mar 16 nicklas 415     if (index >= 0)
7085 02 Mar 16 nicklas 416     {
7085 02 Mar 16 nicklas 417       // Hide this column
7085 02 Mar 16 nicklas 418       visibleCols.splice(index, 1);
7162 30 May 16 nicklas 419       Doc.removeClass(event.currentTarget, 'visible-column');
7085 02 Mar 16 nicklas 420     }
7085 02 Mar 16 nicklas 421     else
7085 02 Mar 16 nicklas 422     {
7085 02 Mar 16 nicklas 423       // Insert after the column that was clicked
7085 02 Mar 16 nicklas 424       var afterIndex = visibleCols.indexOf(afterColumnId);
7085 02 Mar 16 nicklas 425       visibleCols.splice(afterIndex+1, 0, columnId);
7162 30 May 16 nicklas 426       Doc.addClass(event.currentTarget, 'visible-column');
7085 02 Mar 16 nicklas 427     }
7162 30 May 16 nicklas 428     
7162 30 May 16 nicklas 429     if (event.altKey || event.ctrlKey || event.shiftKey)
7162 30 May 16 nicklas 430     {
7162 30 May 16 nicklas 431       // Keep the context menu open and make it possible to select more columns
7162 30 May 16 nicklas 432       var frm = document.forms[tableId];
7162 30 May 16 nicklas 433       frm.columns.value = visibleCols.join(',');
7162 30 May 16 nicklas 434       event.stopPropagation();
7162 30 May 16 nicklas 435     }
7162 30 May 16 nicklas 436     else
7162 30 May 16 nicklas 437     {
7162 30 May 16 nicklas 438       table.setColumns(tableId, visibleCols.join(','));
7162 30 May 16 nicklas 439     }
7085 02 Mar 16 nicklas 440   }
7085 02 Mar 16 nicklas 441   
7085 02 Mar 16 nicklas 442   /**
6182 23 Oct 12 nicklas 443     Click handler that changes the sort order of the table. The sort property
6182 23 Oct 12 nicklas 444     and sort direction should be stored in the data-sort-property and data-sort-direction
6182 23 Oct 12 nicklas 445     properties of the target element.
6182 23 Oct 12 nicklas 446   */
6182 23 Oct 12 nicklas 447   table.sortOnClick = function(event)
6182 23 Oct 12 nicklas 448   {
6182 23 Oct 12 nicklas 449     var column = event.currentTarget;
6182 23 Oct 12 nicklas 450     var sortProperty = Data.get(column, 'sort-property');
6182 23 Oct 12 nicklas 451     var sortDirection = Data.get(column, 'sort-direction');
6220 10 Jan 13 nicklas 452     var tableId = Data.get(column, 'table-id');
6182 23 Oct 12 nicklas 453     var frm = document.forms[tableId];
6336 28 Oct 13 nicklas 454     var mainDirection = frm.direction.value;
6336 28 Oct 13 nicklas 455     if (frm.sortby.value != sortProperty || mainDirection != sortDirection)
6182 23 Oct 12 nicklas 456     {
6182 23 Oct 12 nicklas 457       if (event.altKey || event.ctrlKey || event.shiftKey) 
6182 23 Oct 12 nicklas 458       {
6182 23 Oct 12 nicklas 459         // Append the current sort property to the list of already sorted columns
6336 28 Oct 13 nicklas 460         // If the sort property is already used we keep it, but use the new sort direction
6182 23 Oct 12 nicklas 461         var sortArray = frm.sortby.value.split(',');
6182 23 Oct 12 nicklas 462         var index = sortArray.indexOf(sortProperty);
6336 28 Oct 13 nicklas 463         // Check for '+' and '-' prefix if the sort order is different from main direction
6336 28 Oct 13 nicklas 464         if (index == -1) index = sortArray.indexOf('+'+sortProperty);
6336 28 Oct 13 nicklas 465         if (index == -1) index = sortArray.indexOf('-'+sortProperty);
6336 28 Oct 13 nicklas 466         // Currently not sorted, insert at end
6336 28 Oct 13 nicklas 467         if (index == -1) index = sortArray.length;
6182 23 Oct 12 nicklas 468         // Add the sort property as the last property
6336 28 Oct 13 nicklas 469         if (sortDirection != mainDirection)
6336 28 Oct 13 nicklas 470         {
6336 28 Oct 13 nicklas 471           sortProperty = (sortDirection == 'ASC' ? '+' : '-') + sortProperty;
6336 28 Oct 13 nicklas 472           sortDirection = mainDirection;
6336 28 Oct 13 nicklas 473         }
6336 28 Oct 13 nicklas 474         sortArray[index] = sortProperty;
6182 23 Oct 12 nicklas 475         sortProperty = sortArray.join(',');
6182 23 Oct 12 nicklas 476       }
6182 23 Oct 12 nicklas 477       frm.sortby.value = sortProperty;
6182 23 Oct 12 nicklas 478       frm.direction.value = sortDirection;
7894 08 Dec 20 nicklas 479       Forms.submit(frm);
6182 23 Oct 12 nicklas 480     }
6182 23 Oct 12 nicklas 481   }
6182 23 Oct 12 nicklas 482   
6182 23 Oct 12 nicklas 483   /**
7083 01 Mar 16 nicklas 484     Start dragging a table column. Store table-id, column-id 
7083 01 Mar 16 nicklas 485     and column-index on the table element.
7083 01 Mar 16 nicklas 486   */
7083 01 Mar 16 nicklas 487   table.beginColumnDrag = function(event)
7083 01 Mar 16 nicklas 488   {
7083 01 Mar 16 nicklas 489     var dragSrc = {};
7083 01 Mar 16 nicklas 490     dragSrc.tableId = Data.get(event.currentTarget, 'table-id');
7083 01 Mar 16 nicklas 491     dragSrc.columnId = Data.get(event.currentTarget, 'column-id');
7083 01 Mar 16 nicklas 492     dragSrc.columnIndex = Data.int(event.currentTarget, 'column-index');
7083 01 Mar 16 nicklas 493     
7083 01 Mar 16 nicklas 494     // Store the drag data on the <table> div
7083 01 Mar 16 nicklas 495     Doc.element(dragSrc.tableId).dragSrc = dragSrc;
7083 01 Mar 16 nicklas 496     event.dataTransfer.effectAllowed = 'move';
7083 01 Mar 16 nicklas 497     // In FF, we also need to call setData() or the drag event will not start
7083 01 Mar 16 nicklas 498     // but this results in an exception in IE!!!
7083 01 Mar 16 nicklas 499     try
7083 01 Mar 16 nicklas 500     {
7083 01 Mar 16 nicklas 501       event.dataTransfer.setData('application/json', JSON.stringify(dragSrc));
7083 01 Mar 16 nicklas 502     }
7083 01 Mar 16 nicklas 503     catch (e)
7083 01 Mar 16 nicklas 504     {}
7083 01 Mar 16 nicklas 505   }
7083 01 Mar 16 nicklas 506   
7083 01 Mar 16 nicklas 507   /**
7083 01 Mar 16 nicklas 508     Clean up after dragging.
7083 01 Mar 16 nicklas 509    */
7083 01 Mar 16 nicklas 510   table.endColumnDrag = function(event)
7083 01 Mar 16 nicklas 511   {
7083 01 Mar 16 nicklas 512     var tableId = Data.get(event.currentTarget, 'table-id');
7083 01 Mar 16 nicklas 513     Doc.element(tableId).dragSrc = null;
7083 01 Mar 16 nicklas 514   }
7083 01 Mar 16 nicklas 515   
7083 01 Mar 16 nicklas 516   /**
7083 01 Mar 16 nicklas 517     Checks if dropping is allowed at this target.
7083 01 Mar 16 nicklas 518     We only allow dragging within the same table,
7083 01 Mar 16 nicklas 519     and the target column must be different from the 
7083 01 Mar 16 nicklas 520     source column.
7083 01 Mar 16 nicklas 521   */
7083 01 Mar 16 nicklas 522   table.checkColumnDropTarget = function(event)
7083 01 Mar 16 nicklas 523   {
7083 01 Mar 16 nicklas 524     var tableId = Data.get(event.currentTarget, 'table-id');
7083 01 Mar 16 nicklas 525     var dragSrc = Doc.element(tableId).dragSrc;
7083 01 Mar 16 nicklas 526     
7083 01 Mar 16 nicklas 527     var dropLocation = table.checkTheDropTarget(dragSrc, event.currentTarget);
7083 01 Mar 16 nicklas 528     if (dropLocation)
7083 01 Mar 16 nicklas 529     {
7083 01 Mar 16 nicklas 530       // Enable drop target!
7083 01 Mar 16 nicklas 531       event.preventDefault();
7083 01 Mar 16 nicklas 532       event.dataTransfer.dropEffect = 'move';
7083 01 Mar 16 nicklas 533       // Left or right depending on the order or columns
7083 01 Mar 16 nicklas 534       Doc.addClass(event.currentTarget, dropLocation < 0 ? 'table-drop-left' : 'table-drop-right');
7083 01 Mar 16 nicklas 535     }
7083 01 Mar 16 nicklas 536   }
7083 01 Mar 16 nicklas 537
7083 01 Mar 16 nicklas 538   /**
7083 01 Mar 16 nicklas 539     Checks if dropping is allowed at this target.
7083 01 Mar 16 nicklas 540     We only allow dragging within the same table,
7083 01 Mar 16 nicklas 541     and the target column must be different from the 
7083 01 Mar 16 nicklas 542     source column.
7083 01 Mar 16 nicklas 543     returns: 0 = no drop, -1 drop to left, +1 drop to right
7083 01 Mar 16 nicklas 544   */
7083 01 Mar 16 nicklas 545   table.checkTheDropTarget = function(dragSrc, dragTarget)
7083 01 Mar 16 nicklas 546   {
7083 01 Mar 16 nicklas 547     if (!dragSrc) return false;
7083 01 Mar 16 nicklas 548     var tableId = Data.get(dragTarget, 'table-id');
7083 01 Mar 16 nicklas 549     var columnIndex = Data.int(dragTarget, 'column-index');
7083 01 Mar 16 nicklas 550     return tableId == dragSrc.tableId ? columnIndex - dragSrc.columnIndex : 0;
7083 01 Mar 16 nicklas 551   }
7083 01 Mar 16 nicklas 552   
7083 01 Mar 16 nicklas 553   /**
7083 01 Mar 16 nicklas 554     Remove drop indicator classes when leaving.
7083 01 Mar 16 nicklas 555   */
7083 01 Mar 16 nicklas 556   table.leaveColumnDropTarget = function(event)
7083 01 Mar 16 nicklas 557   {
7083 01 Mar 16 nicklas 558     Doc.removeClass(event.currentTarget, 'table-drop-right');
7083 01 Mar 16 nicklas 559     Doc.removeClass(event.currentTarget, 'table-drop-left');
7083 01 Mar 16 nicklas 560   }
7083 01 Mar 16 nicklas 561
7083 01 Mar 16 nicklas 562   /**
7084 01 Mar 16 nicklas 563     Get the visibile columns as an array with column id values.
7084 01 Mar 16 nicklas 564     The special case is that 'all' is expanded into actual
7084 01 Mar 16 nicklas 565     column ids.
7083 01 Mar 16 nicklas 566   */
7084 01 Mar 16 nicklas 567   table.getVisibleColumnIdsAsArray = function(tableId)
7083 01 Mar 16 nicklas 568   {
7083 01 Mar 16 nicklas 569     var columns = table.getColumns(tableId);
7083 01 Mar 16 nicklas 570     var colArray;
7083 01 Mar 16 nicklas 571     if (columns == 'all')
7083 01 Mar 16 nicklas 572     {
7083 01 Mar 16 nicklas 573       // Special case, load the existing columns
7083 01 Mar 16 nicklas 574       var colDefs = table.getColumnDefs(tableId);
7083 01 Mar 16 nicklas 575       colArray = [];
7083 01 Mar 16 nicklas 576       for (var colNo = 0; colNo < colDefs.length; colNo++)
7083 01 Mar 16 nicklas 577       {
7083 01 Mar 16 nicklas 578         var col = colDefs[colNo];
7083 01 Mar 16 nicklas 579         if (!col.alwaysHide) colArray[colArray.length] = col.id;
7083 01 Mar 16 nicklas 580       }
7083 01 Mar 16 nicklas 581     }
7083 01 Mar 16 nicklas 582     else
7083 01 Mar 16 nicklas 583     {
7083 01 Mar 16 nicklas 584       colArray = columns.split(',');
7083 01 Mar 16 nicklas 585     }
7084 01 Mar 16 nicklas 586     return colArray;
7084 01 Mar 16 nicklas 587   }
7084 01 Mar 16 nicklas 588   
7084 01 Mar 16 nicklas 589   /**
7084 01 Mar 16 nicklas 590     Another column was dropped here!
7084 01 Mar 16 nicklas 591   */
7084 01 Mar 16 nicklas 592   table.columnDropped = function(event)
7084 01 Mar 16 nicklas 593   {
7084 01 Mar 16 nicklas 594     Doc.removeClass(event.currentTarget, 'table-drop-right');
7084 01 Mar 16 nicklas 595     Doc.removeClass(event.currentTarget, 'table-drop-left');
7083 01 Mar 16 nicklas 596     
7084 01 Mar 16 nicklas 597     // Check that we can drop here
7084 01 Mar 16 nicklas 598     var tableId = Data.get(event.currentTarget, 'table-id');
7084 01 Mar 16 nicklas 599     var dragSrc = Doc.element(tableId).dragSrc;
7084 01 Mar 16 nicklas 600     if (!table.checkTheDropTarget(dragSrc, event.currentTarget)) return;
7084 01 Mar 16 nicklas 601     
7084 01 Mar 16 nicklas 602     // Get the existing columns as an array
7084 01 Mar 16 nicklas 603     var colArray = table.getVisibleColumnIdsAsArray(tableId);
7084 01 Mar 16 nicklas 604     
7083 01 Mar 16 nicklas 605     var indexSrc = colArray.indexOf(dragSrc.columnId);
7083 01 Mar 16 nicklas 606     var indexDest = colArray.indexOf(Data.get(event.currentTarget, 'column-id'));
7083 01 Mar 16 nicklas 607     // Remove the dragged column from the array
7083 01 Mar 16 nicklas 608     if (indexSrc >= 0) colArray.splice(indexSrc, 1);
7083 01 Mar 16 nicklas 609     // Insert the dragged column before or after the column it was dropped on
7083 01 Mar 16 nicklas 610     if (indexDest >= 0) colArray.splice(indexDest, 0, dragSrc.columnId);
7083 01 Mar 16 nicklas 611     
7083 01 Mar 16 nicklas 612     // Update and submit the table
7084 01 Mar 16 nicklas 613     table.setColumns(tableId, colArray.join(','));
7083 01 Mar 16 nicklas 614   }
7083 01 Mar 16 nicklas 615   
7084 01 Mar 16 nicklas 616   /**
7084 01 Mar 16 nicklas 617     Event handler for hiding a single column.
7084 01 Mar 16 nicklas 618   */
7084 01 Mar 16 nicklas 619   table.hideColumnOnClick = function(event)
7084 01 Mar 16 nicklas 620   {
7084 01 Mar 16 nicklas 621     var columnId = Data.get(event.currentTarget, 'column-id');
7084 01 Mar 16 nicklas 622     var tableId = Data.get(event.currentTarget, 'table-id');
7084 01 Mar 16 nicklas 623     
7084 01 Mar 16 nicklas 624     var colArray = table.getVisibleColumnIdsAsArray(tableId);
7084 01 Mar 16 nicklas 625     var colIndex = colArray.indexOf(columnId);
7084 01 Mar 16 nicklas 626     
7084 01 Mar 16 nicklas 627     if (colIndex >= 0)
7084 01 Mar 16 nicklas 628     {
7084 01 Mar 16 nicklas 629       colArray.splice(colIndex, 1);
7084 01 Mar 16 nicklas 630       table.setColumns(tableId, colArray.join(','));
7084 01 Mar 16 nicklas 631     }
7084 01 Mar 16 nicklas 632   }
7083 01 Mar 16 nicklas 633
7083 01 Mar 16 nicklas 634   /**
6182 23 Oct 12 nicklas 635     Event handler for the page navigator. The actual target should 
6182 23 Oct 12 nicklas 636     have a table-page attribute that specify the page to move to.
6182 23 Oct 12 nicklas 637   */
6182 23 Oct 12 nicklas 638   table.navigatorOnClick = function(event)
6182 23 Oct 12 nicklas 639   {
6182 23 Oct 12 nicklas 640     var target = event.target;
6182 23 Oct 12 nicklas 641     var page = Data.get(target, 'table-page');
6182 23 Oct 12 nicklas 642     if (page == null) return;
6182 23 Oct 12 nicklas 643     
6182 23 Oct 12 nicklas 644     var tableId = Data.get(event.currentTarget, 'table-id');
6182 23 Oct 12 nicklas 645     table.setPage(tableId, page);
6182 23 Oct 12 nicklas 646   }
6182 23 Oct 12 nicklas 647   
6182 23 Oct 12 nicklas 648   /**
6183 24 Oct 12 nicklas 649     Event handler for showing all hidden columns that have a filter.
6183 24 Oct 12 nicklas 650     The hidden columns should be stored as a comma-separated list
6220 10 Jan 13 nicklas 651     in 'data-hidden-columns' attribute and the element must have the
6220 10 Jan 13 nicklas 652     table id stored in 'data-table-id' attribute.
1606 14 Nov 05 nicklas 653   */
6183 24 Oct 12 nicklas 654   table.showColumnsOnClick = function(event)
417 19 Apr 05 nicklas 655   {
6183 24 Oct 12 nicklas 656     var target = event.currentTarget;
6183 24 Oct 12 nicklas 657     var hiddenColumns = Data.get(target, 'hidden-columns');
6220 10 Jan 13 nicklas 658     var tableId = Data.get(target, 'table-id');
6183 24 Oct 12 nicklas 659     table.showColumns(tableId, hiddenColumns);
6183 24 Oct 12 nicklas 660   }
6183 24 Oct 12 nicklas 661   
6183 24 Oct 12 nicklas 662   /**
6220 10 Jan 13 nicklas 663     Event handler for removing all filters from the table.
6220 10 Jan 13 nicklas 664     The element must have the table id stored in 'data-table-id' 
6220 10 Jan 13 nicklas 665     attribute.
6220 10 Jan 13 nicklas 666   */
6220 10 Jan 13 nicklas 667   table.clearFilterOnClick = function(event)
6220 10 Jan 13 nicklas 668   {
6220 10 Jan 13 nicklas 669     var target = event.currentTarget;
6220 10 Jan 13 nicklas 670     var tableId = Data.get(target, 'table-id');
6220 10 Jan 13 nicklas 671     table.clearFilter(tableId);
6220 10 Jan 13 nicklas 672   }
6220 10 Jan 13 nicklas 673   
6220 10 Jan 13 nicklas 674   /**
6183 24 Oct 12 nicklas 675     Event handler for the 'view/presets' selection list.
6183 24 Oct 12 nicklas 676   */
6183 24 Oct 12 nicklas 677   table.presetOnChange = function(event)
6183 24 Oct 12 nicklas 678   {
6183 24 Oct 12 nicklas 679     var presetSelector = event.currentTarget;
6183 24 Oct 12 nicklas 680     var selected = presetSelector[presetSelector.selectedIndex];
6183 24 Oct 12 nicklas 681     var cmd = selected.value;
6183 24 Oct 12 nicklas 682     var tableId = presetSelector.form.name;
6183 24 Oct 12 nicklas 683     
6183 24 Oct 12 nicklas 684     // Reset the list to no selection
6183 24 Oct 12 nicklas 685     presetSelector.selectedIndex = 0;    
6183 24 Oct 12 nicklas 686     
6183 24 Oct 12 nicklas 687     // Perform whatever command as indicated by the selected value
6183 24 Oct 12 nicklas 688     if (cmd == 'save-as')
3077 22 Jan 07 nicklas 689     {
6183 24 Oct 12 nicklas 690       table.saveCurrentContext(tableId);
3077 22 Jan 07 nicklas 691     }
6183 24 Oct 12 nicklas 692     else if (cmd == 'manage')
935 14 Jul 05 nicklas 693     {
6183 24 Oct 12 nicklas 694       table.manageContexts(tableId);
935 14 Jul 05 nicklas 695     }
6183 24 Oct 12 nicklas 696     else if (cmd == 'load-preset')
6183 24 Oct 12 nicklas 697     {
6183 24 Oct 12 nicklas 698       var presetId = Data.get(selected, 'preset-id');
6183 24 Oct 12 nicklas 699       table.loadContext(tableId, presetId);
6183 24 Oct 12 nicklas 700     }
6183 24 Oct 12 nicklas 701     else if (cmd == 'manage-columns')
6183 24 Oct 12 nicklas 702     {
6183 24 Oct 12 nicklas 703       table.configureColumns(tableId);
6183 24 Oct 12 nicklas 704     }
6183 24 Oct 12 nicklas 705     else if (cmd == 'clear-filter')
6183 24 Oct 12 nicklas 706     {
6183 24 Oct 12 nicklas 707       table.clearFilter(tableId);
6183 24 Oct 12 nicklas 708     }
6183 24 Oct 12 nicklas 709     else if (cmd == 'option')
6183 24 Oct 12 nicklas 710     {
6183 24 Oct 12 nicklas 711       var key = Data.get(selected, 'option-key');
6183 24 Oct 12 nicklas 712       var value = Data.get(selected, 'option-value');
6183 24 Oct 12 nicklas 713       table.setOption(tableId, key, value);
6183 24 Oct 12 nicklas 714     }
417 19 Apr 05 nicklas 715   }
6183 24 Oct 12 nicklas 716
6220 10 Jan 13 nicklas 717   /**
6220 10 Jan 13 nicklas 718     Event handler for the 'Check/uncheck all' icon that select
6220 10 Jan 13 nicklas 719     or deselect all checkboxes on the current table page.
6220 10 Jan 13 nicklas 720     The element must have the table id stored in 'data-table-id' 
6220 10 Jan 13 nicklas 721     attribute. The 'data-regexp' may be used to specify a regular
6220 10 Jan 13 nicklas 722     expression to match checkbox names, otherwise all numeric 
6220 10 Jan 13 nicklas 723     checkboxes are included.
6220 10 Jan 13 nicklas 724   */
6220 10 Jan 13 nicklas 725   table.checkUncheckOnClick = function(event)
6220 10 Jan 13 nicklas 726   {
6220 10 Jan 13 nicklas 727     var target = event.currentTarget;
6220 10 Jan 13 nicklas 728     var tableId = Data.get(target, 'table-id');
6220 10 Jan 13 nicklas 729     var regexp = Data.get(target, 'regexp');
6834 08 Apr 15 nicklas 730     var specialKey = event.altKey || event.ctrlKey || event.shiftKey;
6834 08 Apr 15 nicklas 731     if (specialKey)
6834 08 Apr 15 nicklas 732     {
6834 08 Apr 15 nicklas 733       Forms.checkUncheck(document.forms[tableId], regexp);
6834 08 Apr 15 nicklas 734     }
6834 08 Apr 15 nicklas 735     else
6834 08 Apr 15 nicklas 736     {
6834 08 Apr 15 nicklas 737       Forms.toggleCheckboxes(document.forms[tableId], regexp);
6834 08 Apr 15 nicklas 738     }
6834 08 Apr 15 nicklas 739
6220 10 Jan 13 nicklas 740   }
3077 22 Jan 07 nicklas 741   
3077 22 Jan 07 nicklas 742   /**
6699 30 Jan 15 nicklas 743     Event handler for the 'Add filter row' and 'Remove filter row' icons
6699 30 Jan 15 nicklas 744     that adds or remove filter rows to/from the table.
6697 29 Jan 15 nicklas 745     The element must have the table id stored in 'data-table-id' 
6699 30 Jan 15 nicklas 746     attribute. If 'remove-row' is set, a the given row is removed,
6699 30 Jan 15 nicklas 747     otherwise a new row is added.
6697 29 Jan 15 nicklas 748   */
6699 30 Jan 15 nicklas 749   table.filterRowActionOnClick = function(event)
6697 29 Jan 15 nicklas 750   {
6697 29 Jan 15 nicklas 751     var target = event.currentTarget;
6697 29 Jan 15 nicklas 752     var tableId = Data.get(target, 'table-id');
6699 30 Jan 15 nicklas 753     var removeRow = Data.get(target, 'remove-row');
6699 30 Jan 15 nicklas 754     if (removeRow != null)
6699 30 Jan 15 nicklas 755     {
6699 30 Jan 15 nicklas 756       table.removeFilterRow(tableId, removeRow);
6699 30 Jan 15 nicklas 757     }
6699 30 Jan 15 nicklas 758     else
6699 30 Jan 15 nicklas 759     {
6699 30 Jan 15 nicklas 760       table.addFilterRow(tableId);
6699 30 Jan 15 nicklas 761     }
6697 29 Jan 15 nicklas 762   }
6697 29 Jan 15 nicklas 763   
6697 29 Jan 15 nicklas 764   /**
6220 10 Jan 13 nicklas 765     Event handler for clicking on the main item on the table. In normal
6220 10 Jan 13 nicklas 766     list mode, the event handler simply forwards to the Item.itemOnClick
6220 10 Jan 13 nicklas 767     method. In selection mode, the corresponding checkbox/radio button
6220 10 Jan 13 nicklas 768     is selected and returned to the caller and the window is closed.
6220 10 Jan 13 nicklas 769   */
6220 10 Jan 13 nicklas 770   table.mainItemOnClick = function(event)
6220 10 Jan 13 nicklas 771   {
6220 10 Jan 13 nicklas 772     var target = event.currentTarget;
6220 10 Jan 13 nicklas 773     var tableId = Data.get(target, 'table-id');
6220 10 Jan 13 nicklas 774     var itemId = Data.int(target, 'item-id');
6308 20 Aug 13 nicklas 775     
6220 10 Jan 13 nicklas 776     var frm = document.forms[tableId];
6220 10 Jan 13 nicklas 777     var mode = frm.mode ? frm.mode.value : 'default';
6220 10 Jan 13 nicklas 778     if (mode == 'selectone')
6220 10 Jan 13 nicklas 779     {
6220 10 Jan 13 nicklas 780       var index = Forms.checkRadio(frm.item_id, itemId);
6222 14 Jan 13 nicklas 781       table.returnSelectedItems(tableId);
6222 14 Jan 13 nicklas 782       App.closeWindow();
6220 10 Jan 13 nicklas 783     }
6220 10 Jan 13 nicklas 784     else if (mode == 'selectmultiple' || mode == 'selectmultiplenobuttons')
6220 10 Jan 13 nicklas 785     {
6220 10 Jan 13 nicklas 786       var checkbox = table.toggleCheckBox(tableId, itemId);
6222 14 Jan 13 nicklas 787       table.returnSelectedItems(tableId);
6222 14 Jan 13 nicklas 788       App.closeWindow();
6220 10 Jan 13 nicklas 789     }
6840 09 Apr 15 nicklas 790     else if (mode == 'selectfilter')
6840 09 Apr 15 nicklas 791     {
6840 09 Apr 15 nicklas 792       table.toggleCheckBox(tableId, itemId);
6840 09 Apr 15 nicklas 793     }
6220 10 Jan 13 nicklas 794     else
6220 10 Jan 13 nicklas 795     {
6220 10 Jan 13 nicklas 796       Items.itemOnClick(event);
6220 10 Jan 13 nicklas 797     }
6220 10 Jan 13 nicklas 798   }
6220 10 Jan 13 nicklas 799   
6220 10 Jan 13 nicklas 800   /**
3077 22 Jan 07 nicklas 801     Get all columns defined for the specified table.
6188 30 Oct 12 nicklas 802     @param tableDiv The ID or main table element
3077 22 Jan 07 nicklas 803   */
6188 30 Oct 12 nicklas 804   table.getColumnDefs = function(tableDiv)
3077 22 Jan 07 nicklas 805   {
6188 30 Oct 12 nicklas 806     tableDiv = Doc.element(tableDiv);
6188 30 Oct 12 nicklas 807     var columns = columnDefs[tableDiv.id];
6183 24 Oct 12 nicklas 808     if (!columns)
6183 24 Oct 12 nicklas 809     {
6188 30 Oct 12 nicklas 810       columns = Data.json(tableDiv.id+'.table-data', 'column-defs');
6186 29 Oct 12 nicklas 811       // Store each definitition using the 'id' as a key
6183 24 Oct 12 nicklas 812       for (var i = 0; i < columns.length; i++)
6183 24 Oct 12 nicklas 813       {
6183 24 Oct 12 nicklas 814         columns['id'+columns[i].id] = columns[i];
6183 24 Oct 12 nicklas 815       }
6183 24 Oct 12 nicklas 816       
6188 30 Oct 12 nicklas 817       columnDefs[tableDiv.id] = columns;
6183 24 Oct 12 nicklas 818     }
6183 24 Oct 12 nicklas 819     return columns;
3077 22 Jan 07 nicklas 820   }
417 19 Apr 05 nicklas 821
417 19 Apr 05 nicklas 822   /**
417 19 Apr 05 nicklas 823     Change the page of the table.
6188 30 Oct 12 nicklas 824     @param tableDiv The ID or main table element
6182 23 Oct 12 nicklas 825     @param page The new page number
417 19 Apr 05 nicklas 826   */
6188 30 Oct 12 nicklas 827   table.setPage = function(tableDiv, page)
417 19 Apr 05 nicklas 828   {
6188 30 Oct 12 nicklas 829     tableDiv = Doc.element(tableDiv);
6188 30 Oct 12 nicklas 830     var frm = document.forms[tableDiv.id];
417 19 Apr 05 nicklas 831     if (frm.page.value != page)
417 19 Apr 05 nicklas 832     {
417 19 Apr 05 nicklas 833       frm.page.value = page;
7894 08 Dec 20 nicklas 834       Forms.submit(frm);
417 19 Apr 05 nicklas 835     }
417 19 Apr 05 nicklas 836   }
417 19 Apr 05 nicklas 837   
417 19 Apr 05 nicklas 838   /**
417 19 Apr 05 nicklas 839     Change the visible columns of the table.
6188 30 Oct 12 nicklas 840     @param tableDiv The ID or main table element
417 19 Apr 05 nicklas 841     @param columns Comma-separated list of column ID:s of the visible columns, or the value 'all'
417 19 Apr 05 nicklas 842   */
7982 14 Jun 21 nicklas 843   table.setColumns = function(tableDiv, columns, stickyColumn)
417 19 Apr 05 nicklas 844   {
6188 30 Oct 12 nicklas 845     tableDiv = Doc.element(tableDiv);
6188 30 Oct 12 nicklas 846     var frm = document.forms[tableDiv.id];
7982 14 Jun 21 nicklas 847     var submit = false;
417 19 Apr 05 nicklas 848     if (frm.columns.value != columns)
417 19 Apr 05 nicklas 849     {
417 19 Apr 05 nicklas 850       frm.columns.value = columns;
7982 14 Jun 21 nicklas 851       submit = true;
417 19 Apr 05 nicklas 852     }
7982 14 Jun 21 nicklas 853     if (stickyColumn && frm.sticky_column && frm.sticky_column.value != stickyColumn)
7982 14 Jun 21 nicklas 854     {
7982 14 Jun 21 nicklas 855       frm.sticky_column.value = stickyColumn;
7982 14 Jun 21 nicklas 856       submit = true;
7982 14 Jun 21 nicklas 857     }     
7982 14 Jun 21 nicklas 858     if (submit) Forms.submit(frm);
417 19 Apr 05 nicklas 859   }
526 04 May 05 nicklas 860
417 19 Apr 05 nicklas 861   /**
1760 12 Jan 06 nicklas 862     Show columns in the table, preserving the currently visible columns.
6188 30 Oct 12 nicklas 863     @param tableDiv The ID or main table element
1760 12 Jan 06 nicklas 864     @param columns Comma-separated list of column ID:s of the visible columns, or the value 'all'
1760 12 Jan 06 nicklas 865   */
6188 30 Oct 12 nicklas 866   table.showColumns = function(tableDiv, columns)
1760 12 Jan 06 nicklas 867   {
6188 30 Oct 12 nicklas 868     tableDiv = Doc.element(tableDiv);
6188 30 Oct 12 nicklas 869     var frm = document.forms[tableDiv.id];
1760 12 Jan 06 nicklas 870     if (frm.columns.value != columns)
1760 12 Jan 06 nicklas 871     {
1760 12 Jan 06 nicklas 872       frm.columns.value += ',' + columns;
7894 08 Dec 20 nicklas 873       Forms.submit(frm);
1760 12 Jan 06 nicklas 874     }
1760 12 Jan 06 nicklas 875   }
1760 12 Jan 06 nicklas 876   
452 25 Apr 05 nicklas 877
452 25 Apr 05 nicklas 878   /**
424 20 Apr 05 nicklas 879     Get the visible columns of the table.
6188 30 Oct 12 nicklas 880     @param tableDiv The ID or main table element
424 20 Apr 05 nicklas 881   */
6188 30 Oct 12 nicklas 882   table.getColumns = function(tableDiv)
424 20 Apr 05 nicklas 883   {
6188 30 Oct 12 nicklas 884     tableDiv = Doc.element(tableDiv);
6188 30 Oct 12 nicklas 885     var frm = document.forms[tableDiv.id];
424 20 Apr 05 nicklas 886     return frm.columns.value;
424 20 Apr 05 nicklas 887   }
424 20 Apr 05 nicklas 888   
7982 14 Jun 21 nicklas 889   table.getStickyColumn = function(tableDiv)
7982 14 Jun 21 nicklas 890   {
7982 14 Jun 21 nicklas 891     tableDiv = Doc.element(tableDiv);
7982 14 Jun 21 nicklas 892     var frm = document.forms[tableDiv.id];
7982 14 Jun 21 nicklas 893     return frm.sticky_column ? frm.sticky_column.value : null;
7982 14 Jun 21 nicklas 894   }
452 25 Apr 05 nicklas 895   
6182 23 Oct 12 nicklas 896   /**
6182 23 Oct 12 nicklas 897     Clear the all filters 
6188 30 Oct 12 nicklas 898     @param tableDiv The ID or main table element
6182 23 Oct 12 nicklas 899   */
6188 30 Oct 12 nicklas 900   table.clearFilter = function(tableDiv)
1714 14 Dec 05 nicklas 901   {
6188 30 Oct 12 nicklas 902     tableDiv = Doc.element(tableDiv);
6188 30 Oct 12 nicklas 903     var frm = document.forms[tableDiv.id];
6182 23 Oct 12 nicklas 904     Forms.addHidden(frm, 'filter:clearAll', '1');
7894 08 Dec 20 nicklas 905     Forms.submit(frm);
1714 14 Dec 05 nicklas 906   }
1714 14 Dec 05 nicklas 907   
6182 23 Oct 12 nicklas 908   /**
6697 29 Jan 15 nicklas 909     Add a new filter row to the table
6697 29 Jan 15 nicklas 910     @param tableDiv The ID or main table element
6697 29 Jan 15 nicklas 911   */
6697 29 Jan 15 nicklas 912   table.addFilterRow = function(tableDiv)
6697 29 Jan 15 nicklas 913   {
6697 29 Jan 15 nicklas 914     tableDiv = Doc.element(tableDiv);
6697 29 Jan 15 nicklas 915     var frm = document.forms[tableDiv.id];
6697 29 Jan 15 nicklas 916     Forms.addHidden(frm, 'addFilterRows', '1');
7894 08 Dec 20 nicklas 917     Forms.submit(frm);
6697 29 Jan 15 nicklas 918   }
6697 29 Jan 15 nicklas 919   
6697 29 Jan 15 nicklas 920   /**
6697 29 Jan 15 nicklas 921     Remove a filter row from the table
6697 29 Jan 15 nicklas 922     @param tableDiv The ID or main table element
6697 29 Jan 15 nicklas 923     @param filterIndex The index of the filter row, starting at 0
6697 29 Jan 15 nicklas 924   */
6697 29 Jan 15 nicklas 925   table.removeFilterRow = function(tableDiv, filterIndex)
6697 29 Jan 15 nicklas 926   {
6697 29 Jan 15 nicklas 927     tableDiv = Doc.element(tableDiv);
6697 29 Jan 15 nicklas 928     var frm = document.forms[tableDiv.id];
6697 29 Jan 15 nicklas 929     Forms.addHidden(frm, 'removeFilterRow', filterIndex);
7894 08 Dec 20 nicklas 930     Forms.submit(frm);
6697 29 Jan 15 nicklas 931   }
6697 29 Jan 15 nicklas 932   
6697 29 Jan 15 nicklas 933   /**
6183 24 Oct 12 nicklas 934     Open a popup window that allows a user to configure which columns
6183 24 Oct 12 nicklas 935     that should be visible and their order.
6183 24 Oct 12 nicklas 936     @param table The ID or main table element
6183 24 Oct 12 nicklas 937     @param settingName The name of the setting that is used to store the
6183 24 Oct 12 nicklas 938       column visibility and order, if not specified the default is 'columns'
6183 24 Oct 12 nicklas 939   */
6188 30 Oct 12 nicklas 940   table.configureColumns = function(tableDiv, settingName)
6183 24 Oct 12 nicklas 941   {
6188 30 Oct 12 nicklas 942     tableDiv = Doc.element(tableDiv);
7982 14 Jun 21 nicklas 943     var frm = document.forms[tableDiv.id];
6188 30 Oct 12 nicklas 944     var itemType = Data.get(tableDiv, 'item-type');
6188 30 Oct 12 nicklas 945     var subContext = Data.get(tableDiv, 'subcontext', '');
6689 21 Jan 15 nicklas 946     var enableInheritedAnnotations = Data.get(tableDiv, 'inherited-annotations');
7842 01 Sep 20 nicklas 947     var enableRelatedItemColumns = Data.get(tableDiv, 'relateditem-columns');
7851 14 Oct 20 nicklas 948     var disableLinkedItemColumns = Data.get(tableDiv, 'no-linkeditem-columns');
6183 24 Oct 12 nicklas 949     
6183 24 Oct 12 nicklas 950     var url = App.getRoot()+'common/columns/configure.jsp?ID='+App.getSessionId();
6188 30 Oct 12 nicklas 951     url += '&table_id='+tableDiv.id+'&item_type='+itemType+'&subcontext='+subContext;
7851 14 Oct 20 nicklas 952     if (enableInheritedAnnotations) url += '&enableInheritedAnnotations=1';
7851 14 Oct 20 nicklas 953     if (enableRelatedItemColumns) url += '&enableRelatedItemColumns=1';
7851 14 Oct 20 nicklas 954     if (!disableLinkedItemColumns) url += '&enableLinkedItemColumns=1';
7982 14 Jun 21 nicklas 955     if (frm.sticky_column) url += '&enableStickyColumn=1';
7851 14 Oct 20 nicklas 956
6183 24 Oct 12 nicklas 957     if (settingName) url += '&settingName='+settingName;
6576 22 Oct 14 nicklas 958     Dialogs.openPopup(url, 'ConfigureColumns', 750, 450);
6183 24 Oct 12 nicklas 959   }
6183 24 Oct 12 nicklas 960
6183 24 Oct 12 nicklas 961   /**
6182 23 Oct 12 nicklas 962     Open a popup dialog that allows the user to save the current 
6182 23 Oct 12 nicklas 963     table settings to a named preset.
6182 23 Oct 12 nicklas 964     @param table The ID or main table element
6182 23 Oct 12 nicklas 965   */
6188 30 Oct 12 nicklas 966   table.saveCurrentContext = function(tableDiv)
1714 14 Dec 05 nicklas 967   {
6188 30 Oct 12 nicklas 968     tableDiv = Doc.element(tableDiv);
6188 30 Oct 12 nicklas 969     var itemType = Data.get(tableDiv, 'item-type');
6188 30 Oct 12 nicklas 970     var subContext = Data.get(tableDiv, 'subcontext', '');
6182 23 Oct 12 nicklas 971     var url = App.getRoot()+'common/context/saveas.jsp?ID='+App.getSessionId();
6182 23 Oct 12 nicklas 972     url += '&item_type='+itemType+'&subcontext='+subContext;
6182 23 Oct 12 nicklas 973     Dialogs.openPopup(url, 'SaveCurrentContext', 450, 300);
6182 23 Oct 12 nicklas 974   }
6183 24 Oct 12 nicklas 975   
6182 23 Oct 12 nicklas 976   /**
6182 23 Oct 12 nicklas 977     Open a popup dialog that allows the user to manage (eg. load or delete)
6182 23 Oct 12 nicklas 978     all table setting presets that have been saved for the given table.
6182 23 Oct 12 nicklas 979     @param table The ID or main table element
6182 23 Oct 12 nicklas 980   */
6188 30 Oct 12 nicklas 981   table.manageContexts = function(tableDiv)
6182 23 Oct 12 nicklas 982   {
6188 30 Oct 12 nicklas 983     tableDiv = Doc.element(tableDiv);
6188 30 Oct 12 nicklas 984     var itemType = Data.get(tableDiv, 'item-type');
6188 30 Oct 12 nicklas 985     var subContext = Data.get(tableDiv, 'subcontext', '');
6182 23 Oct 12 nicklas 986     var url = App.getRoot()+'common/context/manage.jsp?ID='+App.getSessionId();
6182 23 Oct 12 nicklas 987     url += '&item_type='+itemType+'&subcontext='+subContext;
6182 23 Oct 12 nicklas 988     Dialogs.openPopup(url, 'ManageContexts', 450, 300);
6182 23 Oct 12 nicklas 989   }
6183 24 Oct 12 nicklas 990   
6182 23 Oct 12 nicklas 991   /**
6182 23 Oct 12 nicklas 992     Load the table settings preset with the given id.
6182 23 Oct 12 nicklas 993     @param table The ID or main table element
6182 23 Oct 12 nicklas 994   */
6188 30 Oct 12 nicklas 995   table.loadContext = function(tableDiv, contextId)
6182 23 Oct 12 nicklas 996   {
6188 30 Oct 12 nicklas 997     tableDiv = Doc.element(tableDiv);
6188 30 Oct 12 nicklas 998     var frm = document.forms[tableDiv.id];
6182 23 Oct 12 nicklas 999     Forms.addHidden(frm, 'context', contextId);
6182 23 Oct 12 nicklas 1000     frm.cmd.value = 'LoadContext';
7894 08 Dec 20 nicklas 1001     Forms.submit(frm);
1714 14 Dec 05 nicklas 1002   }
6183 24 Oct 12 nicklas 1003   
6182 23 Oct 12 nicklas 1004   /**
6182 23 Oct 12 nicklas 1005     Change a table option and reload the table.
6182 23 Oct 12 nicklas 1006     
6182 23 Oct 12 nicklas 1007     @param table The ID or main table element
6182 23 Oct 12 nicklas 1008     @param name The name of the option
6182 23 Oct 12 nicklas 1009     @param value The value of the option
6182 23 Oct 12 nicklas 1010   */
6188 30 Oct 12 nicklas 1011   table.setOption = function(tableDiv, name, value)
1714 14 Dec 05 nicklas 1012   {
6188 30 Oct 12 nicklas 1013     tableDiv = Doc.element(tableDiv);
6188 30 Oct 12 nicklas 1014     var frm = document.forms[tableDiv.id];
6182 23 Oct 12 nicklas 1015     frm[name].value = value;
7894 08 Dec 20 nicklas 1016     Forms.submit(frm);
1714 14 Dec 05 nicklas 1017   }
1714 14 Dec 05 nicklas 1018
6183 24 Oct 12 nicklas 1019   
6188 30 Oct 12 nicklas 1020   /**
6188 30 Oct 12 nicklas 1021     Open a popup window with the given width and height
6188 30 Oct 12 nicklas 1022     and submit the table form (POST) to that popup.
6220 10 Jan 13 nicklas 1023     @param tableDiv The ID or main table element
6188 30 Oct 12 nicklas 1024     @param cmd The command value to use when sending the form
6188 30 Oct 12 nicklas 1025       (the old command is restored afterwards)
6188 30 Oct 12 nicklas 1026     @param width The width in pixels of the popup (may be scaled)
6188 30 Oct 12 nicklas 1027     @param height The height in pixels of the popup (may be scaled)
6188 30 Oct 12 nicklas 1028   */
6188 30 Oct 12 nicklas 1029   table.submitToPopup = function(tableDiv, cmd, width, height)
1714 14 Dec 05 nicklas 1030   {
6188 30 Oct 12 nicklas 1031     tableDiv = Doc.element(tableDiv);
6188 30 Oct 12 nicklas 1032     var frm = document.forms[tableDiv.id];
6183 24 Oct 12 nicklas 1033     var oldCmd = frm.cmd.value;
6188 30 Oct 12 nicklas 1034     var oldTarget = frm.target;
6183 24 Oct 12 nicklas 1035     frm.cmd.value = cmd;
6200 05 Nov 12 nicklas 1036     frm.target = tableDiv.id+cmd;
6188 30 Oct 12 nicklas 1037     Dialogs.openPopup('', frm.target, width, height);
6183 24 Oct 12 nicklas 1038     frm.submit();
6188 30 Oct 12 nicklas 1039     frm.target = oldTarget;
6183 24 Oct 12 nicklas 1040     frm.cmd.value = oldCmd;
1714 14 Dec 05 nicklas 1041   }
6182 23 Oct 12 nicklas 1042   
6188 30 Oct 12 nicklas 1043   /**
6289 05 Jun 13 nicklas 1044     Submit the table using the given cmd if there is 
6289 05 Jun 13 nicklas 1045     at least one item selected.
6289 05 Jun 13 nicklas 1046     @param tableDiv The ID or main table element
6289 05 Jun 13 nicklas 1047     @param cmd The command value to use when sending the form
6289 05 Jun 13 nicklas 1048     @param regexp A regular expression to use for matching checkboxes in the table,
6289 05 Jun 13 nicklas 1049       if not specified all checkboxes with a numeric name are used
6289 05 Jun 13 nicklas 1050    */
6289 05 Jun 13 nicklas 1051   table.submitSelected = function(tableDiv, cmd, regexp)
6289 05 Jun 13 nicklas 1052   {
6289 05 Jun 13 nicklas 1053     tableDiv = Doc.element(tableDiv);
6289 05 Jun 13 nicklas 1054     var frm = document.forms[tableDiv.id];
6289 05 Jun 13 nicklas 1055     if (!table.checkIfSelected(tableDiv, regexp))
6289 05 Jun 13 nicklas 1056     {
6289 05 Jun 13 nicklas 1057       return;
6289 05 Jun 13 nicklas 1058     }
6289 05 Jun 13 nicklas 1059     frm.cmd.value = cmd;
7894 08 Dec 20 nicklas 1060     Forms.submit(frm);
6289 05 Jun 13 nicklas 1061   }
6289 05 Jun 13 nicklas 1062   
6289 05 Jun 13 nicklas 1063   /**
6220 10 Jan 13 nicklas 1064     Submit a request to delete (or put in trashcan) all selected items
6220 10 Jan 13 nicklas 1065     in the table.
6220 10 Jan 13 nicklas 1066     @param tableDiv The ID or main table element
6220 10 Jan 13 nicklas 1067     @param regexp A regular expression to use for matching checkboxes in the table,
6220 10 Jan 13 nicklas 1068       if not specified all checkboxes with a numeric name are used
6260 27 Mar 13 nicklas 1069     @param confirmFirst If set, ask for confirmation before deleting the items
6220 10 Jan 13 nicklas 1070   */
6260 27 Mar 13 nicklas 1071   table.deleteItems = function(tableDiv, regexp, confirmFirst)
6220 10 Jan 13 nicklas 1072   {
6220 10 Jan 13 nicklas 1073     tableDiv = Doc.element(tableDiv);
6220 10 Jan 13 nicklas 1074     var frm = document.forms[tableDiv.id];
6260 27 Mar 13 nicklas 1075     var numSelected = table.checkIfSelected(tableDiv, regexp);
6260 27 Mar 13 nicklas 1076     if (numSelected == 0) return;
6260 27 Mar 13 nicklas 1077     if (confirmFirst)
6220 10 Jan 13 nicklas 1078     {
6220 10 Jan 13 nicklas 1079       if (!confirm('You are about to delete '+numSelected+' items. This can\'t be undone. Continue?'))
6220 10 Jan 13 nicklas 1080       {
6220 10 Jan 13 nicklas 1081         return;
6220 10 Jan 13 nicklas 1082       }
6220 10 Jan 13 nicklas 1083     }
6220 10 Jan 13 nicklas 1084     frm.cmd.value = 'DeleteItems';
7894 08 Dec 20 nicklas 1085     Forms.submit(frm);
6220 10 Jan 13 nicklas 1086   }
6220 10 Jan 13 nicklas 1087   
6220 10 Jan 13 nicklas 1088   /**
6220 10 Jan 13 nicklas 1089     Submit a request to undelete (remove from trashcan) all selected items
6220 10 Jan 13 nicklas 1090     in the table.
6220 10 Jan 13 nicklas 1091     @param tableDiv The ID or main table element
6220 10 Jan 13 nicklas 1092     @param regexp A regular expression to use for matching checkboxes in the table,
6220 10 Jan 13 nicklas 1093       if not specified all checkboxes with a numeric name are used
6220 10 Jan 13 nicklas 1094   */
6220 10 Jan 13 nicklas 1095   table.restoreItems = function(tableDiv, regexp)
6220 10 Jan 13 nicklas 1096   {
6220 10 Jan 13 nicklas 1097     tableDiv = Doc.element(tableDiv);
6220 10 Jan 13 nicklas 1098     var frm = document.forms[tableDiv.id];
6260 27 Mar 13 nicklas 1099     if (!table.checkIfSelected(tableDiv, regexp))
6220 10 Jan 13 nicklas 1100     {
6260 27 Mar 13 nicklas 1101       return;
6220 10 Jan 13 nicklas 1102     }
6220 10 Jan 13 nicklas 1103     frm.cmd.value = 'RestoreItems';
7894 08 Dec 20 nicklas 1104     Forms.submit(frm);
6220 10 Jan 13 nicklas 1105   }
6220 10 Jan 13 nicklas 1106
6220 10 Jan 13 nicklas 1107   
6220 10 Jan 13 nicklas 1108   /**
6188 30 Oct 12 nicklas 1109     Open a popup dialog that allows a user to select a new owner for
6188 30 Oct 12 nicklas 1110     all items that are selected in the given table. 
6188 30 Oct 12 nicklas 1111     @param tableDiv The ID or main table element
6188 30 Oct 12 nicklas 1112     @param regexp An optional regular expression matching the names
6188 30 Oct 12 nicklas 1113       of checkboxes that can be selected, if not specified it matches
6188 30 Oct 12 nicklas 1114       checkboxes with numeric names (eg. the name is the id of the item
6188 30 Oct 12 nicklas 1115       in the table)
6188 30 Oct 12 nicklas 1116    */
6188 30 Oct 12 nicklas 1117   table.setOwnerOfItems = function(tableDiv, regexp)
1714 14 Dec 05 nicklas 1118   {
6188 30 Oct 12 nicklas 1119     tableDiv = Doc.element(tableDiv);
6260 27 Mar 13 nicklas 1120     if (!table.checkIfSelected(tableDiv, regexp))
1714 14 Dec 05 nicklas 1121     {
6260 27 Mar 13 nicklas 1122       return;
1714 14 Dec 05 nicklas 1123     }
6188 30 Oct 12 nicklas 1124     table.submitToPopup(tableDiv, 'SetOwnerOfItems', 450, 300);
6188 30 Oct 12 nicklas 1125   } 
6188 30 Oct 12 nicklas 1126
6188 30 Oct 12 nicklas 1127   /**
6188 30 Oct 12 nicklas 1128     Open a popup dialog that allows a user to specify sharing permissions
6188 30 Oct 12 nicklas 1129     for all items that are selected in the given table. 
6188 30 Oct 12 nicklas 1130     @param tableDiv The ID or main table element
6188 30 Oct 12 nicklas 1131     @param regexp An optional regular expression matching the names
6188 30 Oct 12 nicklas 1132       of checkboxes that can be selected, if not specified it matches
6188 30 Oct 12 nicklas 1133       checkboxes with numeric names (eg. the name is the id of the item
6188 30 Oct 12 nicklas 1134       in the table)
6188 30 Oct 12 nicklas 1135    */
6188 30 Oct 12 nicklas 1136   table.shareItems = function(tableDiv, regexp)
6183 24 Oct 12 nicklas 1137   {
6188 30 Oct 12 nicklas 1138     tableDiv = Doc.element(tableDiv);
6260 27 Mar 13 nicklas 1139     if (!table.checkIfSelected(tableDiv, regexp))
1714 14 Dec 05 nicklas 1140     {
6260 27 Mar 13 nicklas 1141       return;
1714 14 Dec 05 nicklas 1142     }
6188 30 Oct 12 nicklas 1143     table.submitToPopup(tableDiv, 'ShareItems', 600, 400);
6188 30 Oct 12 nicklas 1144   }
6188 30 Oct 12 nicklas 1145
6220 10 Jan 13 nicklas 1146   /**
6694 26 Jan 15 nicklas 1147     Open a popup dialog that allows a user to bathc inherit annotations
6694 26 Jan 15 nicklas 1148     to all items that are selected in the given table. 
6694 26 Jan 15 nicklas 1149     @param tableDiv The ID or main table element
6694 26 Jan 15 nicklas 1150     @param regexp An optional regular expression matching the names
6694 26 Jan 15 nicklas 1151       of checkboxes that can be selected, if not specified it matches
6694 26 Jan 15 nicklas 1152       checkboxes with numeric names (eg. the name is the id of the item
6694 26 Jan 15 nicklas 1153       in the table)
6694 26 Jan 15 nicklas 1154    */
6694 26 Jan 15 nicklas 1155   table.inheritAnnotations = function(tableDiv, regexp)
6694 26 Jan 15 nicklas 1156   {
6694 26 Jan 15 nicklas 1157     tableDiv = Doc.element(tableDiv);
6694 26 Jan 15 nicklas 1158     if (!table.checkIfSelected(tableDiv, regexp))
6694 26 Jan 15 nicklas 1159     {
6694 26 Jan 15 nicklas 1160       return;
6694 26 Jan 15 nicklas 1161     }
6694 26 Jan 15 nicklas 1162     table.submitToPopup(tableDiv, 'InheritAnnotations', 750, 500);
6694 26 Jan 15 nicklas 1163   }
6694 26 Jan 15 nicklas 1164
6694 26 Jan 15 nicklas 1165   
6694 26 Jan 15 nicklas 1166   /**
6220 10 Jan 13 nicklas 1167     Open a popup window for selecting a plug-in that can run in the 
6220 10 Jan 13 nicklas 1168     current list context
6220 10 Jan 13 nicklas 1169     @param tableDiv The ID or main table element
6315 06 Sep 13 nicklas 1170     @param pluginType One of: IMPORT, EXPORT, ANALYZE or OTHER (default)
6315 06 Sep 13 nicklas 1171     @param cmd Override the default command for running the plugin
6220 10 Jan 13 nicklas 1172   */
6315 06 Sep 13 nicklas 1173   table.runPlugin = function(tableDiv, pluginType, cmd)
6220 10 Jan 13 nicklas 1174   {
6315 06 Sep 13 nicklas 1175     if (!cmd)
6220 10 Jan 13 nicklas 1176     {
6315 06 Sep 13 nicklas 1177       if (pluginType == 'EXPORT')
6315 06 Sep 13 nicklas 1178       {
6315 06 Sep 13 nicklas 1179         cmd = 'ExportItems';
6315 06 Sep 13 nicklas 1180       }
6315 06 Sep 13 nicklas 1181       else if (pluginType == 'IMPORT')
6315 06 Sep 13 nicklas 1182       {
6315 06 Sep 13 nicklas 1183         cmd = 'ImportItems';
6315 06 Sep 13 nicklas 1184       }
6315 06 Sep 13 nicklas 1185       else if (pluginType == 'ANALYZE')
6315 06 Sep 13 nicklas 1186       {
6315 06 Sep 13 nicklas 1187         cmd = 'RunListAnalysisPlugin';
6315 06 Sep 13 nicklas 1188       }
6315 06 Sep 13 nicklas 1189       else
6315 06 Sep 13 nicklas 1190       {
6315 06 Sep 13 nicklas 1191         cmd = 'RunListPlugin';
6315 06 Sep 13 nicklas 1192       }
6220 10 Jan 13 nicklas 1193     }
6220 10 Jan 13 nicklas 1194     table.submitToPopup(tableDiv, cmd, 750, 500);
6220 10 Jan 13 nicklas 1195   }
6188 30 Oct 12 nicklas 1196
6337 28 Oct 13 nicklas 1197   /**
6337 28 Oct 13 nicklas 1198     Toggle the selected status of a checkbox with 
6337 28 Oct 13 nicklas 1199     @param tableDiv The ID or main table element
6337 28 Oct 13 nicklas 1200     
6337 28 Oct 13 nicklas 1201     @returns The toggled  element or null if no element was found
6337 28 Oct 13 nicklas 1202   */
6337 28 Oct 13 nicklas 1203   table.toggleCheckBox = function(tableDiv, itemId)
6337 28 Oct 13 nicklas 1204   {
6337 28 Oct 13 nicklas 1205     tableDiv = Doc.element(tableDiv);
6337 28 Oct 13 nicklas 1206     var frm = document.forms[tableDiv.id];
7419 03 Nov 17 nicklas 1207
6337 28 Oct 13 nicklas 1208     for (var i=0; i < frm.elements.length; i++)
6337 28 Oct 13 nicklas 1209     {
6337 28 Oct 13 nicklas 1210       var element = frm.elements[i];
6337 28 Oct 13 nicklas 1211       if (element.type == 'checkbox' && element.name == itemId)
6337 28 Oct 13 nicklas 1212       {
6337 28 Oct 13 nicklas 1213         element.checked = !element.checked;
6576 22 Oct 14 nicklas 1214         Events.sendChangeEvent(element);
6337 28 Oct 13 nicklas 1215         return element;
6337 28 Oct 13 nicklas 1216       }
6337 28 Oct 13 nicklas 1217     }
6337 28 Oct 13 nicklas 1218     return null;
6337 28 Oct 13 nicklas 1219   }
6337 28 Oct 13 nicklas 1220
6337 28 Oct 13 nicklas 1221   /**
6337 28 Oct 13 nicklas 1222     Get the ID of all selected items in a table.
6337 28 Oct 13 nicklas 1223     
6337 28 Oct 13 nicklas 1224     @param tableDiv The ID or main table element
6337 28 Oct 13 nicklas 1225     @param regexp An optional regular expression matching the names
6337 28 Oct 13 nicklas 1226       of checkboxes that can be selected, if not specified it matches
6337 28 Oct 13 nicklas 1227       checkboxes with numeric names (eg. the name is the id of the item
6337 28 Oct 13 nicklas 1228       in the table)
6337 28 Oct 13 nicklas 1229     @return An array object with the ID:s
6337 28 Oct 13 nicklas 1230   */
6834 08 Apr 15 nicklas 1231   table.getSelected = function(tableDiv, regexp, messageIfNoneSelected)
6337 28 Oct 13 nicklas 1232   {
6337 28 Oct 13 nicklas 1233     tableDiv = Doc.element(tableDiv);
6337 28 Oct 13 nicklas 1234     if (!regexp) regexp = /\d+/;
6337 28 Oct 13 nicklas 1235
6337 28 Oct 13 nicklas 1236     var frm = document.forms[tableDiv.id];
6337 28 Oct 13 nicklas 1237     var items = [];
6337 28 Oct 13 nicklas 1238     if (frm.item_id)
6337 28 Oct 13 nicklas 1239     {
6337 28 Oct 13 nicklas 1240       // Radio buttons
6337 28 Oct 13 nicklas 1241       var element = Forms.getCheckedRadio(frm.item_id);
6337 28 Oct 13 nicklas 1242       if (element != null)
6337 28 Oct 13 nicklas 1243       {
6337 28 Oct 13 nicklas 1244         items[items.length] = element.value;
6337 28 Oct 13 nicklas 1245       }
6337 28 Oct 13 nicklas 1246     }
6337 28 Oct 13 nicklas 1247     else
6337 28 Oct 13 nicklas 1248     {
6337 28 Oct 13 nicklas 1249       // Checkboxes
6337 28 Oct 13 nicklas 1250       for (var i=0; i < frm.elements.length; i++)
6337 28 Oct 13 nicklas 1251       {
6337 28 Oct 13 nicklas 1252         var element = frm.elements[i];
6337 28 Oct 13 nicklas 1253         if (element.type == 'checkbox' && element.name.match(regexp) && element.checked)
6337 28 Oct 13 nicklas 1254         {
6337 28 Oct 13 nicklas 1255           items[items.length] = element.value;
6337 28 Oct 13 nicklas 1256         }
6337 28 Oct 13 nicklas 1257       }
6337 28 Oct 13 nicklas 1258     }
6834 08 Apr 15 nicklas 1259     
6834 08 Apr 15 nicklas 1260     if (items.length == 0 && messageIfNoneSelected)
6834 08 Apr 15 nicklas 1261     {
6834 08 Apr 15 nicklas 1262       Forms.showNotification(tableDiv.tableCheck, messageIfNoneSelected, null, 'pointer-left');
6834 08 Apr 15 nicklas 1263     }
6834 08 Apr 15 nicklas 1264     
6337 28 Oct 13 nicklas 1265     return items;
6337 28 Oct 13 nicklas 1266   }
6337 28 Oct 13 nicklas 1267
6222 14 Jan 13 nicklas 1268   
6222 14 Jan 13 nicklas 1269   /**
6222 14 Jan 13 nicklas 1270     Return the selected items to the parent window using either a callback
6222 14 Jan 13 nicklas 1271     method (older way) or an event notification (new way).
6222 14 Jan 13 nicklas 1272     
6337 28 Oct 13 nicklas 1273     @param tableDiv The ID or main table element
6337 28 Oct 13 nicklas 1274     @param regexp An optional regular expression matching the names
6337 28 Oct 13 nicklas 1275       of checkboxes that can be selected, if not specified it matches
6337 28 Oct 13 nicklas 1276       checkboxes with numeric names (eg. the name is the id of the item
6337 28 Oct 13 nicklas 1277       in the table)
6222 14 Jan 13 nicklas 1278
6222 14 Jan 13 nicklas 1279     @return The number of selected items
6222 14 Jan 13 nicklas 1280   */
6222 14 Jan 13 nicklas 1281   table.returnSelectedItems = function(tableDiv, regexp)
6222 14 Jan 13 nicklas 1282   {
6222 14 Jan 13 nicklas 1283     tableDiv = Doc.element(tableDiv);
6222 14 Jan 13 nicklas 1284     if (!regexp) regexp = /\d+/;
6222 14 Jan 13 nicklas 1285     
6222 14 Jan 13 nicklas 1286     var frm = document.forms[tableDiv.id];
6291 11 Jun 13 nicklas 1287     var itemType = Data.get(tableDiv, 'item-type');
6222 14 Jan 13 nicklas 1288     
6222 14 Jan 13 nicklas 1289     // Should we use 'callback method' or 'event notification'?
6308 20 Aug 13 nicklas 1290     var callback = frm.callback ? frm.callback.value : null;
6308 20 Aug 13 nicklas 1291     var notifyTarget = callback ? window.top.opener.document.getElementById(callback) : null;
6308 20 Aug 13 nicklas 1292     var callbackMethod = callback ? window.top.opener[callback] : null;
6222 14 Jan 13 nicklas 1293     
6308 20 Aug 13 nicklas 1294     if (!notifyTarget && !callbackMethod) 
6308 20 Aug 13 nicklas 1295     {
6308 20 Aug 13 nicklas 1296       notifyTarget = tableDiv;
6308 20 Aug 13 nicklas 1297     }
6308 20 Aug 13 nicklas 1298     
6576 22 Oct 14 nicklas 1299     var selected = [];
6222 14 Jan 13 nicklas 1300     if (frm.item_id)
6222 14 Jan 13 nicklas 1301     {
6222 14 Jan 13 nicklas 1302       // Radio buttons allow single selection
6222 14 Jan 13 nicklas 1303       var element = Forms.getCheckedRadio(frm.item_id);
6222 14 Jan 13 nicklas 1304       if (element != null)
6222 14 Jan 13 nicklas 1305       {
6372 06 Dec 13 nicklas 1306         var id = element.value.match(/^\d+$/) ? parseInt(element.value) : element.value;
6576 22 Oct 14 nicklas 1307         selected[selected.length] = {'id': id, 'name': element.title, 'itemType': itemType};
6222 14 Jan 13 nicklas 1308       }
6222 14 Jan 13 nicklas 1309     }
6222 14 Jan 13 nicklas 1310     else
6222 14 Jan 13 nicklas 1311     {
6222 14 Jan 13 nicklas 1312       // Check boxes allow multiple selections
6308 20 Aug 13 nicklas 1313       for (var i=0; i < frm.elements.length; i++)
6222 14 Jan 13 nicklas 1314       {
6222 14 Jan 13 nicklas 1315         var element = frm.elements[i];
6222 14 Jan 13 nicklas 1316         if (element.type == 'checkbox' && element.name.match(regexp) && element.checked)
6222 14 Jan 13 nicklas 1317         {
6372 06 Dec 13 nicklas 1318           var id = element.value.match(/^\d+$/) ? parseInt(element.value) : element.value;
6576 22 Oct 14 nicklas 1319           selected[selected.length] = {'id': id, 'name': element.title, 'itemType': itemType};
6222 14 Jan 13 nicklas 1320         }
6222 14 Jan 13 nicklas 1321       }
6222 14 Jan 13 nicklas 1322     }
6576 22 Oct 14 nicklas 1323     
6576 22 Oct 14 nicklas 1324     var remaining = selected.length-1;
6770 13 Mar 15 nicklas 1325     if (notifyTarget)
6770 13 Mar 15 nicklas 1326     {
6770 13 Mar 15 nicklas 1327       Events.sendCustomEvent(notifyTarget, 'base-selected-start', { 'numSelected': selected.length });
6770 13 Mar 15 nicklas 1328     }
6576 22 Oct 14 nicklas 1329     for (var i = 0; i < selected.length; i++)
6576 22 Oct 14 nicklas 1330     {
6576 22 Oct 14 nicklas 1331       var s = selected[i];
6576 22 Oct 14 nicklas 1332       s.remaining = remaining--;
6576 22 Oct 14 nicklas 1333       if (notifyTarget)
6576 22 Oct 14 nicklas 1334       {
6576 22 Oct 14 nicklas 1335         // Send event to the target in the opener window
6576 22 Oct 14 nicklas 1336         Events.sendCustomEvent(notifyTarget, 'base-selected', s);
6576 22 Oct 14 nicklas 1337       }
6576 22 Oct 14 nicklas 1338       else if (callbackMethod)
6576 22 Oct 14 nicklas 1339       {
6576 22 Oct 14 nicklas 1340         // Call the callback method in the opener window
6576 22 Oct 14 nicklas 1341         callbackMethod.call(null, s.id, s.name);
6576 22 Oct 14 nicklas 1342       }
6576 22 Oct 14 nicklas 1343     }
6576 22 Oct 14 nicklas 1344
6576 22 Oct 14 nicklas 1345     return selected.length;
6222 14 Jan 13 nicklas 1346   }
6222 14 Jan 13 nicklas 1347
6260 27 Mar 13 nicklas 1348   table.checkIfSelected = function(tableDiv, regexp, messageIfNoneSelected)
6260 27 Mar 13 nicklas 1349   {
6260 27 Mar 13 nicklas 1350     tableDiv = Doc.element(tableDiv);
6260 27 Mar 13 nicklas 1351     var frm = document.forms[tableDiv.id];
6260 27 Mar 13 nicklas 1352     var numSelected = Forms.numChecked(frm, regexp);
6260 27 Mar 13 nicklas 1353     if (numSelected == 0)
6260 27 Mar 13 nicklas 1354     {
6260 27 Mar 13 nicklas 1355       if (!messageIfNoneSelected) 
6260 27 Mar 13 nicklas 1356       {
6260 27 Mar 13 nicklas 1357         messageIfNoneSelected = 'Please select at least one item in the list';
6260 27 Mar 13 nicklas 1358       }
6834 08 Apr 15 nicklas 1359       Forms.showNotification(tableDiv.tableCheck, messageIfNoneSelected, null, 'pointer-left');
6260 27 Mar 13 nicklas 1360     }
6260 27 Mar 13 nicklas 1361     return numSelected;
6260 27 Mar 13 nicklas 1362   }
6222 14 Jan 13 nicklas 1363
6182 23 Oct 12 nicklas 1364   return table;
6182 23 Oct 12 nicklas 1365 }();
1775 16 Jan 06 nicklas 1366
417 19 Apr 05 nicklas 1367