[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Phpgroupware-cvs] sitemgr inc/class.Categories_BO.inc.php inc/cla... [s
From: |
Dave Hall |
Subject: |
[Phpgroupware-cvs] sitemgr inc/class.Categories_BO.inc.php inc/cla... [skwashd-16-compat] |
Date: |
Mon, 27 Mar 2006 13:13:25 +0000 |
CVSROOT: /cvsroot/phpgroupware
Module name: sitemgr
Branch: skwashd-16-compat
Changes by: Dave Hall <address@hidden> 06/03/27 13:13:24
Modified files:
inc : class.Categories_BO.inc.php
class.Categories_SO.inc.php
class.Categories_UI.inc.php
class.Category_SO.inc.php
class.Content_BO.inc.php
class.Content_UI.inc.php class.Sites_BO.inc.php
class.Sites_SO.inc.php class.module.inc.php
modules : class.module_html.inc.php
setup : setup.inc.php tables_current.inc.php
tables_update.inc.php
sitemgr-site : index.php
sitemgr-site/inc: class.sitebo.inc.php
templates/default: edit_category.tpl
Added files:
inc/api : README class.javascript.inc.php
class.richtext.inc.php
js/columnlist : columnlist.css columnlist.js sortabletable.js
js/columnlist/original: api.html api.xml columnlist.html
demo.html demo2.html implementation.html
usage.html
js/columnlist/original/article-images: ie.png moz.png
js/columnlist/original/images: asc.png desc.png
js/columnlist/original/includes: columnlist.css columnlist.js
sortabletable.js
js/columnlist/original/local: helptip.css helptip.js
title-background.png webfxapi.css
webfxapi.js webfxlayout.css
webfxlayout.js
Log message:
A few changes:
* multiple wysiwyg editor support
* template by cat option
* better cats editor (WIP)
* little bit of polish here and there
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/inc/class.Categories_BO.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.6.2.2.4.1&tr2=1.6.2.2.4.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/inc/class.Categories_SO.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.13.2.5.4.1&tr2=1.13.2.5.4.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/inc/class.Categories_UI.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.1.2.1.4.1&tr2=1.1.2.1.4.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/inc/class.Category_SO.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.4.10.1&tr2=1.4.10.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/inc/class.Content_BO.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.2.2.1&tr2=1.2.2.1.4.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/inc/class.Content_UI.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.3.2.4.2.2&tr2=1.3.2.4.2.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/inc/class.Sites_BO.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.7.2.1&tr2=1.7.2.1.4.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/inc/class.Sites_SO.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.2.2.3&tr2=1.2.2.3.4.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/inc/class.module.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.8.2.2.4.1&tr2=1.8.2.2.4.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/inc/api/README?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/inc/api/class.javascript.inc.php?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/inc/api/class.richtext.inc.php?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/columnlist.css?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/columnlist.js?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/sortabletable.js?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/api.html?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/api.xml?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/columnlist.html?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/demo.html?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/demo2.html?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/implementation.html?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/usage.html?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/article-images/ie.png?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/article-images/moz.png?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/images/asc.png?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/images/desc.png?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/includes/columnlist.css?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/includes/columnlist.js?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/includes/sortabletable.js?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/local/helptip.css?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/local/helptip.js?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/local/title-background.png?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/local/webfxapi.css?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/local/webfxapi.js?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/local/webfxlayout.css?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/js/columnlist/original/local/webfxlayout.js?only_with_tag=skwashd-16-compat&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/modules/class.module_html.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.1.2.2.4.1&tr2=1.1.2.2.4.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/setup/setup.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.12.2.2.4.2&tr2=1.12.2.2.4.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/setup/tables_current.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.11.2.1.4.1&tr2=1.11.2.1.4.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/setup/tables_update.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.11.2.4.4.1&tr2=1.11.2.4.4.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/sitemgr-site/index.php.diff?only_with_tag=skwashd-16-compat&tr1=1.7.2.2.4.1&tr2=1.7.2.2.4.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/sitemgr-site/inc/class.sitebo.inc.php.diff?only_with_tag=skwashd-16-compat&tr1=1.1.2.3&tr2=1.1.2.3.4.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/phpgroupware/sitemgr/templates/default/edit_category.tpl.diff?only_with_tag=skwashd-16-compat&tr1=1.6.2.2.4.1&tr2=1.6.2.2.4.2&r1=text&r2=text
Patches:
Index: sitemgr/inc/api/README
diff -u /dev/null sitemgr/inc/api/README:1.1.2.1
--- /dev/null Mon Mar 27 13:13:24 2006
+++ sitemgr/inc/api/README Mon Mar 27 13:13:24 2006
@@ -0,0 +1,3 @@
+These files need to be copied to phpgwapi/inc
+
+richtext is new and javascript is a drop in replacement
Index: sitemgr/inc/api/class.javascript.inc.php
diff -u /dev/null sitemgr/inc/api/class.javascript.inc.php:1.1.2.1
--- /dev/null Mon Mar 27 13:13:24 2006
+++ sitemgr/inc/api/class.javascript.inc.php Mon Mar 27 13:13:24 2006
@@ -0,0 +1,241 @@
+<?php
+ /**
+ * Javascript support class
+ * @author Dave Hall <address@hidden>
+ * @copyright Portions Copyright (C) 2003,2004 Free Software Foundation,
Inc http://www.fsf.org/
+ * @license http://www.fsf.org/licenses/gpl.html GNU General Public
License
+ * @package phpgwapi
+ * @subpackage gui
+ * @version $Id: class.javascript.inc.php,v 1.1.2.1 2006/03/27 13:13:24
skwashd Exp $
+ * @link http://docs.phpgroupware.org/wiki/classJavaScript
+ */
+
+ /**
+ * phpGroupWare javascript support class
+ *
+ * Only instanstiate this class using:
+ * <code>
+ * if(address@hidden($GLOBALS['phpgw']->js))
+ * {
+ * $GLOBALS['phpgw']->js = CreateObject('phpgwapi.javascript');
+ * }
+ * </code>
+ *
+ * This way a theme can see if this is a defined object and include the
data,
+ * while the is_object() wrapper prevents whiping out existing data held
in
+ * this instance variables, primarily the $files variable.
+ *
+ * Note: The package arguement is the subdirectory of js - all js should
live in subdirectories
+ *
+ * @package phpgwapi
+ * @subpackage gui
+ * @uses template
+ */
+ class javascript
+ {
+ /**
+ * @var array elements to be used for the window.on* events
+ */
+ var $win_events = array
+ (
+ 'load' => array(),
+ 'unload' => array()
+ );
+
+ /**
+ * @var array list of validated files to be included in the head
section of a page
+ */
+ var $files;
+
+ /**
+ * @var object used for holding an instance of the Template class
+ */
+ var $t;
+
+ /**
+ * Constructor
+ *
+ * Initialize the instance variables
+ */
+ function javascript()
+ {
+ }
+
+ /**
+ * Set a window.on?? event
+ *
+ * @param string $event the name of the event
+ * @param string $code the code to be called
+ */
+ function add_event($event, $code)
+ {
+ if ( !isset($this->win_events[$event]) )
+ {
+ $this->win_events[$event] = array();
+ }
+ $this->win_events[$event][] = $code;
+ }
+
+ /**
+ * Returns the javascript required for displaying a popup
message box
+ *
+ * @param string $msg the message to be displayed to user
+ * @returns string the javascript to be used for displaying the
message
+ */
+ function get_alert($msg)
+ {
+ return 'return alert("'.lang($msg).'");';
+ }
+
+ /**
+ * Returns the javascript required for displaying a confirmation
message box
+ *
+ * @param string $msg the message to be displayed to user
+ * @returns string the javascript to be used for displaying the
message
+ */
+ function get_confirm($msg)
+ {
+ return 'return confirm("'.lang($msg).'");';
+ }
+
+ /**
+ * Used for generating the list of external js files to be
included in the head of a page
+ *
+ * NOTE: This method should only be called by the template class.
+ * The validation is done when the file is added so we don't
have to worry now
+ *
+ * @returns string the html needed for importing the js into a
page
+ */
+ function get_script_links()
+ {
+ $links = '';
+ if(!empty($this->files) && is_array($this->files))
+ {
+ $links = "<!--JS Imports from phpGW javascript
class -->\n";
+ foreach($this->files as $app => $packages)
+ {
+ if(!empty($packages) &&
is_array($packages))
+ {
+ foreach($packages as $pkg =>
$files)
+ {
+ if(!empty($files) &&
is_array($files))
+ {
+ foreach($files
as $file => $ignored)
+ {
+ $links
.= '<script type="text/javascript" '
+ .
"src=\"{$GLOBALS['phpgw_info']['server']['webserver_url']}/{$app}/js/{$pkg}/{$file}.js\">"
+ .
"</script>\n";
+ }
+ }
+ }
+ }
+ }
+ }
+ $links .= "<script type=\"text/javascript\">\n" .
$this->get_win_on_events() . "\n</script>\n";
+ return $links;
+ }
+
+ /**
+ * @deprecated
+ */
+ function get_body_attribs()
+ {
+ return '';
+ }
+
+
+ /**
+ * Creates the javascript for handling window.on* events
+ *
+ * @returns string the attributes to be used
+ */
+ function get_win_on_events()
+ {
+ $ret_str = "\n//<![CDATA[\n// start phpGW javascript
class imported window.on* event handlers\n";
+ foreach ( $this->win_events as $win_event => $actions )
+ {
+ if ( is_array($actions) && count($actions) )
+ {
+ $ret_str .= "window.on{$win_event} =
function()\n{\n";
+ foreach ( $actions as $action )
+ {
+ $ret_str .= "\t$action\n";
+ }
+ $ret_str .= "}\n";
+ }
+ }
+ $ret_str .= "\n// end phpGW javascript class imported
window.on* event handlers\n//]]>\n\n";
+ return $ret_str;
+ }
+
+ /**
+ * Sets an onLoad action for a page
+ *
+ * @deprecated
+ * @param string javascript to be used
+ */
+ function set_onload($code)
+ {
+ $this->win_events['load'][] = $code;
+ }
+
+ /**
+ * Sets an onUnload action for a page
+ *
+ * @deprecated
+ * @param string javascript to be used
+ */
+ function set_onunload($code)
+ {
+ $this->events['unload'][] = $code;
+ }
+
+ /**
+ * DO NOT USE - NOT SURE IF I AM GOING TO USE IT - ALSO IT NEEDS
SOME CHANGES!!!!
+ * Used for removing a file or package of files to be included
in the head section of a page
+ *
+ * @param string $app application to use
+ * @param string $package the name of the package to be removed
+ * @param string $file the name of a file in the package to be
removed - if ommitted package is removed
+ */
+ function unset_script_link($app, $package, $file=False)
+ {
+ /* THIS DOES NOTHING ATM :P
+ if($file !== False)
+ {
+ unset($this->files[$app][$package][$file]);
+ }
+ else
+ {
+ unset($this->files[$app][$package]);
+ }
+ */
+ }
+
+ /**
+ * Checks to make sure a valid package and file name is provided
+ *
+ * @param string $package package to be included
+ * @param string $file file to be included - no ".js" on the end
+ * @param string $app application directory to search - default
= phpgwapi
+ * @returns bool was the file found?
+ */
+ function validate_file($package, $file, $app='phpgwapi')
+ {
+ if(is_readable(PHPGW_INCLUDE_ROOT .
"/$app/js/$package/$file.js"))
+ {
+ $this->files[$app][$package][$file] = True;
+ return True;
+ }
+ elseif($app != 'phpgwapi')
+ {
+ if(is_readable(PHPGW_INCLUDE_ROOT .
"/phpgwapi/js/$package/$file.js"))
+ {
+
$this->files['phpgwapi'][$package][$file] = True;
+ return True;
+ }
+ return False;
+ }
+ }
+ }
+?>
Index: sitemgr/inc/api/class.richtext.inc.php
diff -u /dev/null sitemgr/inc/api/class.richtext.inc.php:1.1.2.1
--- /dev/null Mon Mar 27 13:13:24 2006
+++ sitemgr/inc/api/class.richtext.inc.php Mon Mar 27 13:13:24 2006
@@ -0,0 +1,276 @@
+<?php
+ /**
+ * Rich Text Editor Handler class
+ *
+ * Allows different rich text wysiwyg html editors to be used within
phpgw
+ *
+ * @author Dave Hall skwashd at phpgroupware.org
+ * @copyright Copyright (C) 2006 Free Software Foundation, Inc.
http://www.fsf.org/
+ * @license http://www.fsf.org/licenses/gpl.html GNU General Public
License
+ * @package phpgwapi
+ * @subpackage gui
+ * @version $Id: class.richtext.inc.php,v 1.1.2.1 2006/03/27 13:13:24
skwashd Exp $
+ */
+
+ //This is done here for 16 support
+ $GLOBALS['phpgw_info']['server']['enable_fckeditor'] = true;
+ $GLOBALS['phpgw_info']['server']['enable_tinymce'] = true;
+ $GLOBALS['phpgw_info']['user']['preferences']['common']['rteditor'] =
'tinymce';
+
+ /**
+ * Rich Text Editor Handler class
+ *
+ * @package phpgwapi
+ * @subpackage gui
+ */
+ class richtext
+ {
+ /**
+ * @var the base URL for all links, defaults to phpgw url
+ */
+ var $base_url;
+
+ /**
+ * @var string $rte which rich text editor will be used
+ */
+ var $rte;
+
+ /**
+ * @var array $targets the targets which will be replaced by the
rich text editor
+ */
+ var $targets = array();
+
+ /**
+ * @constructor
+ */
+ function richtext()
+ {
+ $this->base_url =
$GLOBALS['phpgw_info']['server']['webserver_url'];
+ $this->rte = '';
+ if(!is_object($GLOBALS['phpgw']->js))
+ {
+ $GLOBALS['phpgw']->js =
createObject('phpgwapi.javascript');
+ }
+ $this->_init_head();
+ $GLOBALS['phpgw']->js->validate_file('jscalendar',
'calendar_stripped');
+ }
+
+ /**
+ * Generate the dynamic script content for the header
+ */
+ function generate_script()
+ {
+ if ( count($this>targets) )
+ {
+ switch($this->rte)
+ {
+ case 'fckeditor':
+
$this->_generate_script_fckeditor();
+ break;
+
+ case 'tinymce':
+
$this->_generate_script_tinymce();
+ break;
+ default:
+ //do nothing
+ }
+ }
+ }
+
+ /**
+ * Replaces an element with a rich text editor instance
+ */
+ function replace_element($html_id)
+ {
+ $this->targets[$html_id] = true; //stops duplicates :)
+ }
+
+ /**
+ * Set the base URL for all links
+ */
+ function set_base_url($url)
+ {
+ $this->base_url = $url;
+ }
+
+ /**
+ * Generate the js needed for FCKeditor to function properly
+ */
+ function _generate_script_fckeditor()
+ {
+ $str = '';
+
+ foreach ( $this->targets as $target => $crap )
+ {
+ $str .= "var oFCKeditor_{$target} = new
FCKeditor( '{$target}' ) ;\n" .
+
"oFCKeditor_{$target}.AutoDetectLanguage = false;\n" .
+ "oFCKeditor_{$target}.BaseHref
= '{$this->base_url}';\n" .
+ "oFCKeditor_{$target}.BasePath
=
'{$GLOBALS['phpgw_info']['server']['webserver_url']}/phpgwapi/js/fckeditor/';\n"
.
+
"oFCKeditor_{$target}.DefaultLanguage =
'{$GLOBALS['phpgw_info']['user']['preferences']['common']['lang']}';\n" .
+
"oFCKeditor_{$target}.GeckoUseSPAN = false;\n" .
+
"oFCKeditor_{$target}.SpellChecker = '" . (extension_loaded('pspell') ?
'SpellerPages' : 'ieSpell') . "';\n" .
+
"oFCKeditor_{$target}.ReplaceTextarea();\n\n";
+ }
+ $GLOBALS['phpgw']->js->add_event('load', $str);
+ }
+
+ /**
+ * Generate the js needed for tiny to function properly
+ */
+ function _generate_script_tinymce()
+ {
+ $str = "<script
type=\"text/javascript\">\n//<![CDATA[\n" .
+ "tinyMCE.init({\n" .
+ "\t\tdocument_base_url :
'{$this->base_url}',\n" .
+ "\t\tinline_styles : false,\n" .
+ "\t\tlanguage :
'{$GLOBALS['phpgw_info']['user']['preferences']['common']['lang']}',\n" .
+ "\t\tmode : 'none',\n" .
+ "\t\ttheme : 'advanced',\n" .
+ "\t\ttheme_advanced_toolbar_align :
'left',\n" .
+ "\t\ttheme_advanced_toolbar_location :
'top',\n" .
+ //FIXME make this more configrable
(using array? and unset?)
+ "\t\tvalid_elements : ''" . '
++"a[accesskey|charset|class|coords|dir<ltr?rtl|href|hreflang|id|lang|name|rel|rev|shape<circle?default?poly?rect|tabindex|title|target|type],"
++"abbr[class|dir<ltr?rtl|id|lang|title],"
++"acronym[class|dir<ltr?rtl|id|id|lang|title],"
++"address[class|align|dir<ltr?rtl|id|lang|title],"
++"area[accesskey|alt|class|coords|dir<ltr?rtl|href|id|lang|nohref<nohref|shape<circle?default?poly?rect|tabindex|title|target],"
++"bdo[class|dir<ltr?rtl|id|lang|title],"
++"big[class|dir<ltr?rtl|id|lang|title],"
++"blockquote[dir|cite|class|dir<ltr?rtl|id|lang|title],"
++"body[alink|background|bgcolor|class|dir<ltr?rtl|id|lang|link|title|text|vlink],"
++"br[class|clear<all?left?none?right|id|title],"
++"button[accesskey|class|dir<ltr?rtl|disabled<disabled|id|lang|name|tabindex|title|type|value],"
++"caption[align<bottom?left?right?top|class|dir<ltr?rtl|id|lang|title],"
++"cite[class|dir<ltr?rtl|id|lang|title],"
++"code[class|dir<ltr?rtl|id|lang|title],"
++"col[align<center?char?justify?left?right|char|charoff|class|dir<ltr?rtl|id|lang|span|title|valign<baseline?bottom?middle?top|width],"
++"colgroup[align<center?char?justify?left?right|char|charoff|class|dir<ltr?rtl|id|lang|span|title|valign<baseline?bottom?middle?top|width],"
++"dd[class|dir<ltr?rtl|id|lang|title],"
++"del[cite|class|datetime|dir<ltr?rtl|id|lang|title],"
++"dfn[class|dir<ltr?rtl|id|lang|title],"
++"dir[class|compact<compact|dir<ltr?rtl|id|lang|title],"
++"div[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|title],"
++"dl[class|compact<compact|dir<ltr?rtl|id|lang|title],"
++"dt[class|dir<ltr?rtl|id|lang|title],"
++"em/i[class|dir<ltr?rtl|id|lang|title],"
++"fieldset[class|dir<ltr?rtl|id|lang|title],"
++"font[class|color|dir<ltr?rtl|face|id|lang|size|title],"
++"form[accept|accept-charset|action|class|dir<ltr?rtl|enctype|id|lang|method<get?post|name|title|target],"
++"h1[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|title],"
++"h2[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|title],"
++"h3[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|title],"
++"h4[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|title],"
++"h5[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|title],"
++"h6[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|title],"
++"hr[align<center?left?right|class|dir<ltr?rtl|id|lang|noshade<noshade|size|title|width],"
++"img[align<bottom?left?middle?right?top|alt|border|class|dir<ltr?rtl|height|hspace|id|ismap<ismap|lang|longdesc|name|src|title|usemap|vspace|width],"
++"input[accept|accesskey|align<bottom?left?middle?right?top|alt|checked<checked|class|dir<ltr?rtl|disabled<disabled|id|ismap<ismap|lang|maxlength|name|readonly<readonly|size|src|tabindex|title|type<button?checkbox?file?hidden?image?password?radio?reset?submit?text|usemap|value],"
++"ins[cite|class|datetime|dir<ltr?rtl|id|lang|title],"
++"isindex[class|dir<ltr?rtl|id|lang|prompt|title],"
++"kbd[class|dir<ltr?rtl|id|lang|title],"
++"label[accesskey|class|dir<ltr?rtl|for|id|lang|title],"
++"legend[align<bottom?left?right?top|accesskey|class|dir<ltr?rtl|id|lang|title],"
++"li[class|dir<ltr?rtl|id|lang|title|type|value],"
++"link[charset|class|dir<ltr?rtl|href|hreflang|id|lang|media|rel|rev|title|target|type],"
++"map[class|dir<ltr?rtl|id|lang|name|title],"
++"menu[class|compact<compact|dir<ltr?rtl|id|lang|title],"
++"object[align<bottom?left?middle?right?top|archive|border|class|classid|codebase|codetype|data|declare|dir<ltr?rtl|height|hspace|id|lang|name|standby|tabindex|title|type|usemap|vspace|width],"
++"ol[class|compact<compact|dir<ltr?rtl|id|lang|start|title|type],"
++"optgroup[class|dir<ltr?rtl|disabled<disabled|id|label|lang|title],"
++"option[class|dir<ltr?rtl|disabled<disabled|id|label|lang|selected<selected|title|value],"
++"p[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|title],"
++"param[id|name|type|value|valuetype<DATA?OBJECT?REF],"
++"pre/listing/plaintext/xmp[align|class|dir<ltr?rtl|id|lang|title|width],"
++"q[cite|class|dir<ltr?rtl|id|lang|title],"
++"s[class|dir<ltr?rtl|id|lang|title],"
++"samp[class|dir<ltr?rtl|id|lang|title],"
++"select[class|dir<ltr?rtl|disabled<disabled|id|lang|multiple<multiple|name|size|tabindex|title],"
++"small[class|dir<ltr?rtl|id|lang|title],"
++"span[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|title],"
++"strike[class|class|dir<ltr?rtl|id|lang|title],"
++"strong/b[class|dir<ltr?rtl|id|lang|title],"
++"style[dir<ltr?rtl|lang|media|title|type],"
++"sub[class|dir<ltr?rtl|id|lang|title],"
++"sup[class|dir<ltr?rtl|id|lang|title],"
++"table[align<center?left?right|bgcolor|border|cellpadding|cellspacing|class|dir<ltr?rtl|frame|height|id|lang|rules|summary|title|width],"
++"tbody[align<center?char?justify?left?right|char|class|charoff|dir<ltr?rtl|id|lang|title|valign<baseline?bottom?middle?top],"
++"td[abbr|align<center?char?justify?left?right|axis|bgcolor|char|charoff|class|colspan|dir<ltr?rtl|headers|height|id|lang|nowrap<nowrap|rowspan|scope<col?colgroup?row?rowgroup|title|valign<baseline?bottom?middle?top|width],"
++"textarea[accesskey|class|cols|dir<ltr?rtl|disabled<disabled|id|lang|name|readonly<readonly|rows|tabindex|title],"
++"tfoot[align<center?char?justify?left?right|char|charoff|class|dir<ltr?rtl|id|lang|title|valign<baseline?bottom?middle?top],"
++"th[abbr|align<center?char?justify?left?right|axis|bgcolor|char|charoff|class|colspan|dir<ltr?rtl|headers|height|id|lang|nowrap<nowrap|rowspan|scope<col?colgroup?row?rowgroup|title|valign<baseline?bottom?middle?top|width],"
++"thead[align<center?char?justify?left?right|char|charoff|class|dir<ltr?rtl|id|lang|title|valign<baseline?bottom?middle?top],"
++"title[dir<ltr?rtl|lang],"
++"tr[abbr|align<center?char?justify?left?right|bgcolor|char|charoff|class|rowspan|dir<ltr?rtl|id|lang|title|valign<baseline?bottom?middle?top],"
++"tt[class|dir<ltr?rtl|id|lang|title],"
++"u[class|dir<ltr?rtl|id|lang|title],"
++"ul[class|compact<compact|dir<ltr?rtl|id|lang|title|type],"
++"var[class|dir<ltr?rtl|id|lang|title]"'
+ . "});\n"
+ . "\n//]]>\n</script>\n";
+ foreach ( $this->targets as $target => $crap )
+ {
+ //$str .=
"\ttinyMCE.execCommand('mceAddControl', true, {$target});\n";
+ }
+ $str .= "\n\n";
+
+ $GLOBALS['phpgw_info']['flags']['java_script'] .= $str;
+ //$GLOBALS['phpgw']->js->add_event('load', $str);
+
+ foreach ( $this->targets as $target => $crap )
+ {
+ $GLOBALS['phpgw']->js->add_event('load',
"\ttinyMCE.execCommand('mceAddControl', true, '{$target}');\n");
+ }
+ }
+
+ /**
+ * Add the appropriate <script>s to the <head> section
+ *
+ * @access private
+ */
+ function _init_head()
+ {
+ if (
!isset($GLOBALS['phpgw_info']['user']['preferences']['common']['rteditor'])
+ ||
$GLOBALS['phpgw_info']['user']['preferences']['common']['rteditor'] == 'none' )
+ {
+ //nothing to do here as the user doesn't want
to use a rte
+ return true;
+ }
+ $rte_name =
$GLOBALS['phpgw_info']['user']['preferences']['common']['rteditor'];
+
+ if ( isset($GLOBALS['phpgw_info']['server']['enable_' .
$rte_name]) )
+ {
+ //now that we know that the user is allowed to
use it we init it
+ switch($rte_name)
+ {
+ case 'fckeditor':
+ $this->_init_fckeditor();
+ break;
+ case 'tinymce':
+ $this->_init_tinymce();
+ break;
+ default:
+ //do nothing
+ }
+ }
+ }
+
+ /**
+ * Prepare FCKeditor to be used in a page
+ */
+ function _init_fckeditor()
+ {
+ $GLOBALS['phpgw']->js->validate_file('fckeditor',
'fckeditor');
+ $this->rte = 'fckeditor';
+ }
+
+ /**
+ * Prepare tinymce to be used in a page
+ */
+ function _init_tinymce()
+ {
+ $GLOBALS['phpgw']->js->validate_file('tinymce',
'tiny_mce');
+ $this->rte = 'tinymce';
+ }
+ }
+?>
Index: sitemgr/inc/class.Categories_BO.inc.php
diff -u sitemgr/inc/class.Categories_BO.inc.php:1.6.2.2.4.1
sitemgr/inc/class.Categories_BO.inc.php:1.6.2.2.4.2
--- sitemgr/inc/class.Categories_BO.inc.php:1.6.2.2.4.1 Sat Nov 12 13:15:37 2005
+++ sitemgr/inc/class.Categories_BO.inc.php Mon Mar 27 13:13:24 2006
@@ -170,7 +170,7 @@
return True;
}
- function saveCategoryInfo($cat_id, $cat_name, $cat_description,
$lang, $sort_order, $state, $parent=False, $old_parent=False, $def_page = 0)
+ function saveCategoryInfo($cat_id, $cat_name, $cat_description,
$lang, $sort_order, $state, $parent=False, $old_parent=False, $def_page = 0,
$cat_tpl = '')
{
if (!$parent)
{
@@ -185,6 +185,7 @@
$cat_info->parent = $parent;
$cat_info->old_parent = $old_parent ? $old_parent :
$parent;
$cat_info->def_page = $def_page;
+ $cat_info->cat_tpl = $cat_tpl;
if
($GLOBALS['Common_BO']->acl->can_write_category($cat_id))
{
Index: sitemgr/inc/class.Categories_SO.inc.php
diff -u sitemgr/inc/class.Categories_SO.inc.php:1.13.2.5.4.1
sitemgr/inc/class.Categories_SO.inc.php:1.13.2.5.4.2
--- sitemgr/inc/class.Categories_SO.inc.php:1.13.2.5.4.1 Sat Nov 12
13:15:37 2005
+++ sitemgr/inc/class.Categories_SO.inc.php Mon Mar 27 13:13:24 2006
@@ -82,7 +82,8 @@
$this->cats->edit($data);
$this->db->query('UPDATE phpgw_sitemgr_categories_state'
. ' SET state = ' .
intval($cat_info->state) . ','
- . ' def_page = ' .
intval($cat_info->def_page)
+ . ' def_page = ' .
intval($cat_info->def_page) . ','
+ . " template_set = '" .
$this->db->db_addslashes($cat_info->cat_tpl) . "'"
. ' WHERE cat_id = ' .
intval($cat_info->id), __LINE__,__FILE__);
}
@@ -138,14 +139,16 @@
$cat_info->root = $cat[0]['main'];
$cat_info->state = 0;
$cat_info->def_page = 0;
+ $cat_info->cat_tpl = '';
- $this->db->query('SELECT state, def_page FROM
phpgw_sitemgr_categories_state'
+ $this->db->query('SELECT state, def_page,
template_set FROM phpgw_sitemgr_categories_state'
. ' WHERE cat_id=' .
intval($cat_id), __LINE__, __FILE__);
if ( $this->db->next_record() )
{
$cat_info->state =
$this->db->f('state');
$cat_info->def_page =
$this->db->f('def_page');
+ $cat_info->cat_tpl =
$this->db->f('template_set');
}
if ($lang)
@@ -157,8 +160,8 @@
if ($this->db->next_record())
{
- $cat_info->name =
$this->db->f('name');
- $cat_info->description =
$this->db->f('description');
+ $cat_info->name =
$this->db->f('name', true);
+ $cat_info->description =
$this->db->f('description', true);
}
// else
// {
@@ -174,9 +177,9 @@
. ' WHERE cat_id=' .
intval($cat_id), __LINE__, __FILE__);
if ($this->db->next_record())
{
- $cat_info->name =
$this->db->f('name');
- $cat_info->description =
$this->db->f('description');
- $cat_info->lang =
$this->db->f('lang');
+ $cat_info->name =
$this->db->f('name', true);
+ $cat_info->description =
$this->db->f('description', true);
+ $cat_info->lang =
$this->db->f('lang', true);
}
else
{
Index: sitemgr/inc/class.Categories_UI.inc.php
diff -u sitemgr/inc/class.Categories_UI.inc.php:1.1.2.1.4.1
sitemgr/inc/class.Categories_UI.inc.php:1.1.2.1.4.2
--- sitemgr/inc/class.Categories_UI.inc.php:1.1.2.1.4.1 Sat Nov 12 13:15:37 2005
+++ sitemgr/inc/class.Categories_UI.inc.php Mon Mar 27 13:13:24 2006
@@ -35,6 +35,41 @@
$this->sitelanguages =
$GLOBALS['Common_BO']->sites->current_site['sitelanguages'];
}
+ function delete()
+ {
+ if (!$this->isadmin)
+ {
+
$GLOBALS['phpgw']->redirect($GLOBALS['phpgw']->link('/index.php','menuaction=sitemgr.Outline_UI.manage'));
+ return;
+ }
+
+
$GLOBALS['Common_BO']->globalize(array('btnDelete','btnCancel'));
+ global $btnDelete,$btnCancel;
+ $cat_id = $_GET['cat_id'];
+
+ if ($btnDelete)
+ {
+ $this->cat_bo->removeCategory($cat_id);
+
$GLOBALS['phpgw']->redirect($GLOBALS['phpgw']->link('/index.php','menuaction=sitemgr.Outline_UI.manage'));
+ return;
+ }
+ if ($btnCancel)
+ {
+
$GLOBALS['phpgw']->redirect($GLOBALS['phpgw']->link('/index.php','menuaction=sitemgr.Outline_UI.manage'));
+ return;
+ }
+
+ $this->common_ui->DisplayHeader();
+
+ $cat =
$this->cat_bo->getCategory($cat_id,$this->sitelanguages[0]);
+ $this->t->set_file('ConfirmDelete','confirmdelete.tpl');
+ $this->t->set_var('deleteheader',lang('Are you sure you
want to delete the category %1 and all of its associated pages? You cannot
retrieve the deleted pages if you continue.',$cat->name));
+ $this->t->set_var('cat_id',$cat_id);
+ $this->t->set_var('lang_yes',lang('Yes, please delete
it'));
+ $this->t->set_var('lang_no',lang('Cancel the delete'));
+ $this->t->pfp('out','ConfirmDelete');
+ }
+
function edit()
{
if (!$this->isadmin)
@@ -46,19 +81,23 @@
$cat_id = isset($_REQUEST['cat_id']) &&
$_REQUEST['cat_id'] ? $_REQUEST['cat_id'] : 0;
$cat_id = isset($_REQUEST['inputcatid']) &&
$_REQUEST['inputcatid'] ? $_REQUEST['inputcatid'] : $cat_id;
- if (isset($_POST['btnSave']) && $_POST['btnSave']
- && isset($_POST['inputcatname']) &&
$_POST['inputcatname']
- && isset($_POST['inputcatdesc']) &&
$_POST['inputcatdesc'] )
+ if (isset($_POST['btnSave']) && $_POST['btnSave'] )
{
if ( $_POST['inputcatname'] == '' ||
$_POST['inputcatdesc'] == '')
{
$error = lang('You failed to fill in
one or more required fields.');
$this->t->set_var('message', $error);
+ $cat = new Category_SO();
+ $cat->id = $cat_id;
+ $cat->name = $_POST['inputcatname'];
+ $cat->description =
$_POST['inputcatdesc'];
+ $cat->sort_order =
$_POST['inputsortorder'];
+ $cat->parent = $_POST['inputparent'];
+ $cat->state = $_POST['inputstate'];
}
else
{
$cat_id = $cat_id ? $cat_id :
$this->cat_bo->addCategory('','');
-
$groupaccess =
array_merge_recursive($_POST['inputgroupaccessread'],
$_POST['inputgroupaccesswrite']);
$individualaccess =
array_merge_recursive($_POST['inputindividualaccessread'],
$_POST['inputindividualaccesswrite']);
$savelanguage =
isset($_POST['savelanguage']) && $_POST['savelanguage'] ?
$_POST['savelanguage'] : $this->sitelanguages[0];
@@ -70,10 +109,11 @@
$_POST['inputstate'],
$_POST['inputparent'],
$_POST['inputparentold'],
-
$_POST['def_page']
+
$_POST['def_page'],
+
$_POST['cat_tpl']
);
- if (
isset($_POST['inputgetparentpermissions']) &&
$_POST['inputgetparentpermissions'] )
+ if ( isset($_POST['permissions']) &&
$_POST['permissions'] == 'parent' )
{
$this->cat_bo->saveCategoryPermsfromparent($cat_id);
}
@@ -82,7 +122,7 @@
$this->cat_bo->saveCategoryPerms($cat_id, $groupaccess, $individualaccess);
}
- if (
isset($_POST['inputapplypermissionstosubs']) &&
$_POST['inputapplypermissionstosubs'] )
+ if ( isset($_POST['permissionstosubs'])
&& $_POST['permissionstosubs'] )
{
$this->cat_bo->applyCategoryPermstosubs($cat_id);
}
@@ -95,7 +135,7 @@
//we use force here since we might edit an
archive category
$cat =
$this->cat_bo->getCategory($cat_id,$this->sitelanguages[0],True);
}
-
+
$this->t->set_file('EditCategory', 'edit_category.tpl');
$this->t->set_block('EditCategory','GroupBlock',
'GBlock');
@@ -127,12 +167,14 @@
'cat_id' => $cat_id,
'catname' => $cat->name,
'catdesc' =>
$cat->description,
+ 'cat_tpl' =>
$this->get_cat_tpl_list($cat->cat_tpl),
'sort_order' =>
$cat->sort_order,
'def_page' =>
$def_page_list,
- 'parent_dropdown' =>
$this->getParentOptions($cat->parent,$cat_id),
+ 'parent_dropdown' =>
$this->get_parent_options($cat->parent,$cat_id),
'stateselect' =>
$GLOBALS['Common_BO']->inputstateselect($cat->state),
'old_parent' => $cat->parent,
'lang_basic' => lang('Basic
Settings'),
+ 'lang_cat_tpl' =>
lang('template for category'),
'lang_catname' =>
lang('Category Name'),
'lang_catsort' => lang('Sort
Order'),
'lang_catparent' =>
lang('Parent'),
@@ -174,10 +216,10 @@
$permission_id = 0;
}
- $this->t->set_var('groupname',
$account_name);
+ $this->t->set_var('groupname', lang('%1
group', $account_name));
if ($permission_id & PHPGW_ACL_READ)
{
-
$this->t->set_var('checkedgroupread','CHECKED');
+
$this->t->set_var('checkedgroupread','checked="checked"');
}
else
{
@@ -185,7 +227,7 @@
}
if ($permission_id & PHPGW_ACL_ADD)
{
-
$this->t->set_var('checkedgroupwrite','CHECKED');
+
$this->t->set_var('checkedgroupwrite','checked="checked"');
}
else
{
@@ -208,7 +250,7 @@
{
for($i = 0; $i < count($userlist); $i++ )
{
- $user_name =
$userlist[$i]['account_lid'];
+ $user_name =
$userlist[$i]['account_firstname'] . ' ' . $userlist[$i]['account_lastname'] ;
$user_id = $userlist[$i]['account_id'];
if ($cat_id)
{
@@ -223,7 +265,7 @@
$this->t->set_var('username',
$user_name);
if ($user_permission_id &
PHPGW_ACL_READ )
{
-
$this->t->set_var('checkeduserread','CHECKED');
+
$this->t->set_var('checkeduserread','checked="checked"');
}
else
{
@@ -231,7 +273,7 @@
}
if ($user_permission_id & PHPGW_ACL_ADD
)
{
-
$this->t->set_var('checkeduserwrite','CHECKED');
+
$this->t->set_var('checkeduserwrite','checked="checked"');
}
else
{
@@ -249,19 +291,31 @@
$this->common_ui->DisplayFooter();
}
+
+ function get_cat_tpl_list($cat_tpl)
+ {
+ $str = '<option value="">' . lang('site template') .
"</option>\n";
+ foreach
($GLOBALS['Common_BO']->theme->getAvailableThemes() as $tpl )
+ {
+ $str .= "<option value=\"{$tpl['value']}\""
+ . ($tpl['value'] == $cat_tpl ?
'selected="selected"' : '')
+
.">{$tpl['display']}</option>\n";
+ }
+ return $str;
+ }
- function getParentOptions($selected_id=0,$skip_id=0)
+ function get_parent_options($selected_id=0,$skip_id=0)
{
$option_list=$this->cat_bo->getCategoryOptionList();
if (!$selected_id)
{
- $selected=' SELECTED';
+ $selected=' selected="selected"';
}
if (!$skip_id)
{
$skip_id = -1;
}
- $retval="\n".'<SELECT NAME="inputparent">'."\n";
+ $retval="\n".'<select name="inputparent"
id="inputparent">'."\n";
foreach($option_list as $option)
{
if ($option['value']!=$skip_id)
@@ -269,49 +323,14 @@
$selected='';
if ($option['value']==$selected_id)
{
- $selected=' SELECTED';
+ $selected='
selected="selected"';
}
- $retval.='<OPTION
VALUE="'.$option['value'].'"'.$selected.'>'.
-
$option['display'].'</OPTION>'."\n";
+ $retval.='<option
value="'.$option['value'].'"'.$selected.'>'.
+
$option['display'].'</option>'."\n";
}
}
- $retval.='</SELECT>';
+ $retval.='</select>';
return $retval;
}
-
- function delete()
- {
- if (!$this->isadmin)
- {
-
$GLOBALS['phpgw']->redirect($GLOBALS['phpgw']->link('/index.php','menuaction=sitemgr.Outline_UI.manage'));
- return;
- }
-
-
$GLOBALS['Common_BO']->globalize(array('btnDelete','btnCancel'));
- global $btnDelete,$btnCancel;
- $cat_id = $_GET['cat_id'];
-
- if ($btnDelete)
- {
- $this->cat_bo->removeCategory($cat_id);
-
$GLOBALS['phpgw']->redirect($GLOBALS['phpgw']->link('/index.php','menuaction=sitemgr.Outline_UI.manage'));
- return;
- }
- if ($btnCancel)
- {
-
$GLOBALS['phpgw']->redirect($GLOBALS['phpgw']->link('/index.php','menuaction=sitemgr.Outline_UI.manage'));
- return;
- }
-
- $this->common_ui->DisplayHeader();
-
- $cat =
$this->cat_bo->getCategory($cat_id,$this->sitelanguages[0]);
- $this->t->set_file('ConfirmDelete','confirmdelete.tpl');
- $this->t->set_var('deleteheader',lang('Are you sure you
want to delete the category %1 and all of its associated pages? You cannot
retrieve the deleted pages if you continue.',$cat->name));
- $this->t->set_var('cat_id',$cat_id);
- $this->t->set_var('lang_yes',lang('Yes, please delete
it'));
- $this->t->set_var('lang_no',lang('Cancel the delete'));
- $this->t->pfp('out','ConfirmDelete');
- }
}
?>
Index: sitemgr/inc/class.Category_SO.inc.php
diff -u sitemgr/inc/class.Category_SO.inc.php:1.4.10.1
sitemgr/inc/class.Category_SO.inc.php:1.4.10.2
--- sitemgr/inc/class.Category_SO.inc.php:1.4.10.1 Sat Nov 12 13:15:37 2005
+++ sitemgr/inc/class.Category_SO.inc.php Mon Mar 27 13:13:24 2006
@@ -9,6 +9,7 @@
var $depth;
var $root;
var $def_page;
+ var $cat_tpl;
function Category_SO()
{
Index: sitemgr/inc/class.Content_BO.inc.php
diff -u /dev/null sitemgr/inc/class.Content_BO.inc.php:1.2.2.1.4.1
--- /dev/null Mon Mar 27 13:13:24 2006
+++ sitemgr/inc/class.Content_BO.inc.php Mon Mar 27 13:13:24 2006
@@ -0,0 +1,339 @@
+<?php
+
+require_once(PHPGW_INCLUDE_ROOT . SEP . 'sitemgr' . SEP . 'inc' . SEP .
'class.module.inc.php');
+
+define('SITEMGR_STATE_DRAFT',0);
+define('SITEMGR_STATE_PREPUBLISH',1);
+define('SITEMGR_STATE_PUBLISH',2);
+define('SITEMGR_STATE_PREUNPUBLISH',3);
+define('SITEMGR_STATE_ARCHIVE',4);
+
+define('SITEMGR_VIEWABLE_EVERBODY',0);
+define('SITEMGR_VIEWABLE_USER',1);
+define('SITEMGR_VIEWABLE_ADMIN',2);
+define('SITEMGR_VIEWABLE_ANONYMOUS',3);
+ class Content_BO
+ {
+ var $so;
+
+ function Content_BO()
+ {
+ $this->so = CreateObject('sitemgr.Content_SO', true);
+ }
+
+ function getContentAreas()
+ {
+ $theme =
$GLOBALS['Common_BO']->sites->current_site['themesel'];
+
+ if ( isset($_REQUEST['cat_id']) && $_REQUEST['cat_id'] )
+ {
+ $cat =
$GLOBALS['Common_BO']->cats->getCategory($_REQUEST['cat_id']);
+ if ( isset($cat->cat_tpl) && $cat->cat_tpl )
+ {
+ $theme = $cat->cat_tpl;
+ }
+ }
+ elseif ( isset($_REQUEST['page_id']) &&
$_REQUEST['page_id'])
+ {
+ $page =
$GLOBALS['Common_BO']->pages->getPage($_GET['page_id']);
+ if ( isset($page->cat_id) && $page->cat_id )
+ {
+ $cat =
$GLOBALS['Common_BO']->cats->getCategory($page->cat_id);
+ if ( isset($cat->cat_tpl) &&
$cat->cat_tpl )
+ {
+ $theme = $cat->cat_tpl;
+ }
+ }
+ }
+
+ $templatefile =
"{$GLOBALS['Common_BO']->sites->current_site['site_dir']}/templates/{$theme}/main.tpl";
+
+ if (file_exists($templatefile))
+ {
+ $str = implode('', @file($templatefile));
+ if (preg_match_all("/\{contentarea:([^{
]+)\}/",$str,$matches))
+ {
+ return $matches[1];
+ }
+ else
+ {
+ return lang('No content areas found in
selected template');
+ }
+ }
+ else
+ {
+ return lang('No template file found.');
+ }
+ }
+
+
+ function addblock($block)
+ {
+ $permittedmoduleids =
array_keys($GLOBALS['Common_BO']->modules->getcascadingmodulepermissions($block->area,$block->cat_id));
+ $module =
$GLOBALS['Common_BO']->modules->getmodule($block->module_id);
+
+ if
($GLOBALS['Common_BO']->acl->can_write_category($block->cat_id) &&
+ in_array($block->module_id,$permittedmoduleids)
&&
+
$GLOBALS['Common_BO']->modules->createmodule($module['module_name']))
+ {
+ return $this->so->addblock($block);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function createversion($blockid)
+ {
+ return $this->so->createversion($blockid);
+ }
+
+ function deleteversion($versionid,$force=False)
+ {
+ if (!$force)
+ {
+ $blockid =
$this->so->getblockidforversion($versionid);
+ if (!$blockid)
+ {
+ return false;
+ }
+ $block = $this->so->getblockdef($blockid);
+ if (!($block &&
$GLOBALS['Common_BO']->acl->can_write_category($block->cat_id)))
+ {
+ return false;
+ }
+ }
+ return $this->so->deleteversion($versionid);
+ }
+
+ function removeBlocksInPageOrCat($cat_id,$page_id,$force=False)
+ {
+ if (!($force ||
$GLOBALS['Common_BO']->acl->can_write_category($cat_id)))
+ {
+ return false;
+ }
+ $blocks =
$this->so->getblocksforscope($cat_id,$page_id);
+ while(list($blockid,) = each($blocks))
+ {
+ $this->removeblock($blockid,True);
+ }
+ }
+
+ function removeblock($blockid,$force=False)
+ {
+ if (!$force)
+ {
+ $block = $this->so->getblockdef($blockid);
+ if (!($block &&
$GLOBALS['Common_BO']->acl->can_write_category($block->cat_id)))
+ {
+ return false;
+ }
+ }
+ if ($this->so->removeblock($blockid))
+ {
+ $versions =
$this->so->getversionidsforblock($blockid);
+ while(list(,$versionid) = @each($versions))
+ {
+ //since we already did the ACL we force
+ $this->deleteversion($versionid,True);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ //the next two functions retrieves all blocks for a certain
area, if (cat_id = $site_id and page_id = 0), only site-wide blocks are
retrieved.
+ //if (cat_id != $site_id and page_id is 0), site-wide blocks
and all blocks for the category and all its ancestor categories are retrieved.
+ //if page_id is non zero, cat_id should be the page's category.
Page blocks + category blocks + site blocks are retrieved.
+ //there is no ACL, since these functions are called in a
context where getcategory and getpage have been called before and would have
intercepted a breach
+ function
getvisibleblockdefsforarea($area,$cat_id,$page_id,$isadmin,$isuser)
+ {
+ $cat_ancestorlist = ($cat_id != CURRENT_SITE_ID) ?
+
$GLOBALS['Common_BO']->cats->getCategoryancestorids($cat_id,True) :
+ False;
+ return
$this->so->getvisibleblockdefsforarea($area,$cat_ancestorlist,$page_id,$isadmin,$isuser);
+ }
+
+ function getallblocksforarea($area,$cat_id,$page_id,$lang)
+ {
+ $cat_ancestorlist = ($cat_id != CURRENT_SITE_ID) ?
+
$GLOBALS['Common_BO']->cats->getCategoryancestorids($cat_id,True) :
+ False;
+ return
$this->so->getallblocksforarea($area,$cat_ancestorlist,$page_id,$lang);
+ }
+
+ function getcommitableblocks()
+ {
+ return
$this->so->getallblocks($GLOBALS['Common_BO']->cats->getpermittedcatsWrite(),$GLOBALS['Common_BO']->getstates('Commit'));
+ }
+
+ function getarchivedblocks()
+ {
+ return
$this->so->getallblocks($GLOBALS['Common_BO']->cats->getpermittedcatsWrite(),$GLOBALS['Common_BO']->getstates('Archive'));
+ }
+ function getallversionsforblock($blockid,$lang)
+ {
+ return
$this->so->getallversionsforblock($blockid,$lang);
+ }
+
+ function getblock($id,$lang)
+ {
+ //do we need ACL here, since we have ACL when getting
the block lists, we could do without it here?
+ return $this->so->getblock($id,$lang);
+ }
+
+ function getlangblocktitle($block_id,$lang=false)
+ {
+ return
$this->so->getlangblocktitle($block_id,$lang);
+ }
+
+ function getlangarrayforblocktitle($block_id)
+ {
+ return $this->so->getlangarrayforblocktitle($block_id);
+ }
+
+ function getlangarrayforversion($version_id)
+ {
+ return $this->so->getlangarrayforversion($version_id);
+ }
+
+ //this function retrieves blocks only for a certain scope
(site-wide, specific to one category or specific to one page),
+ //but for all areas.
+ function getblocksforscope($cat_id,$page_id)
+ {
+ if ($cat_id &&
!$GLOBALS['Common_BO']->acl->can_read_category($cat_id))
+ {
+ return array();
+ }
+ else
+ {
+ return
$this->so->getblocksforscope($cat_id,$page_id);
+ }
+ }
+
+ function getversion($version_id,$lang=False)
+ {
+ //TODO: add ACL ?
+ return $this->so->getversion($version_id,$lang);
+ }
+
+ function saveblockdata($block,$data,$state,$lang)
+ {
+ $oldblock = $this->so->getblockdef($block->id);
+ if (!($oldblock &&
$GLOBALS['Common_BO']->acl->can_write_category($oldblock->cat_id)))
+ {
+ return lang("You are not entitled to edit block
%1",$block->id);
+ }
+ $this->so->saveblockdata($block);
+
$this->so->saveblockdatalang($block->id,$block->title,$lang);
+ if (!$this->saveversionstate($block->id,$state))
+ {
+ $validationerrors[] = lang('There can only be
one version in (pre(un))published state, with the one exeption that one
prepublished version can coexist with one preunpublished version');
+ }
+ $moduleobject = $this->getblockmodule($block->id);
+ while (list($versionid,$versiondata) = @each($data))
+ {
+ if ($moduleobject->validate($versiondata))
+ {
+ if
($this->saveversiondatalang($block->id,$versionid,$versiondata['i18n'],$lang))
+ {
+ unset($versiondata['i18n']);
+
$this->so->saveversiondata($block->id,$versionid,$versiondata);
+ }
+ }
+ if ($moduleobject->validation_error)
+ {
+ $validationerrors[] =
$moduleobject->validation_error;
+ }
+ }
+ return $validationerrors ? $validationerrors : True;
+ }
+
+ function saveblockdatalang($block,$data,$lang)
+ {
+ $oldblock = $this->so->getblockdef($block->id);
+ if (!($oldblock &&
$GLOBALS['Common_BO']->acl->can_write_category($oldblock->cat_id)))
+ {
+ return lang("You are not entitled to edit block
%1",$block->id);
+ }
+
$this->so->saveblockdatalang($block->id,$block->title,$lang);
+ $moduleobject = $this->getblockmodule($block->id);
+ while (list($versionid,$versiondata) = @@each($data))
+ //TODO: check if version really belongs to block
+ {
+ if ($moduleobject->validate($versiondata))
+ {
+
$this->saveversiondatalang($block->id,$versionid,$versiondata['i18n'],$lang);
+ }
+ else
+ {
+ $validationerrors[] =
$moduleobject->validation_error;
+ }
+ }
+ return $validationerrors ? $validationerrors : True;
+ }
+
+ //takes the array (version_id => version_state) posted from the
UI as argument
+ //and checks if there is only one in (pre(un))published state
+ //(exeption one prepublished, and one preunpublished can
coexsit)
+ function saveversionstate($block_id,$state)
+ {
+ $count_array = array_count_values($state);
+ $active_versions =
$count_array[SITEMGR_STATE_PREPUBLISH] +
+ $count_array[SITEMGR_STATE_PUBLISH] +
+ $count_array[SITEMGR_STATE_PREUNPUBLISH];
+ if (($active_versions < 2) || (($active_versions == 2)
&& ($count_array[SITEMGR_STATE_PUBLISH] == 0)))
+ {
+ while (list($versionid,$versionstate) =
each($state))
+ {
+
$this->so->saveversionstate($block_id,$versionid,$versionstate);
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function saveversiondatalang($block_id,$version_id,$data,$lang)
+ {
+ return ($this->so->getblockidforversion($version_id) ==
$block_id) ?
+
$this->so->saveversiondatalang($version_id,$data,$lang) :
+ false;
+ }
+
+ //this function can be called from a block's get_content
function. It stores modification to the
+ //blocks arguments in the database
+ function savepublicdata(&$block)
+ {
+ //TODO: check if argument is public, disentangle
session data from arguments
+
$this->so->saveversiondata($block->id,$block->version,$block->arguments);
+ }
+
+ function getblockmodule($blockid)
+ {
+ $block = $this->so->getblockdef($blockid);
+ return
$GLOBALS['Common_BO']->modules->createmodule($block->module_name);
+ }
+
+ function commit($block_id)
+ {
+ $block = $this->so->getblockdef($block_id);
+ if
($GLOBALS['Common_BO']->acl->can_write_category($block->cat_id))
+ {
+ $this->so->commit($block_id);
+ }
+ }
+
+ function reactivate($block_id)
+ {
+ $block = $this->so->getblockdef($block_id);
+ if
($GLOBALS['Common_BO']->acl->can_write_category($block->cat_id))
+ {
+ $this->so->reactivate($block_id);
+ }
+ }
+ }
+?>
Index: sitemgr/inc/class.Content_UI.inc.php
diff -u sitemgr/inc/class.Content_UI.inc.php:1.3.2.4.2.2
sitemgr/inc/class.Content_UI.inc.php:1.3.2.4.2.3
--- sitemgr/inc/class.Content_UI.inc.php:1.3.2.4.2.2 Fri Dec 9 00:40:38 2005
+++ sitemgr/inc/class.Content_UI.inc.php Mon Mar 27 13:13:24 2006
@@ -72,7 +72,12 @@
{
$GLOBALS['phpgw']->js =
createObject('phpgwapi.javascript');
}
- $GLOBALS['phpgw']->js->validate_file('fckeditor',
'fckeditor', 'news_admin');
+
+ if ( !isset($GLOBALS['phpgw']->richtext) ||
!is_object($GLOBALS['phpgw']->richtext) )
+ {
+ $GLOBALS['phpgw']->richtext =&
createObject('phpgwapi.richtext');
+ }
+
$GLOBALS['phpgw']->richtext->set_base_url($GLOBALS['Common_BO']->sites->current_site['site_url']);
$GLOBALS['Common_BO']->globalize(array(
'inputblockid','inputblocktitle','inputblocksort','inputblockview',
@@ -221,7 +226,6 @@
return;
}
- $this->common_ui->DisplayHeader();
$this->t->set_file('Managecontent',
'manage_content.tpl');
$this->t->set_file('Blocks','edit_block.tpl');
@@ -237,7 +241,6 @@
'page_or_cat_name' => ($page_or_cat_name ? (' -
' . $page_or_cat_name) : '')
));
-
$contentareas = $this->bo->getContentAreas();
if (is_array($contentareas))
{
@@ -292,6 +295,8 @@
{
$this->t->set_var('CBlock',$contentareas);
}
+ $GLOBALS['phpgw']->richtext->generate_script();
+ $this->common_ui->DisplayHeader();
$this->t->pfp('out', 'Managecontent');
$this->common_ui->DisplayFooter();
}
Index: sitemgr/inc/class.Sites_BO.inc.php
diff -u /dev/null sitemgr/inc/class.Sites_BO.inc.php:1.7.2.1.4.1
--- /dev/null Mon Mar 27 13:13:24 2006
+++ sitemgr/inc/class.Sites_BO.inc.php Mon Mar 27 13:13:24 2006
@@ -0,0 +1,229 @@
+<?php
+ /**************************************************************************\
+ * phpGroupWare - phpgroupware SiteMgr *
+ * http://www.phpgroupware.org *
+ * -------------------------------------------- *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU General Public License as published by the *
+ * Free Software Foundation; either version 2 of the License, or (at your *
+ * option) any later version. *
+ \**************************************************************************/
+
+ /* $Id: class.Sites_BO.inc.php,v 1.7.2.1.4.1 2006/03/27 13:13:24 skwashd Exp
$ */
+
+ class Sites_BO
+ {
+
+ var $xml_functions = array();
+ var $soap_functions = array();
+
+ var $debug = False;
+
+ var $so = '';
+ var $start = 0;
+ var $query = '';
+ var $sort = '';
+ var $order = '';
+ var $total = 0;
+
+ var $current_site;
+ var $number_of_sites;
+
+ var $use_session = False;
+
+ function Sites_BO($session=False)
+ {
+ //Web site definitions are stored as top level
categories
+ $this->so = CreateObject('sitemgr.Sites_SO');
+
+ if($session)
+ {
+ $this->read_sessiondata();
+ $this->use_session = True;
+ }
+
+ foreach(array('start','query','sort','order') as $var)
+ {
+ if (isset($_REQUEST[$var]))
+ {
+ $this->$var = $_REQUEST[$var];
+ }
+ }
+ }
+
+ function save_sessiondata($data)
+ {
+ if ($this->use_session)
+ {
+ if($this->debug) { echo '<br>Save:';
_debug_array($data); }
+
$GLOBALS['phpgw']->session->appsession('session_data','sitemgr_sites',$data);
+ }
+ }
+
+ function read_sessiondata()
+ {
+ $data =
$GLOBALS['phpgw']->session->appsession('session_data','sitemgr_sites');
+ if($this->debug) { echo '<br>Read:';
_debug_array($data); }
+
+ $this->start = $data['start'];
+ $this->query = $data['query'];
+ $this->sort = $data['sort'];
+ $this->order = $data['order'];
+ }
+
+ function list_sites($limit=True)
+ {
+ return
$this->so->getWebsites($limit,$this->start,$this->sort,$this->order,$this->query,$this->total);
+ }
+
+ function getnumberofsites()
+ {
+ return $this->so->getnumberofsites();
+ }
+
+ function read($id)
+ {
+ $result = $this->so->read($id);
+ if ($result)
+ {
+ $result['sitelanguages'] =
$result['site_languages'] ? explode(',',$result['site_languages']) :
array('en');;
+ foreach($result['sitelanguages'] as $lang)
+ {
+ $langinfo =
$GLOBALS['Common_BO']->cats->getCategory($id,$lang,True);
+ $result['site_name_' . $lang] =
$langinfo->name;
+ $result['site_desc_' . $lang] =
$langinfo->description;
+ }
+ return $result;
+ }
+ else
+ {
+ return False;
+ }
+ }
+
+ function get_adminlist($site_id)
+ {
+ return
$GLOBALS['Common_BO']->acl->get_permission_list($site_id);
+ }
+
+ function add($site)
+ {
+ $site_id = $this->so->add($site);
+
//$GLOBALS['Common_BO']->cats->saveCategoryLang($site_id,
$site['name'],$site['description'],$site['savelang']);
+
$GLOBALS['Common_BO']->acl->set_adminlist($site_id,$site['adminlist']);
+ return $site_id;
+ }
+
+ function update($site_id,$site)
+ {
+ $this->so->update($site_id,$site);
+
+
$GLOBALS['Common_BO']->acl->set_adminlist($site_id,$site['adminlist']);
+ }
+
+ function saveprefs($prefs)
+ {
+ $this->so->saveprefs($prefs);
+ $sitelanguages = $this->current_site['site_languages']
?
+
explode(',',$this->current_site['site_languages']) :
+ array('en');
+ foreach ($sitelanguages as $lang)
+ {
+ $GLOBALS['Common_BO']->cats->saveCategoryLang(
+ CURRENT_SITE_ID,
+ $prefs['site_name_' . $lang],
+ $prefs['site_desc_' . $lang],
+ $lang
+ );
+ }
+ $this->current_site = $this->read(CURRENT_SITE_ID);
+ }
+
+ function delete($id)
+ {
+ if (!$GLOBALS['phpgw']->acl->check('run',1,'admin'))
+ {
+ return False;
+ }
+
$GLOBALS['Common_BO']->cats->removeCategory($id,True,True);
+ $this->so->delete($id);
+ return True;
+ }
+
+ function urltoid($url)
+ {
+ return $this->so->urltoid($url);
+ }
+
+
+ function set_currentsite($site_url,$mode)
+ {
+ if ($site_url)
+ {
+ $this->current_site =
$this->read($this->urltoid($site_url));
+ }
+ else
+ {
+
$GLOBALS['phpgw']->preferences->read_repository();
+ $siteswitch = get_var('siteswitch');
+ if ($siteswitch)
+ {
+ $this->current_site =
$this->read($siteswitch);
+
$GLOBALS['phpgw']->preferences->change('sitemgr','currentsite',$siteswitch);
+
$GLOBALS['phpgw']->preferences->save_repository(True);
+ }
+ else
+ {
+ $currentsite =
$GLOBALS['phpgw_info']['user']['preferences']['sitemgr']['currentsite'];
+ if($currentsite)
+ {
+ $this->current_site =
$this->read($currentsite);
+ }
+ }
+ }
+ if (!$this->current_site)
+ {
+ $allsites = $this->so->list_siteids();
+ if ($allsites)
+ {
+ $this->current_site =
$this->read($allsites[0]);
+
$GLOBALS['phpgw']->preferences->change('sitemgr','currentsite',$allsites[0]);
+
$GLOBALS['phpgw']->preferences->save_repository(True);
+ }
+ else
+ {
+ return False;
+ }
+ }
+
+
define('CURRENT_SITE_ID',$this->current_site['site_id']);
+ $this->setmode($mode);
+ return True;
+ }
+
+ function setmode($mode)
+ {
+ $this->current_site['mode'] = $mode;
+ $GLOBALS['Common_BO']->setvisiblestates($mode);
+ $GLOBALS['Common_BO']->cats->setcurrentcats();
+ }
+
+ //this function is here so that we can retrieve basic info from
sitemgr-link without creating COMMON_BO
+ function get_currentsiteinfo()
+ {
+ $GLOBALS['phpgw']->preferences->read_repository();
+ $currentsite =
$GLOBALS['phpgw_info']['user']['preferences']['sitemgr']['currentsite'];
+ if($currentsite)
+ {
+ $info = $this->so->read2($currentsite);
+ }
+ if (!$info)
+ {
+ $allsites = $this->so->list_siteids();
+ $info = $this->so->read2($allsites[0]);
+
$GLOBALS['phpgw']->preferences->change('sitemgr','currentsite',$allsites[0]);
+
$GLOBALS['phpgw']->preferences->save_repository(True);
+ }
+ return $info;
+ }
+ }
Index: sitemgr/inc/class.Sites_SO.inc.php
diff -u /dev/null sitemgr/inc/class.Sites_SO.inc.php:1.2.2.3.4.1
--- /dev/null Mon Mar 27 13:13:24 2006
+++ sitemgr/inc/class.Sites_SO.inc.php Mon Mar 27 13:13:24 2006
@@ -0,0 +1,169 @@
+<?php
+ class Sites_SO
+ {
+ var $db;
+
+ function Sites_SO()
+ {
+ $this->db = $GLOBALS['phpgw']->db;
+ }
+
+ function list_siteids()
+ {
+ $result = array();
+
+ $this->db->query('SELECT site_id FROM
phpgw_sitemgr_sites', __LINE__, __FILE__);
+ while ($this->db->next_record())
+ {
+ $result[] = $this->db->f('site_id');
+ }
+ return $result;
+ }
+
+ function getWebsites($limit,$start,$sort,$order,$query,&$total)
+ {
+ if ($limit)
+ {
+ if (!$sort)
+ {
+ $sort = 'DESC';
+ }
+ if ($query)
+ {
+ $query =
$this->db->db_addslashes($query);
+ $whereclause = "WHERE site_name LIKE
'%$query%'"
+ . "OR site_url LIKE '%$query%'"
+ . "OR site_dir LIKE '%$query%'";
+ }
+ if ($order)
+ {
+ $orderclause = 'ORDER BY ' .
$this->db->db_addslashes($order)
+ . ' ' .
$this->db->db_addslashes($sort);
+ }
+ else
+ {
+ $orderclause = 'ORDER BY site_name ASC';
+ }
+ $sql = "SELECT site_id,site_name,site_url from
phpgw_sitemgr_sites $whereclause $orderclause";
+ $this->db->query($sql,__LINE__,__FILE__);
+ $total = $this->db->num_rows();
+
$this->db->limit_query($sql,$start,__LINE__,__FILE__);
+ }
+ else
+ {
+ $this->db->query('SELECT
site_id,site_name,site_url FROM phpgw_sitemgr_sites', __LINE__, __FILE__);
+ }
+ while ($this->db->next_record())
+ {
+ foreach(array('site_id', 'site_name',
'site_url') as $col)
+ {
+ $site[$col] = $this->db->f($col, true);
+ }
+ $result[$site['site_id']] = $site;
+ }
+ return $result;
+ }
+
+ function getnumberofsites()
+ {
+ $this->db->query('SELECT COUNT(*) FROM
phpgw_sitemgr_sites',__LINE__,__FILE__);
+ $this->db->next_record();
+ return $this->db->f(0);
+ }
+
+ function urltoid($url)
+ {
+ $sql = 'SELECT site_id FROM phpgw_sitemgr_sites ';
+ $sql .= "WHERE site_url ='" .
$this->db->db_addslashes($url) . "'";
+ $this->db->query($sql,__LINE__,__FILE__);
+ $this->db->next_record();
+ return $this->db->f('site_id');
+ }
+
+ function read($id)
+ {
+ $sql = 'SELECT * FROM phpgw_sitemgr_sites ';
+ $sql .= 'WHERE site_id = ' . intval($id);
+ $this->db->query($sql,__LINE__,__FILE__);
+ if ($this->db->next_record())
+ {
+ foreach(
+ array(
+ 'site_id', 'site_name',
'site_url', 'site_dir', 'themesel',
+ 'site_languages',
'home_page_id', 'anonymous_user','anonymous_passwd'
+ ) as $col
+ )
+ {
+ $site[$col] = $this->db->f($col);
+ }
+ return $site;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function read2($id)
+ {
+ $sql = 'SELECT site_url,site_dir FROM
phpgw_sitemgr_sites ';
+ $sql .= 'WHERE site_id = ' . intval($id);
+ $this->db->query($sql,__LINE__,__FILE__);
+ if ($this->db->next_record())
+ {
+ foreach(
+ array(
+ 'site_url', 'site_dir'
+ ) as $col
+ )
+ {
+ $site[$col] = $this->db->f($col);
+ }
+ return $site;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function add($site)
+ {
+ $cats =
CreateObject('phpgwapi.categories',-1,'sitemgr');
+ $data = array
+ (
+ 'name' => $site['name'],
+ 'descr' => '',
+ 'access' => 'public',
+ 'parent' => 0,
+ 'old_parent' => 0
+ );
+ $site_id = $cats->add($data);
+ $sql = "INSERT INTO phpgw_sitemgr_sites
(site_id,site_name,site_url,site_dir,anonymous_user,anonymous_passwd) VALUES
($site_id,'" .
+ $site['name'] . "','" . $site['url'] . "','" .
$site['dir'] . "','" . $site['anonuser'] . "','" . $site['anonpasswd'] .
+ "')";
+ $this->db->query($sql,__LINE__,__FILE__);
+ return $site_id;
+ }
+
+ function update($id,$site)
+ {
+ $sql = "UPDATE phpgw_sitemgr_sites SET site_name = '" .
$site['name'] . "', site_url = '" . $site['url'] . "', site_dir = '" .
+ $site['dir'] . "', anonymous_user = '" .
$site['anonuser'] . "', anonymous_passwd = '" . $site['anonpasswd'] .
+ "' WHERE site_id = $id";
+ $this->db->query($sql,__LINE__,__FILE__);
+ }
+
+ function delete($id)
+ {
+ $sql = "DELETE FROM phpgw_sitemgr_sites WHERE site_id =
$id";
+ $this->db->query($sql,__LINE__,__FILE__);
+ }
+
+ function saveprefs($prefs)
+ {
+ $sql = "UPDATE phpgw_sitemgr_sites SET themesel = '" .
$prefs['themesel'] . "', site_languages = '" . $prefs['site_languages'] .
+ "', home_page_id = " . $prefs['home_page_id'] .
" WHERE site_id = " . CURRENT_SITE_ID;
+ $this->db->query($sql,__LINE__,__FILE__);
+ }
+ }
Index: sitemgr/inc/class.module.inc.php
diff -u sitemgr/inc/class.module.inc.php:1.8.2.2.4.1
sitemgr/inc/class.module.inc.php:1.8.2.2.4.2
--- sitemgr/inc/class.module.inc.php:1.8.2.2.4.1 Sat Nov 12 14:11:58 2005
+++ sitemgr/inc/class.module.inc.php Mon Mar 27 13:13:24 2006
@@ -174,6 +174,7 @@
while (isset($input[$i]))
{
$element['label'] = $input[$i]['label'];
+ $element['label_for'] =
'sitemgr_element_' . $this->block->version . $input[$i]['name'];
$element['form'] =
$this->build_input_element($input[$i],$this->block->arguments[$key][$i],$elementname.'[]');
$interface[] = $element;
$i++;
@@ -182,7 +183,7 @@
else
{
$element['label'] = $input['label'];
- $element['label_for'] = 'sitemgr_element_' .
$this->block->version;
+ $element['label_for'] =
"sitemgr_element_{$this->block->version}_{$key}";
$element['form'] =
$this->build_input_element($input,$this->block->arguments[$key],$elementname,
$element['label_for']);
$interface[] = $element;
}
@@ -247,7 +248,8 @@
return $this->build_input_element(
$this->post[$key],
($default !== False) ? $default :
$this->block->arguments[$key],
- ('block[' . $this->block->id . '][' . $key . ']')
+ ('block[' . $this->block->id . '][' . $key . ']'),
+ "block_{$this->block->id}_{$key}"
);
}
@@ -315,13 +317,8 @@
return '<input id="'.$element_id.'"
type="image" ' . $inputdef .' src ="' . $input['src'] . '" />';
case 'richtext':
-
- return "<textarea
id=\"{$element_id}\"{$inputdef}>{$default}</textarea>\n"
- . "<script>\n\nvar
oFCKEditor_{$this->block->version} = new FCKeditor('{$elementname}');
-
oFCKEditor_{$this->block->version}.BasePath =
'{$GLOBALS['phpgw_info']['server']['webserver_url']}/news_admin/js/fckeditor/';
-
oFCKEditor_{$this->block->version}.SpellChecker = '" .
(extension_loaded('pspell') ? 'SpellerPages' : 'ieSpell') . "';
-
oFCKEditor_{$this->block->version}.ReplaceTextarea();
- \n</script>\n";
+
$GLOBALS['phpgw']->richtext->replace_element($element_id);
+ return "<textarea id=\"{$element_id}\"
{$inputdef}>{$default}</textarea>\n";
}
}
Index: sitemgr/js/columnlist/columnlist.css
diff -u /dev/null sitemgr/js/columnlist/columnlist.css:1.1.2.1
--- /dev/null Mon Mar 27 13:13:24 2006
+++ sitemgr/js/columnlist/columnlist.css Mon Mar 27 13:13:24 2006
@@ -0,0 +1,113 @@
+.webfx-columnlist {
+ border: 1px solid;
+ border-color: threedshadow threedhighlight threedhighlight threedshadow;
+ display: block;
+ margin: 0px auto;
+ overflow: hidden;
+ width: 600px;
+ -moz-user-select: none;
+ -moz-user-focus: normal;
+ -moz-user-input: enabled;
+}
+
+.webfx-columnlist td {
+ font: menu;
+ padding: 1px;
+ white-space: nowrap;
+}
+
+.webfx-columnlist-head {
+ position: absolute;
+ background: threedface;
+ overflow: hidden;
+ -moz-user-select: none;
+}
+
+.webfx-columnlist-head table {
+ table-layout: fixed;
+}
+
+.webfx-columnlist-head td {
+ border: 1px solid;
+ border-color: threedhighlight threedshadow threedshadow threedhighlight;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.webfx-columnlist-head td img {
+ width: 8px;
+ height: 7px;
+ margin: 0px 5px 0px 5px;
+ display: none;
+}
+
+.webfx-columnlist-body {
+ border: 1px solid;
+ border-color: threedhighlight threedface threedface threedhighlight;
+ background: window;
+ height: 300px;
+ overflow: auto;
+}
+
+.webfx-columnlist-body table {
+ table-layout: fixed;
+}
+
+.webfx-columnlist-body td {
+ border-bottom: solid white;
+ border-width: 0px 1px 1px 0px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: no-wrap;
+}
+
+.webfx-columnlist-body tr.selected td {
+ background: #C0C0FF;
+}
+
+.webfx-columnlist-body tr.odd td {
+ background: #FFFFC0;
+}
+
+.webfx-columnlist-body tr.even td {
+ background: window;
+}
+
+.webfx-columnlist-move-header {
+ position: absolute;
+ background: threedshadow;
+ top: 0px;
+ font: menu;
+ padding: 2px;
+ height: 1em;
+ filter: Alpha(Opacity=50);
+ -moz-opacity: 0.5;
+ -moz-user-select: none;
+}
+
+.webfx-columnlist-active-header {
+ border-color: threedface !important;
+}
+
+.webfx-columnlist-separator-header {
+ position: absolute;
+ top: 0px;
+ left: 10px;
+ font: menu;
+ height: 1em;
+ width: 1px;
+ overflow: hidden;
+ background: blue;
+ padding: 3px 0px;
+}
+
+td
+{
+ width: 360px;
+}
+
+td.permscol, col.permscol
+{
+ text-align: center;
+ width: 120px;
+}
\ No newline at end of file
Index: sitemgr/js/columnlist/columnlist.js
diff -u /dev/null sitemgr/js/columnlist/columnlist.js:1.1.2.1
--- /dev/null Mon Mar 27 13:13:24 2006
+++ sitemgr/js/columnlist/columnlist.js Mon Mar 27 13:13:24 2006
@@ -0,0 +1,1258 @@
+/*----------------------------------------------------------------------------\
+| Column List Widget 1.03 |
+|-----------------------------------------------------------------------------|
+| Created by Emil A Eklund |
+| (http://webfx.eae.net/contact.html#emil) |
+| For WebFX (http://webfx.eae.net/) |
+|-----------------------------------------------------------------------------|
+| A DHTML column list widget. Can be generated from supplied data or attached |
+| to an existing html structure. Supports multiple selection, sorting, column |
+| resizing, column moving and keyboard navigation. |
+|-----------------------------------------------------------------------------|
+| Copyright (c) 2004, 205 Emil A Eklund |
+|-----------------------------------------------------------------------------|
+| This software is provided "as is", without warranty of any kind, express or |
+| implied, including but not limited to the warranties of merchantability, |
+| fitness for a particular purpose and noninfringement. In no event shall the |
+| authors or copyright holders be liable for any claim, damages or other |
+| liability, whether in an action of contract, tort or otherwise, arising |
+| from, out of or in connection with the software or the use or other |
+| dealings in the software. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| This software is available under the three different licenses mentioned |
+| below. To use this software you must chose, and qualify, for one of those. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| The WebFX Non-Commercial License http://webfx.eae.net/license.html |
+| Permits anyone the right to use the software in a non-commercial context |
+| free of charge. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| The WebFX Commercial license http://webfx.eae.net/commercial.html |
+| Permits the license holder the right to use the software in a commercial |
+| context. Such license must be specifically obtained, however it's valid for |
+| any number of implementations of the licensed software. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt |
+| Permits anyone the right to use and modify the software without limitations |
+| as long as proper credits are given and the original and modified source |
+| code are included. Requires that the final product, software derivate from |
+| the original source or any software utilizing a GPL component, such as |
+| this, is also licensed under the GPL license. |
+|-----------------------------------------------------------------------------|
+| Dependencies: columnlist.css Column list style declarations |
+| sortabletable.js Provides table sorting functionality |
+|-----------------------------------------------------------------------------|
+| Browser compatibility: IE Verified, 6.0+ |
+| Mozilla Verified, 1.7+ (Firefox 1.0+) |
+| Opera Not Verified |
+| Safari/KTML: Not Verified |
+|-----------------------------------------------------------------------------|
+| 2004-08-22 | Work started. |
+| 2004-10-24 | First version published. |
+| 2004-11-01 | Added resizeColumns property, allowing column resizing to be |
+| | enabled/disabled. Fixed a bug in the sort method that caused |
+| | getSelectedRow to return an invalid index when called from the |
+| | function triggered by onselect. Misc bugfixes for Mozilla. |
+| 2004-11-23 | Fixed column resizing in mozilla. It still can't make columns |
+| | smaller than their content, but otherwise it seems to work. |
+| 2005-05-22 | Fixed a bug in the removeRange method for index based removal, |
+| | where the rows where deleted in the wrong order. Also added a |
+| | clear method, that removes all rows. |
+| 2005-11-30 | Fixed bug that caused rows to be colored even if colorEvenRows |
+| | was false. Added rowSelection, columnSorting, moveColumns, |
+| | sortAscImage and sortDescImage properties. Implemented column |
+| | moving and alignment. Updated column resizing implementation. |
+| 2005-12-08 | Added support for making columns smaller than their content in |
+| | Mozilla, bringing the Mozilla support up to pair with that for |
+| | IE. Also added support for specifying column width on create. |
+| 2005-12-20 | Fixed bug in setCellValue method. |
+|-----------------------------------------------------------------------------|
+| Created 2004-08-22 | All changes are in the log above. | Updated 2005-12-20 |
+\----------------------------------------------------------------------------*/
+
+var TYPE_STRING = 0;
+var TYPE_NUMBER = 1;
+var TYPE_DATE = 2;
+var TYPE_STRING_NO_CASE = 3;
+
+var SORT_ASCENDING = 0;
+var SORT_DESCENDING = 1;
+
+var ALIGN_AUTO = 0;
+var ALIGN_LEFT = 1;
+var ALIGN_CENTER = 2;
+var ALIGN_RIGHT = 3;
+
+var COL_HEAD_NONE = 0;
+var COL_HEAD_EDGE = 1;
+var COL_HEAD_OVER = 2;
+var COL_HEAD_SIZE = 3;
+var COL_HEAD_DOWN = 4;
+var COL_HEAD_MOVE = 5;
+
+
+/*
+ * oColumnList = new WebFXColumnList()
+ * Default constructor
+ */
+function WebFXColumnList() {
+
+ /* public properties */
+ this.multiple = true;
// Allow multiple selection (true or false)
+ this.colorEvenRows = true;
// Mark even rows with different color (true or false)
+ this.resizeColumns = true;
// Enable column resizing (true or false)
+ this.bodyColResize = true;
// Resize body columns duing resize operation (true or false)
+ this.moveColumns = true;
// Enable column moving (true or false)
+ this.rowSelection = true;
// Enable row selection (true or false)
+ this.columnSorting = true;
// Enable sorting (true or false)
+ this.columnAlign = true;
// Enable column text alignment (true or false)
+ this.sortAscImage = 'images/asc.png';
// Image used to indicate ascending sort order
+ this.sortDescImage = 'images/desc.png';
// Image used to indicate descending sort order
+
+ /* public read only properties */
+ this.sortCol = -1;
// Column index currently sorted by, read only
+ this.sortDescending = 0;
// Column sort direction, read only (SORT_ASCENDING or SORT_DESCENDING)
+ this.error = '';
// Error message set if an error code was returned, read only.
+ this.selectedRows = [];
// Currently selected rows, read only.
+
+ /* events */
+ this.onresize = null;
+ this.onsort = null;
+ this.onselect = null;
+
+ /* private properties */
+ this._eCont = null;
+ this._eHead = null;
+ this._eBody = null;
+ this._eHeadTable = null;
+ this._eBodyTable = null;
+ this._eHeadCols = null;
+ this._eBodyCols = null;
+
+ this._aColumnTypes = [];
+ this._aColumnAlign = [];
+ this._rows = 0;
+ this._cols = 0;
+ this._headerOper = COL_HEAD_NONE;
+ this._headerData = null;
+}
+
+
+/*
+ * iError = create(eContainer, sColumn[])
+ * Transforms the supplied container into a column list.
+ * sColumn[] - Array containing column headers
+ * sColumn[][] - Two dimensional array with column headers, widths and types
+*/
+WebFXColumnList.prototype.create = function(eContainer, aColumns) {
+ var eRow, eCell, eDiv, eImg, eTableBody, eColGroup, eCol, a, b;
+
+ for (var i = eContainer.childNodes.length - 1; i >= 0; i--) {
+ eContainer.removeChild(eContainer.childNodes[i]);
+ }
+
+ /* Create container, header and body */
+ this._eCont = eContainer;
+ this._eHead = document.createElement('div');
+ this._eBody = document.createElement('div');
+ this._eCont.className = 'webfx-columnlist';
+ this._eHead.className = 'webfx-columnlist-head';
+ this._eBody.className = 'webfx-columnlist-body';
+ this._eCont.appendChild(this._eHead);
+ this._eCont.appendChild(this._eBody);
+
+ /* Populate header */
+ this._eHeadTable = document.createElement('table');
+ this._eHeadTable.style.width = '100px';
// if a width is not set here the overflow: hidden rule will be ignored
by mozilla
+ this._eHeadTable.cellSpacing = 0;
+ this._eHeadTable.cellPadding = 0;
+ this._eHead.appendChild(this._eHeadTable);
+ eTableBody = document.createElement('tbody');
+ this._eHeadTable.appendChild(eTableBody);
+ eRow = document.createElement('tr');
+ eTableBody.appendChild(eRow);
+ for (var i = 0; i < aColumns.length; i++) {
+ eCell = document.createElement('td');
+ eRow.appendChild(eCell);
+ eImg = document.createElement('img');
+ if (typeof(aColumns[i]) == 'object') {
eCell.appendChild(document.createTextNode(aColumns[i][0])); }
+ else { eCell.appendChild(document.createTextNode(aColumns[i]));
}
+ eCell.appendChild(eImg);
+ }
+
+ /* Create main table, colgroup and col elements */
+ this._eBodyTable = document.createElement('table');
+ this._eBodyTable.cellSpacing = 0;
+ this._eBodyTable.cellPadding = 0;
+ this._eBody.appendChild(this._eBodyTable);
+ eTableBody = document.createElement('tbody');
+ this._eBodyTable.appendChild(eTableBody);
+ eColGroup = document.createElement('colgroup');
+ this._eBodyTable.appendChild(eColGroup);
+ for (var i = 0; i < aColumns.length; i++) {
+ eCol = document.createElement('col');
+ if ((typeof(aColumns[i]) == 'object') && (aColumns[i].length)
&& (aColumns[i].length > 1)) { eCol.style.width = aColumns[i][1]; }
+ else { eCol.style.width = 'auto'; }
+ eColGroup.appendChild(eCol);
+ }
+
+ /* Init sortable table */
+ this._stl = new SortableTable(this._eBodyTable);
+
+ /* Set column data types */
+ a = new Array(); b = false;
+ for (var i = 0; i < aColumns.length; i++) {
+ if ((typeof(aColumns[i]) == 'object') && (aColumns[i].length)
&& (aColumns[i].length > 2)) { a.push(aColumns[i][2]); b = true; }
+ else { a.push(TYPE_STRING); }
+ }
+
+ /* Only set explicitly if type was specified for at least one column */
+ if (b) { this.setColumnTypes(a); }
+
+ this._eHeadCols = eRow.cells;
+ this._eBodyCols = null;
+
+ this._cols = aColumns.length;
+ this._rows = 0;
+
+ this._init();
+
+ return 0;
+};
+
+
+/*
+ * iError = bind(eContainer, eHeader, eBody)
+ * Binds column list to an existing HTML structure. Use create
+ * to generate the strucutr automatically.
+*/
+WebFXColumnList.prototype.bind = function(eCont, eHead, eBody) {
+ try {
+ this._eCont = eCont;
+ this._eHead = eHead;
+ this._eBody = eBody;
+ this._eHeadTable = this._eHead.getElementsByTagName('table')[0];
+ this._eBodyTable = this._eBody.getElementsByTagName('table')[0];
+ this._eHeadCols = this._eHeadTable.tBodies[0].rows[0].cells;
+ this._eBodyCols = this._eBodyTable.tBodies[0].rows[0].cells;
+ }
+ catch(oe) {
+ this.error = 'Unable to bind to elements: ' + oe.message;
+ return 1;
+ }
+ if (this._eHeadCols.length != this._eBodyCols.length) {
+ this.error = 'Unable to bind to elements: Number of columns in
header and body does not match.';
+ return 2;
+ }
+
+ this._eHeadCols = this._eHeadTable.tBodies[0].rows[0].cells;
+ this._eBodyCols = this._eBodyTable.tBodies[0].rows[0].cells;
+
+ this._cols = this._eHeadCols.length;
+ this._rows = this._eBodyTable.tBodies[0].rows.length;
+
+ this._stl = new SortableTable(this._eBodyTable);
+
+ /* Set column class names (used for alignment in mozilla) */
+ if ((!document.all) && (this.columnAlign)) {
+ aRows = this._eBodyTable.tBodies[0].rows;
+ this._rows = aRows.length;
+ for (i = 0; i < this._rows; i++) {
+ for (j = 0; j < this._cols; j++) {
+ aRows[i].cells[j].className =
'webfx-columnlist-col-' + j;
+ } } }
+
+ this._init();
+
+ return 0;
+};
+
+
+/*
+ * void _init(iWidth, iHeight)
+ * Initializes column list, called by create and bind
+*/
+WebFXColumnList.prototype._init = function(iWidth, iHeight) {
+ if (navigator.product == 'Gecko') {
+ /*
+ * Mozilla does not allow the scroll* properties of containers
with the
+ * overflow property set to 'hidden' thus we'll have to set it
to
+ * '-moz-scrollbars-none' which is basically the same as
'hidden' in IE,
+ * the container has overflow type 'scroll' but no scrollbars
are shown.
+ */
+ for (var n = 0; n < document.styleSheets.length; n++) {
+ if
(document.styleSheets[n].href.indexOf('columnlist.css') == -1) { continue; }
+ var rules = document.styleSheets[n].cssRules;
+ for (var i = 0; i < rules.length; i++) {
+ if ((rules[i].type == CSSRule.STYLE_RULE) &&
(rules[i].selectorText == '.webfx-columnlist-head')) {
+ rules[i].style.overflow =
'-moz-scrollbars-none';
+ } } } }
+
+ /*
+ * Set tab index to allow element to be focused using keyboard, also
allows
+ * keyboard events to be captured for Mozilla.
+ */
+ this._eCont.tabIndex = '0';
+
+ this.calcSize();
+ this._assignEventHandlers();
+ if (this.colorEvenRows) { this._colorEvenRows(); }
+ if (this.columnAlign) { this._setAlignment(); }
+}
+
+
+/*
+ * void _assignEventHandlers()
+ * Assigns event handlers to the grid elements, called by bind.
+*/
+WebFXColumnList.prototype._assignEventHandlers = function() {
+ var oThis = this;
+ this._eCont.onclick = function(e) { oThis._click(e); }
+ if (this.resizeColumns) {
+ this._eCont.onmousedown = function(e) { oThis._mouseDown(e); }
+ this._eCont.onmousemove = function(e) { oThis._mouseMove(e); }
+ }
+ this._eCont.onmouseup = function(e) { oThis._mouseUp(e); }
+ this._eCont.onselectstart = function(e) { return false; }
+ this._eBody.onscroll = function() {
+ oThis._eHead.scrollLeft = oThis._eBody.scrollLeft;
+ };
+ this._eCont.onkeydown = function(e) {
+ var el = (e)?e.target:window.event.srcElement;
+ var key = (e)?e.keyCode:window.event.keyCode;
+ if (oThis._handleRowKey(key)) { return; }
+ if (window.event) { window.event.cancelBubble = true; }
+ else { e.preventDefault(); e.stopPropagation() }
+ return false;
+ };
+};
+
+
+/*
+ * void calcSize()
+ * Used to calculate the desired size of the grid and size it accordingly.
+ */
+WebFXColumnList.prototype.calcSize = function() {
+ if (this._eCont.offsetWidth >= 4) {
+
+ /* Size body */
+ var h = this._eCont.clientHeight - this._eHead.offsetHeight - 2;
+ if (h >= 0) { this._eBody.style.height = h + 'px'; }
+ this._eBody.style.width = this._eCont.offsetWidth - 4 + 'px';
+ this._eBody.style.paddingTop = this._eHead.offsetHeight + 'px';
+ this._eBodyTable.style.width = this._eBody.clientWidth + 'px';
+
+ /* Size header */
+ var bNoScrollbar = ((this._eBody.offsetWidth -
this._eBody.clientWidth) == 2);
+ this._eHeadTable.style.width = this._eHead.style.width =
this._eBody.clientWidth + ((bNoScrollbar)?2:0) + 'px';
+
+ /* Size columns */
+ if (this._eBodyCols) {
+ var length = this._eBodyCols.length;
+ for (var i = 0; i < length; i++) {
+ this._eHeadCols[i].style.width =
(this._eBodyCols[i].offsetWidth - 4) + ((bNoScrollbar) && (i == length -
1)?2:0) + 'px';
+ } } }
+
+ this._eHeadTable.style.width = 'auto';
+};
+
+
+/*
+ * iErrorCode = selectRow(iRowIndex, bMultiple)
+ * Selects the row identified by the sequence number supplied,
+ *
+ * If bMultiple is specified and multi-select is allowed the
+ * the previously selected row will not be deselected. If the
+ * specified row is already selected it will be deselected.
+ */
+WebFXColumnList.prototype.selectRow = function(iRowIndex, bMultiple) {
+ if (!this.rowSelection) { return; }
+
+ if ((iRowIndex < 0) || (iRowIndex > this._rows - 1)) {
+ this.error = 'Unable to select row, index out of range.';
+ return 1;
+ }
+ var eRows = this._eBodyTable.tBodies[0].rows;
+ var bSelect = true;
+
+ /* Normal click */
+ if ((!bMultiple) || (!this.multiple)) {
+
+ /* Deselect previously selected rows */
+ while (this.selectedRows.length) {
+ if (this.colorEvenRows) {
eRows[this.selectedRows[0]].className = (this.selectedRows[0] &
1)?'odd':'even'; }
+ else { eRows[this.selectedRows[0]].className = ''; }
+ this.selectedRows.splice(0, 1);
+ } }
+
+ /* Control + Click */
+ else {
+ for (var i = 0; i < this.selectedRows.length; i++) {
+
+ /* Deselect clicked row */
+ if (this.selectedRows[i] == iRowIndex) {
+ if (this.colorEvenRows) {
eRows[this.selectedRows[i]].className = (i & 1)?'odd':'even'; }
+ else { eRows[this.selectedRows[i]].className =
''; }
+ this.selectedRows.splice(i, 1);
+ bSelect = false;
+ break;
+ } } }
+
+ /* Select clicked row */
+ if (bSelect) {
+ this.selectedRows.push(iRowIndex);
+ eRows[iRowIndex].className = 'selected';
+ }
+
+ var a = (eRows[iRowIndex].offsetTop + this._eHead.offsetHeight) +
eRows[iRowIndex].offsetHeight + 1;
+ var b = (this._eBody.clientHeight + this._eBody.scrollTop);
+ if (a > b) {
+ this._eBody.scrollTop = (a - this._eBody.clientHeight);
+ }
+ var c = eRows[iRowIndex].offsetTop;
+ var d = this._eBody.scrollTop;
+ if (c < d) {
+ this._eBody.scrollTop = c;
+ }
+
+ /* Call onselect if defined */
+ if (this.onselect) { this.onselect(this.selectedRows); }
+
+ return 0;
+};
+
+
+/*
+ * iErrorCode = selectRange(iRowIndex[])
+ * iErrorCode = selectRange(iFromRowIndex, iToRowIndex)
+ * Selects all rows between iFromRowIndex and iToRowIndex.
+ */
+WebFXColumnList.prototype.selectRange = function(a, b) {
+ var aRowIndex;
+
+ if (!this.rowSelection) { return; }
+
+ if (typeof a == 'number') {
+ aRowIndex = new Array();
+ for (var i = a; i <= b; i++) { aRowIndex.push(i); }
+ for (var i = b; i <= a; i++) { aRowIndex.push(i); }
+ }
+ else { aRowIndex = a; }
+
+ for (var i = 0; i < aRowIndex.length; i++) {
+ if ((aRowIndex[i] < 0) || (aRowIndex[i] > this._rows - 1)) {
+ this.error = 'Unable to select rows, index out of
range.';
+ return 1;
+ } }
+
+ /* Deselect previously selected rows */
+ var eRows = this._eBodyTable.tBodies[0].rows;
+ while (this.selectedRows.length) {
+ if (this.colorEvenRows) { eRows[this.selectedRows[0]].className
= (this.selectedRows[0] & 1)?'odd':'even'; }
+ else { eRows[this.selectedRows[0]].className = ''; }
+ this.selectedRows.splice(0, 1);
+ }
+
+ /* Select all rows indicated by range */
+ var eRows = this._eBodyTable.tBodies[0].rows;
+ var bMatch;
+ for (var i = 0; i < aRowIndex.length; i++) {
+ bMatch = false;
+ for (var j = 0; j < this.selectedRows.length; j++) {
+ if (this.selectedRows[j] == aRowIndex[i]) { bMatch =
true; break; }
+ }
+ if (!bMatch) {
+ /* Select row */
+ this.selectedRows.push(aRowIndex[i]);
+ eRows[aRowIndex[i]].className = 'selected';
+ } }
+
+ /* Call onselect if defined */
+ if (this.onselect) { this.onselect(this.selectedRows); }
+
+ return 0;
+};
+
+
+/*
+ * void resize(iWidth, iHeight)
+ * Resize the grid to the given dimensions, the outer (border) size is given,
not the inner (content) size.
+ */
+WebFXColumnList.prototype.resize = function(w, h) {
+ this._eCont.style.width = w + 'px';
+ this._eCont.style.height = h + 'px';
+ this.calcSize();
+
+ /* Call onresize if defined */
+ if (this.onresize) { this.onresize(); }
+};
+
+
+/*
+ * void _colorEvenRows()
+ * Changes the color of even rows (usually to light yellow) to make it easier
to read.
+ * Also updates the id column to a sequence counter rather than the row ids.
+ */
+WebFXColumnList.prototype._colorEvenRows = function() {
+ if (this._eBodyTable.tBodies.length) {
+ var nodes = this._eBodyTable.tBodies[0].rows;
+ var len = nodes.length;
+ for (var i = 0; i < len; i++) {
+ if (nodes[i].className != 'selected') {
+ nodes[i].className = (i & 1)?'odd':'even';
+ } } }
+};
+
+
+/*
+ * iErrorCode = addRow(aRowData)
+ * Appends supplied row to the column list.
+ */
+WebFXColumnList.prototype.addRow = function(aRowData) {
+ var rc = this._addRow(aRowData);
+ if (rc) { return rc; }
+ this.calcSize();
+ return 0;
+};
+
+
+/*
+ * iErrorCode = addRows(aData)
+ * Appends supplied rows to the column list.
+ */
+WebFXColumnList.prototype.addRows = function(aData) {
+ for (var i = 0; i < aData.length; i++) {
+ var rc = this._addRow(aData[i]);
+ if (rc) { return rc; }
+ }
+ this.calcSize();
+ return 0;
+};
+
+
+/*
+ * void _colorEvenRows()
+ * Changes the color of even rows (usually to light yellow) to make it easier
to read.
+ * Also updates the id column to a sequence counter rather than the row ids.
+ */
+WebFXColumnList.prototype._colorEvenRows = function() {
+ if (this._eBodyTable.tBodies.length) {
+ var nodes = this._eBodyTable.tBodies[0].rows;
+ for (var i = 0; i < nodes.length; i++) {
+ if (nodes[i].className != 'selected') {
+ nodes[i].className = (i & 1)?'odd':'even';
+ } } }
+};
+
+
+/*
+ * iErrorCode = _addRow(aRowData)
+ */
+WebFXColumnList.prototype._addRow = function(aRowData) {
+ var eBody, eRow, eCell, i, len;
+
+ /* Validate column count */
+ if (aRowData.length != this._cols) { return 1; }
+
+ /* Construct Body Row */
+ eBody = this._eBodyTable.tBodies[0];
+ eRow = document.createElement('tr');
+ if (this.colorEvenRows) {
+ eRow.className = (this._rows & 1)?'odd':'even';
+ }
+
+ for (i = 0; i < this._cols; i++) {
+ eCell = document.createElement('td');
+ eCell.className = 'webfx-columnlist-col-' + i;
+ eCell.appendChild(document.createTextNode(aRowData[i]));
+ eRow.appendChild(eCell);
+ }
+ eBody.appendChild(eRow);
+
+ /* Update row counter */
+ this._rows++;
+
+ if (this._eBodyCols == null) {
+ this._eBodyCols = this._eBodyTable.tBodies[0].rows[0].cells;
+ }
+
+ return 0;
+};
+
+
+/*
+ * iErrorCode = removeRow(iRowIndex)
+ * Appends supplied row to the grid.
+ */
+WebFXColumnList.prototype.removeRow = function(iRowIndex) {
+ /* Remove row */
+ var rc = this._removeRow(iRowIndex);
+ if (rc) { return rc; }
+
+ /* Update row counter and select previous row, if any */
+ this._rows--;
+ this.selectRow((iRowIndex > 1)?iRowIndex-1:0);
+
+ /* Recolor rows, if needed */
+ if (this.colorEvenRows) { this._colorEvenRows(); }
+ this.calcSize();
+
+ /* Call onselect if defined */
+ if (this.onselect) { this.onselect(this.selectedRows); }
+
+ return 0;
+};
+
+
+/*
+ * iErrorCode = removeRange(iRowIndex[])
+ * iErrorCode = removeRange(iFirstRowIndex, iLastRowIndex)
+ * Appends supplied row to the grid.
+ */
+WebFXColumnList.prototype.removeRange = function(a, b) {
+ var aRowIndex = new Array();
+ if (typeof a == 'number') {
+ for (var i = a; i <= b; i++) { aRowIndex.push(i); }
+ }
+ else {
+ for (var i = 0; i < a.length; i++) {
+ aRowIndex.push(a[i]);
+ }
+ aRowIndex.sort(compareNumericAsc);
+ }
+
+ while ((i = aRowIndex.pop()) >= 0) {
+ var rc = this._removeRow(i);
+ this._rows--;
+ }
+
+ /* Recolor rows, if needed */
+ if (this.colorEvenRows) { this._colorEvenRows(); }
+ this.calcSize();
+
+ /* Call onselect if defined */
+ if (this.onselect) { this.onselect(this.selectedRows); }
+
+ return 0;
+};
+
+
+/*
+ * iErrorCode = clear()
+ * Removes all rows from the column list.
+ */
+WebFXColumnList.prototype.clear = function() {
+ return this.removeRange(0, this._rows - 1);
+}
+
+/*
+ * iErrorCode = _removeRow(iRowIndex)
+ */
+WebFXColumnList.prototype._removeRow = function(iRowIndex) {
+ if ((iRowIndex < 0) || (iRowIndex > this._rows - 1)) {
+ this.error = 'Unable to remove row, row index out of range.';
+ return 1;
+ }
+
+ /* Remove from selected */
+ for (var i = this.selectedRows.length - 1; i >= 0; i--) {
+ if (this.selectedRows[i] == iRowIndex) {
+ this.selectedRows.splice(i, 1);
+ } }
+
+
this._eBodyTable.tBodies[0].removeChild(this._eBodyTable.tBodies[0].rows[iRowIndex]);
+ return 0;
+};
+
+
+/*
+ * iRowIndex getSelectedRow()
+ * Returns the index of the selected row or -1 if no row is selected.
+ */
+WebFXColumnList.prototype.getSelectedRow = function() {
+ return
(this.selectedRows.length)?this.selectedRows[this.selectedRows.length-1]:-1;
+};
+
+
+/*
+ * iRowIndex[] getSelectedRange()
+ * Returns an array with the row index of all selecteds row or null if no row
is selected.
+ */
+WebFXColumnList.prototype.getSelectedRange = function() {
+ return (this.selectedRows.length)?this.selectedRows:-1;
+};
+
+
+/*
+ * iRows getRowCount()
+ * Returns the nummer of rows.
+ */
+WebFXColumnList.prototype.getRowCount = function() {
+ return this._rows;
+};
+
+
+/*
+ * iRows getColumnCount()
+ * Returns the nummer of columns.
+ */
+WebFXColumnList.prototype.getColumnCount = function() {
+ return this._cols;
+};
+
+
+/*
+ * sValue = getCellValue(iRowIndex, iColumnIndex, bHTML)
+ * Returns the content of the specified cell.
+ */
+WebFXColumnList.prototype.getCellValue = function(iRowIndex, iColIndex) {
+ var el;
+
+ if ((iRowIndex < 0) || (iRowIndex > this._rows - 1)) {
+ this.error = 'Unable to get cell value , row index out of
range.';
+ return null;
+ }
+ if ((iColIndex < 0) || (iColIndex > this._cols - 1)) {
+ this.error = 'Unable to get cell value , row index out of
range.';
+ return null;
+ }
+
+ el = this._eBodyTable.tBodies[0].rows[iRowIndex].cells[iColIndex];
+
+ return (bHTML)?el.innerHTML:getInnerText(el);
+};
+
+
+/*
+ * iError = setCellValue(iRowIndex, iColumnIndex, sValue, bHTML)
+ * Sets the content of the specified cell.
+ */
+WebFXColumnList.prototype.setCellValue = function(iRowIndex, iColIndex,
sValue, bHTML) {
+ var el;
+
+ if ((iRowIndex < 0) || (iRowIndex > this._rows - 1)) {
+ this.error = 'Unable to set cell value , row index out of
range.';
+ return 1;
+ }
+ if ((iColIndex < 0) || (iColIndex > this._cols - 1)) {
+ this.error = 'Unable to set cell value , row index out of
range.';
+ return 2;
+ }
+
+ el = this._eBodyTable.tBodies[0].rows[iRowIndex].cells[iColIndex];
+ if (bHTML) { el.innerHTML = sValue; }
+ else {
+ while (el.firstChild != el.lastChild) {
el.removeChild(el.lastChild); }
+ if (el.firstChild) { el.firstChild.nodeValue = sValue; }
+ else { el.appendChild(document.createTextNode(sValue)); }
+ }
+
+ this.calcSize();
+
+ return 0;
+};
+
+
+/*
+ * void setSortTypes(sSortType[]) {
+ * Sets the column data types for sorting.
+ * Valid options: TYPE_STRING, TYPE_NUMBER, TYPE_DATE, TYPE_STRING_NO_CASE or
+ * custom string value that will be passed to sortable table. Can be registered
+ * with the SortableTable.prototype.addSortType method.
+ */
+WebFXColumnList.prototype.setSortTypes = function(aSortTypes) {
+ var i, a = new Array();
+
+ this._aColumnTypes = aSortTypes;
+ for (i = 0; i < this._cols; i++) {
+ switch (aSortTypes[i]) {
+ case TYPE_STRING: a.push('String');
break;
+ case TYPE_NUMBER: a.push('Number');
break;
+ case TYPE_DATE: a.push('Date');
break;
+ case TYPE_STRING_NO_CASE:
a.push('CaseInsensitiveString'); break;
+ default: a.push('String');
+ };
+ }
+ this._stl.setSortTypes(a);
+};
+
+
+/*
+ * void setColumnTypes(aColumnTypes[]) {
+ * Sets the column data types for sorting, also affects the alignment for
columns
+ * with alignment set to ALIGN_AUTO (which is the default), strings and dates
+ * are left aligned, numbers right aligned.
+ * Valid options: TYPE_STRING, TYPE_NUMBER, TYPE_DATE, TYPE_STRING_NO_CASE or
+ * custom string value that will be passed to sortable table. Can be registered
+ * with the SortableTable.prototype.addSortType method.
+ */
+WebFXColumnList.prototype.setColumnTypes = function(aColumnTypes) {
+ this.setSortTypes(aColumnTypes);
+};
+
+
+/*
+ * void setColumnAlignment(iAlignment[])
+ * Sets column text alignment, ALIGN_AUTO, ALIGN_LEFT, ALIGN_CENTER or
ALIGN_RIGHT.
+ */
+WebFXColumnList.prototype.setColumnAlignment = function(aAlignment) {
+ _aColumnAlign = aAlignment;
+};
+
+
+/*
+ * void sort(iColumnIndex, [bDescending])
+ * Sorts the grid by the specified column (zero based index) and, optionally,
in the specified direction.
+ */
+WebFXColumnList.prototype.sort = function(iCol, bDesc) {
+ if (!this.columnSorting) { return; }
+
+ /* Hide arrow from header for column currently sorted by */
+ if (this.sortCol != -1) {
+ var eImg =
this._eHeadTable.tBodies[0].rows[0].cells[this.sortCol].getElementsByTagName('img')[0];
+ eImg.style.display = 'none';
+ }
+
+ /* Determine sort direction */
+ if (bDesc == null) {
+ bDesc = false;
+ if ((!this.sortDescending) && (iCol == this.sortCol)) { bDesc =
true; }
+ }
+
+ /* Indicate sorting using arrow in header */
+ var eImg =
this._eHeadTable.tBodies[0].rows[0].cells[iCol].getElementsByTagName('img')[0];
+ eImg.src = (bDesc)?this.sortDescImage:this.sortAscImage;
+ eImg.style.display = 'inline';
+
+ /* Perform sort operation */
+ this._stl.sort(iCol, bDesc);
+ this.sortCol = iCol;
+ this.sortDescending = bDesc;
+
+ /* Update row coloring */
+ if (this.colorEvenRows) { this._colorEvenRows(); }
+
+ /* Update selection */
+ var nodes = this._eBodyTable.tBodies[0].rows;
+ var len = nodes.length;
+ var a = new Array();
+ for (var i = 0; i < len; i++) {
+ if (nodes[i].className == 'selected') { a.push(i); }
+ }
+ this.selectRange(a);
+
+ /* Call onsort if defined */
+ if (this.onsort) { this.onsort(this.sortCol, this.sortDescending); }
+
+};
+
+
+/*
+ * void _handleRowKey(iKeyCode)
+ * Key handler for events on row level.
+ */
+WebFXColumnList.prototype._handleRowKey = function(iKeyCode, bCtrl, bShift) {
+ var iActiveRow = -1;
+ if (this.selectedRows.length != 0) { iActiveRow =
this.selectedRows[this.selectedRows.length-1]; }
+ if ((!bCtrl) && (!bShift)) {
+ if (iKeyCode == 38) {
// Up
+ if (iActiveRow > 0) { this.selectRow(iActiveRow - 1); }
+ }
+ else if (iKeyCode == 40) {
// Down
+ if (iActiveRow < this._rows - 1) {
this.selectRow(iActiveRow + 1); }
+ }
+ else if (iKeyCode == 33) {
// Page Up
+ if (iActiveRow > 10) { this.selectRow(iActiveRow - 10);
}
+ else { this.selectRow(0); }
+ }
+ else if (iKeyCode == 34) {
// Page Down
+ if (iActiveRow < this._rows - 10) {
this.selectRow(iActiveRow + 10); }
+ else { this.selectRow(this._rows - 1); }
+ }
+ else if (iKeyCode == 36) { this.selectRow(0); }
// Home
+ else if (iKeyCode == 35) { this.selectRow(this._rows - 1); }
// End
+ else { return true; }
+ return false;
+ }
+};
+
+
+/*
+ * Event Handlers
+ */
+WebFXColumnList.prototype._mouseMove = function(e) {
+ var el, x, w, tw, ox, rx, i, l;
+
+ el = (e)?e.target:window.event.srcElement;
+ x = (e)?e.pageX:window.event.x + this._eBody.scrollLeft;
+
+ /*
+ * Column move operation started, create elements required to indicate
moving
+ * and set operation flag to COL_HEAD_MOVE.
+ */
+ if (this._headerOper == COL_HEAD_DOWN) {
+ this._headerOper = COL_HEAD_MOVE;
+ this._eCont.style.cursor = 'move';
+
+ w = this._headerData[2] + (x - this._headerData[1]);
+
+ if (!this._moveEl) {
+ this._moveEl = document.createElement('div');
+
this._moveEl.appendChild(document.createTextNode(this._headerData[0].firstChild.nodeValue));
+ this._moveEl.className = 'webfx-columnlist-move-header';
+ this._eHead.appendChild(this._moveEl);
+
+ if (this.columnAlign) {
+ switch
(this._aColumnAlign[this._headerData[0].cellIndex]) {
+ case ALIGN_LEFT:
this._moveEl.style.textAlign = 'left'; break;
+ case ALIGN_CENTER:
this._moveEl.style.textAlign = 'center'; break;
+ case ALIGN_RIGHT:
this._moveEl.style.textAlign = 'right'; break;
+ case ALIGN_AUTO:
+ default:
+
switch(this._aColumnTypes[this._headerData[0].cellIndex]) {
+ case TYPE_NUMBER:
this._moveEl.style.textAlign = 'right'; break;
+ default:
this._moveEl.style.textAlign = 'left';
+ };
+ };
+ }
+
+
+ }
+ else { this._moveEl.firstChild.nodeValue =
this._headerData[0].firstChild.nodeValue; }
+ this._moveEl.style.width = this._headerData[0].clientWidth +
'px';
+
+ if (!this._moveSepEl) {
+ this._moveSepEl = document.createElement('div');
+ this._moveSepEl.className =
'webfx-columnlist-separator-header';
+ this._eHead.appendChild(this._moveSepEl);
+ } }
+
+ /*
+ * Column move operation, determine position of column and move place
holder
+ * to that position. Also indicate in between which columns it will be
placed.
+ */
+ if (this._headerOper == COL_HEAD_MOVE) {
+ ox = this._headerData[1] + (x - this._headerData[2]);
+ this._moveEl.style.left = ox + 'px';
+
+ ox = 0, rx = x - this._headerData[3];
+ for (i = 0; i < this._cols; i++) {
+ ox += this._eHeadCols[i].offsetWidth;
+ if (ox >= rx) { break; }
+ }
+ if (i == this._cols) { this._moveSepEl.style.left =
(this._eHeadCols[this._cols-1].offsetLeft +
this._eHeadCols[this._cols-1].offsetWidth - 1) + 'px'; }
+ else { this._moveSepEl.style.left =
this._eHeadCols[i].offsetLeft + 'px'; }
+
+ this._headerData[4] = i;
+ }
+
+ /*
+ * Column resize operation, determine and set new size based on the
original
+ * size and the difference between the current mouse position and the
one that
+ * was recorded once the resize operation was started.
+ */
+ else if (this._headerOper == COL_HEAD_SIZE) {
+ w = this._headerData[1] + x - this._headerData[2];
+ tw = ((w - this._headerData[1]) + this._headerData[3]) + 1;
+ this._eHeadTable.style.width = tw + 'px';
+ if (w > 5) {
+ this._headerData[0].style.width = w + 'px';
+ if (this.bodyColResize) {
+ this._eBodyTable.style.width = tw + 'px';
+
this._eBodyTable.getElementsByTagName('colgroup')[0].getElementsByTagName('col')[this._headerData[0].cellIndex].style.width
= w + 'px';
+ } } }
+
+ else { this._checkHeaderOperation(el, x); }
+
+};
+
+
+WebFXColumnList.prototype._mouseDown = function(e) {
+ var el = (e)?e.target:window.event.srcElement;
+ var x = (e)?e.pageX:window.event.x + this._eBody.scrollLeft;
+
+ if ((el.tagName == 'TD') &&
(el.parentNode.parentNode.parentNode.parentNode.className ==
'webfx-columnlist-head')) {
+ this._checkHeaderOperation(el, x);
+
+ if (this._headerOper == COL_HEAD_EDGE) {
+ if (this.bodyColResize) {
this._sizeBodyAccordingToHeader(); }
+ this._headerOper = COL_HEAD_SIZE;
+ }
+ else if (this._headerOper == COL_HEAD_OVER) {
+ this._headerOper = COL_HEAD_DOWN;
+ this._headerData[0].className =
'webfx-columnlist-active-header';
+ } }
+};
+
+
+WebFXColumnList.prototype._mouseUp = function(e) {
+ var el = (e)?e.target:window.event.srcElement;
+ var x = (e)?e.pageX:window.event.x + this._eBody.scrollLeft;
+
+ if (this._headerOper == COL_HEAD_SIZE) {
+
+ }
+ else if (this._headerOper == COL_HEAD_MOVE) {
+ if (this._moveEl) { this._eHead.removeChild(this._moveEl);
this._moveEl = null; }
+ if (this._moveSepEl) {
this._eHead.removeChild(this._moveSepEl); this._moveSepEl = null; }
+ this._moveColumn(this._headerData[0].cellIndex,
this._headerData[4]);
+ }
+ else if (this._headerOper == COL_HEAD_DOWN) {
+ this.sort(el.cellIndex);
+ }
+
+ if (this._headerOper != COL_HEAD_NONE) {
+ this._headerOper = COL_HEAD_NONE;
+ this._eCont.style.cursor = 'default';
+ this._headerData[0].className = '';
+ this._headerData = null;
+ this._sizeBodyAccordingToHeader();
+ }
+
+};
+
+
+WebFXColumnList.prototype._click = function(e) {
+ var el = (e)?e.target:window.event.srcElement;
+ if (el.tagName == 'IMG') { el = el.parentNode; }
+ if (el.tagName == 'DIV') { el = el.parentNode; }
+ if ((el.tagName == 'TD') &&
(el.parentNode.parentNode.parentNode.parentNode.className ==
'webfx-columnlist-body')) {
+ if (((e)?e.shiftKey:window.event.shiftKey) &&
(this.selectedRows.length) && (this.multiple)) {
+
this.selectRange(this.selectedRows[this.selectedRows.length-1],
el.parentNode.rowIndex);
+ }
+ else { this.selectRow(el.parentNode.rowIndex,
(e)?e.ctrlKey:window.event.ctrlKey); }
+} };
+
+
+/*
+ * Event handler helpers
+ */
+
+WebFXColumnList.prototype._checkHeaderOperation = function(el, x) {
+ var prev, next, left, right, l, r;
+
+ /*
+ * Checks if the mouse cursor is near the edge of a header
+ * cell, in that case the cursor is set to 'e-resize' and
+ * the operation is set to COL_HEAD_EDGE, if it's over the
+ * header but not near the edge it's set to COL_HEAD_OVER
+ * and finnaly if it's not over the header it's set to
+ * COL_HEAD_NONE. The operation value is used to trigger
+ * column resize, move and sort commands.
+ */
+
+ if ((el.tagName == 'TD') &&
(el.parentNode.parentNode.parentNode.parentNode.className ==
'webfx-columnlist-head')) {
+ if (el.tagName == 'IMG') { el = el.parentNode; }
+
+ prev = el.previousSibling;
+ next = el.nextSibling;
+ left = getLeftPos(el);
+ right = left + el.offsetWidth;
+ l = (x - 5) - left;
+ r = right - x;
+
+ if ((l < 5) && (prev)) {
+ this._eCont.style.cursor = 'e-resize';
+ this._headerOper = COL_HEAD_EDGE;
+ this._headerData = [prev, prev.offsetWidth - 5,
x, this._eHeadTable.offsetWidth];
+ }
+ else if (r < 5) {
+ this._eCont.style.cursor = 'e-resize';
+ this._headerOper = COL_HEAD_EDGE;
+ this._headerData = [el, el.offsetWidth - 5, x,
this._eHeadTable.offsetWidth];
+ }
+ else {
+ this._eCont.style.cursor = 'default';
+ this._headerOper = COL_HEAD_OVER;
+ this._headerData = [el, el.offsetLeft, x,
getLeftPos(this._eHead), el.cellIndex];
+ } }
+ else {
+ this._eCont.style.cursor = 'default';
+ this._headerOper = COL_HEAD_NONE;
+ this._headerData = null;
+} };
+
+
+WebFXColumnList.prototype._sizeBodyAccordingToHeader = function() {
+ var aCols =
this._eBodyTable.getElementsByTagName('colgroup')[0].getElementsByTagName('col');
+ var length = aCols.length;
+ var bNoScrollbar = ((this._eBody.offsetWidth - this._eBody.clientWidth)
== 2);
+ this._eBodyTable.style.width = this._eHeadTable.offsetWidth -
((bNoScrollbar)?2:0) + 'px';
+ for (var i = 0; i < length; i++) {
+ aCols[i].style.width = (this._eHeadCols[i].offsetWidth -
((document.all)?2:0)) - (((bNoScrollbar && i) == (length - 1))?2:0) + 'px';
+} };
+
+
+/*
+ * void moveColumn(iColumnIndex, iNewColumnIndex)
+ * Moves column from givin column index to new index.
+ */
+WebFXColumnList.prototype._moveColumn = function(iCol, iNew) {
+ var i, oParent, oCol, oBefore, aRows, a;
+
+ if (iCol == iNew) { return; }
+
+ /* Move header */
+ oCol = this._eHeadCols[iCol];
+ oParent = oCol.parentNode;
+ if (iNew == this._cols) {
+ oParent.removeChild(oCol);
+ oParent.appendChild(oCol);
+ }
+ else {
+ oBefore = this._eHeadCols[iNew];
+ oParent.removeChild(oCol);
+ oParent.insertBefore(oCol, oBefore);
+ }
+
+ /* Move cols */
+ oCol =
this._eBodyTable.getElementsByTagName('colgroup')[0].getElementsByTagName('col')[iCol];
+ oParent = oCol.parentNode;
+ if (iNew == this._cols) {
+ oParent.removeChild(oCol);
+ oParent.appendChild(oCol);
+ }
+ else {
+ oBefore =
this._eBodyTable.getElementsByTagName('colgroup')[0].getElementsByTagName('col')[iNew];
+ oParent.removeChild(oCol);
+ oParent.insertBefore(oCol, oBefore);
+ }
+
+ /* Move cells */
+ aRows = this._eBodyTable.tBodies[0].rows;
+ this._rows = aRows.length;
+ for (i = 0; i < this._rows; i++) {
+ oCol = aRows[i].cells[iCol];
+ oParent = aRows[i];
+
+ if (iNew == this._cols) {
+ oParent.removeChild(oCol);
+ oParent.appendChild(oCol);
+ }
+ else {
+ oBefore = aRows[i].cells[iNew];
+ oParent.removeChild(oCol);
+ oParent.insertBefore(oCol, oBefore);
+ } }
+
+ /* Reorganize column type and sort data */
+ a = new Array();
+ oCol = this._aColumnTypes[iCol];
+ for (i = 0; i < this._aColumnTypes.length; i++) {
+ if (i == iCol) { continue; }
+ if (i == iNew) { a.push(oCol); }
+ a.push(this._aColumnTypes[i]);
+ }
+ if (iNew == this._aColumnTypes.length - 1) { a.push(oCol); }
+ this._aColumnTypes = a;
+ this.setSortTypes(a);
+
+ /* If sorted by column, update sortCol property */
+ if (iCol == this.sortCol) { this.sortCol = iNew; }
+};
+
+
+/*
+ * void _setAlignment()
+ * Sets column alignment
+ */
+WebFXColumnList.prototype._setAlignment = function() {
+ var i, aRows, aAlign, j;
+
+ aAlign = new Array();
+ for (i = 0; i < this._cols; i++) {
+ switch (this._aColumnAlign[i]) {
+ case ALIGN_LEFT: align = 'left'; break;
+ case ALIGN_CENTER: align = 'center'; break;
+ case ALIGN_RIGHT: align = 'right'; break;
+ case ALIGN_AUTO:
+ default:
+ switch(this._aColumnTypes[i]) {
+ case TYPE_NUMBER: align = 'right';
break;
+ default: align = 'left';
+ };
+ };
+ aAlign.push(align);
+ }
+
+ /* Set alignment for headers */
+ for (i = 0; i < this._cols; i++) {
+ this._eHeadCols[i].style.textAlign = aAlign[i];
+ }
+
+ /*
+ * Set alignment for rows.
+ * IE supports the align property on cols in colgorups. As thats the,
by far,
+ * fastest way of setting it, that what we'll use.
+ */
+ var aCols =
this._eBodyTable.getElementsByTagName('colgroup')[0].getElementsByTagName('col');
+ var length = aCols.length;
+ if (document.all) {
+ for (var i = 0; i < length; i++) {
+ aCols[i].align = aAlign[i];
+ } }
+
+ /*
+ * Mozilla does not support the align property, so we'll update the
style
+ * sheet rule for each column instead. Still a lot faster than setting
the
+ * style text-alignment property for all cells.
+ */
+ else {
+ var ss = null, rules = null;
+ for (var n = 0; n < document.styleSheets.length; n++) {
+ if
(document.styleSheets[n].href.indexOf('columnlist.css') == -1) { continue; }
+ ss = document.styleSheets[n];
+ rules = ss.cssRules;
+ }
+ if (!rules) { return; }
+
+ if (!this._aColRules) { this._aColRules = new Array(); }
+ for (var j = 0; j < length; j++) {
+ if (!this._aColRules[j]) {
+ for (var i = 0; i < rules.length; i++) {
+ if ((rules[i].type ==
CSSRule.STYLE_RULE) && (rules[i].selectorText == '.webfx-columnlist-col-' + j))
{
+ this._aColRules[j] = rules[i];
+ break;
+ } } }
+ if (this._aColRules[j]) {
+ this._aColRules[j].style.textAlign = aAlign[j];
+ }
+ else { this._aColRules[j] =
ss.insertRule('.webfx-columnlist-col-' + j + ' { text-align: ' + aAlign[j] +
'};', 0); }
+} } };
+
+
+/*
+ * Helper functions
+ */
+
+function getLeftPos(_el) {
+ var x = 0;
+ for (var el = _el; el; el = el.offsetParent) {
+ x += el.offsetLeft;
+ }
+ return x;
+}
+
+
+function compareNumericAsc(n1, n2) {
+ if (Number(n1) < Number(n2)) { return -1; }
+ if (Number(n1) > Number(n2)) { return 1; }
+ return 0;
+}
+
+
+function getInnerText(el) {
+ if (document.all) { return el.innerText; }
+ var str = '';
+ var cs = el.childNodes;
+ var l = cs.length;
+ for (var i = 0; i < l; i++) {
+ switch (cs[i].nodeType) {
+ case 1: //ELEMENT_NODE
+ str += getInnerText(cs[i]);
+ break;
+ case 3: //TEXT_NODE
+ str += cs[i].nodeValue;
+ break;
+ } }
+ return str;
+}
Index: sitemgr/js/columnlist/original/api.html
diff -u /dev/null sitemgr/js/columnlist/original/api.html:1.1.2.1
--- /dev/null Mon Mar 27 13:13:24 2006
+++ sitemgr/js/columnlist/original/api.html Mon Mar 27 13:13:24 2006
@@ -0,0 +1,58 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <title>ColumnList Usage (WebFX)</title>
+ <meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
+ <!-- WebFX Layout Include -->
+ <script type="text/javascript"
src="local/webfxlayout.js"></script>
+ <script type="text/javascript" src="local/webfxapi.js"></script>
+ <!-- end WebFX Layout Includes -->
+ <link type="text/css" rel="stylesheet" href="columnlist.css" />
+ <script src="columnlist.js" type="text/javascript"></script>
+ </head>
+ <body>
+ <!-- WebFX Layout Include -->
+ <script type="text/javascript">
+ //<![CDATA[
+ var articleMenu= new WebFXMenu;
+ articleMenu.left = 384;
+ articleMenu.top = 86;
+ articleMenu.width = 140;
+ articleMenu.add(new WebFXMenuItem("Introduction",
"columnlist.html"));
+ articleMenu.add(new WebFXMenuItem("Implementation",
"implementation.html"));
+ articleMenu.add(new WebFXMenuItem("Usage",
"usage.html"));
+ articleMenu.add(new WebFXMenuItem("API", "api.html"));
+ articleMenu.add(new WebFXMenuItem("Implementation",
"implementation.html"));
+ articleMenu.add(new WebFXMenuItem("Demo", "demo.html"));
+ articleMenu.add(new WebFXMenuSeparator);
+ articleMenu.add(new WebFXMenuItem("Download",
"http://webfx.eae.net/download/collist103.zip"));
+ webfxMenuBar.add(new WebFXMenuButton("Article Menu",
null, null, articleMenu));
+
+ webfxLayout.writeTitle("ColumnList API");
+ webfxLayout.writeMenu();
+ webfxLayout.writeDesignedByEdger();
+ //]]>
+ </script>
+ <!-- End WebFX Layout Includes -->
+ <div class="webfx-main-body">
+ <h2 id="ColumnList">ColumnList</h2><p>
+ The class that represents a column list.<br />
+ All indexes are zero based.
+ </p><h3>Syntax</h3><pre>new
ColumnList();</pre><h3>Parameters</h3><h3>Static
Methods</h3><table><thead><tr><td>Name</td><td>Description</td></tr></thead><tbody><tr><td
colspan="2">None.</td></tr></tbody></table><h3>Static
Fields</h3><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td
colspan="3">None.</td></tr></tbody></table><h3>Methods</h3><table><thead><tr><td>Name</td><td>Description</td></tr></thead><tbody><tr><td><a
class="helpLink" href="javascript://" onclick="toggleMethodArguments( event,
this ); return false;">addRow</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.addRow(<span
class="methodArgument">aRowData</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>aRowData</code></td><td><code>String[]</code></td><td>Array
containing data for the new row. Each element represents a
cell.</td></tr></tbody></table><h4>Return
Type</h4><p><code>iErrorCode</code></p></div></div></td><td>Appends supplied
row to the column list.</td></tr><tr><td><a class="helpLink"
href="javascript://" onclick="toggleMethodArguments( event, this ); return
false;">addRows</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.addRows(<span
class="methodArgument">aData</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>aData</code></td><td><code>String[][]</code></td><td>Two
dimensional array containing the data. The first dimension specifies the row
and the second the column, thus each element represents a
cell.</td></tr></tbody></table><h4>Return
Type</h4><p><code>iErrorCode</code></p></div></div></td><td>Appends supplied
rows to the column list.</td></tr><tr><td><a class="helpLink"
href="javascript://" onclick="toggleMethodArguments( event, this ); return
false;">bind</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.bind(<span class="methodArgument">eCont</span>,
<span class="methodArgument">eHead</span>, <span
class="methodArgument">eBody</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>eCont</code></td><td><code>HTML
Element</code></td><td>The outer
container.</td></tr><tr><td><code>eHead</code></td><td><code>HTML
Element</code></td><td>Container with the column list
header.</td></tr><tr><td><code>eBody</code></td><td><code>HTML
Element</code></td><td>Container with the column list
body.</td></tr></tbody></table><h4>Return
Type</h4><p><code>MenuItem</code></p></div></div></td><td>Binds column list to
an existing HTML structure. See the usage instructions for further
information.</td></tr><tr><td><a class="helpLink" href="javascript://"
onclick="toggleMethodArguments( event, this ); return false;">calcSize</a><div
class="methodContainer"><div class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.calcSize()</code></p><h4>Arguments</h4><p>No
Arguments.</p><h4>Return
Type</h4><p><code>void</code></p></div></div></td><td>Recalculates the size of
the column list widget. Should be called if the size of the outermost container
is changed.</td></tr><tr><td><a class="helpLink" href="javascript://"
onclick="toggleMethodArguments( event, this ); return false;">clear</a><div
class="methodContainer"><div class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.clear()</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td></td></tr></tbody></table><h4>Return
Type</h4><p><code>iErrorCode</code></p></div></div></td><td>Removes all rows
from column list.</td></tr><tr><td><a class="helpLink" href="javascript://"
onclick="toggleMethodArguments( event, this ); return false;">create</a><div
class="methodContainer"><div class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.create(<span
class="methodArgument">eContent</span>, <span
class="methodArgument">aColumns</span>, <span
class="methodArgument">aColumns</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>eContent</code></td><td><code>HTML
Element</code></td><td>The target container which the column list will be
based
upon.</td></tr><tr><td><code>aColumns</code></td><td><code>String[]</code></td><td>Array
containing the desired column
names.</td></tr><tr><td><code>aColumns</code></td><td><code>[][]</code></td><td>Optionallt
a two dimensional array can be specified instead for the aColumns parameter.
In that case the first child element is the column header, the second the width
(number and unit, ex '30%') and the third the data type, see setColumnTypes for
values.</td></tr></tbody></table><h4>Return
Type</h4><p><code>iErrorCode</code></p></div></div></td><td>Transforms the
supplied container into an empty column list.</td></tr><tr><td><a
class="helpLink" href="javascript://" onclick="toggleMethodArguments( event,
this ); return false;">getCellValue</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.getCellValue(<span
class="methodArgument">iRowIndex</span>, <span
class="methodArgument">iColIndex</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iRowIndex</code></td><td><code>Number</code></td><td>Row
index.</td></tr><tr><td><code>iColIndex</code></td><td><code>Number</code></td><td>Column
index.</td></tr></tbody></table><h4>Return
Type</h4><p><code>String</code></p></div></div></td><td>Returns the content of
the specified cell.</td></tr><tr><td><a class="helpLink" href="javascript://"
onclick="toggleMethodArguments( event, this ); return
false;">getColumnCount</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.getColumnCount()</code></p><h4>Arguments</h4><p>No
Arguments.</p><h4>Return
Type</h4><p><code>Number</code></p></div></div></td><td>Returns the number of
columns in the column list.</td></tr><tr><td><a class="helpLink"
href="javascript://" onclick="toggleMethodArguments( event, this ); return
false;">getRowCount</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.getRowCount()</code></p><h4>Arguments</h4><p>No
Arguments.</p><h4>Return
Type</h4><p><code>Number</code></p></div></div></td><td>Returns the number of
rows in the column list.</td></tr><tr><td><a class="helpLink"
href="javascript://" onclick="toggleMethodArguments( event, this ); return
false;">getSelectedRange</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.getSelectedRange()</code></p><h4>Arguments</h4><p>No
Arguments.</p><h4>Return
Type</h4><p><code>Number[]</code></p></div></div></td><td>Returns an array
containing the row indexes of all selected rows.</td></tr><tr><td><a
class="helpLink" href="javascript://" onclick="toggleMethodArguments( event,
this ); return false;">getSelectedRow</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.getSelectedRow()</code></p><h4>Arguments</h4><p>No
Arguments.</p><h4>Return
Type</h4><p><code>Number</code></p></div></div></td><td>Returns the row index
of the selected row. If multiple rows are selected the first one is
returned.</td></tr><tr><td><a class="helpLink" href="javascript://"
onclick="toggleMethodArguments( event, this ); return
false;">removeRange</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.removeRange(<span
class="methodArgument">iFromRowIndex</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iFromRowIndex</code></td><td><code>Number</code></td><td>Index
of the first row to remove.</td></tr></tbody></table><h4>Return
Type</h4><p><code>iErrorCode</code></p></div></div></td><td>Removes all rows in
the range defined by the iFromRowIndex and iToRowIndex
parameters.</td></tr><tr><td><a class="helpLink" href="javascript://"
onclick="toggleMethodArguments( event, this ); return
false;">removeRange</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.removeRange(<span
class="methodArgument">iRowIndex</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iRowIndex</code></td><td><code>Number[]</code></td><td>Array
containing the row indexes to remove.</td></tr></tbody></table><h4>Return
Type</h4><p><code>iErrorCode</code></p></div></div></td><td>Removes all rows
specified in the iRowIndex parameter.</td></tr><tr><td><a class="helpLink"
href="javascript://" onclick="toggleMethodArguments( event, this ); return
false;">removeRow</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.removeRow(<span
class="methodArgument">iRowIndex</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iRowIndex</code></td><td><code>Number</code></td><td>Index
of the row to remove.</td></tr></tbody></table><h4>Return
Type</h4><p><code>iErrorCode</code></p></div></div></td><td>Removes the row
identified by the sequence number supplied.</td></tr><tr><td><a
class="helpLink" href="javascript://" onclick="toggleMethodArguments( event,
this ); return false;">resize</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.resize(<span class="methodArgument">iWidth</span>,
<span
class="methodArgument">iHeight</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iWidth</code></td><td><code>Number</code></td><td>Desired
width in
pixels.</td></tr><tr><td><code>iHeight</code></td><td><code>Number</code></td><td>Desired
height in pixels.</td></tr></tbody></table><h4>Return
Type</h4><p><code>void</code></p></div></div></td><td>Resize the grid to the
given dimensions, the outer (border) size is given, not the inner (content)
size.</td></tr><tr><td><a class="helpLink" href="javascript://"
onclick="toggleMethodArguments( event, this ); return
false;">selectRange</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.selectRange(<span
class="methodArgument">iFromRowIndex</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iFromRowIndex</code></td><td><code>Number</code></td><td>Index
of the first row to select.</td></tr></tbody></table><h4>Return
Type</h4><p><code>iErrorCode</code></p></div></div></td><td>Selects all rows in
the range defined by the iFromRowIndex and iToRowIndex
parameters.</td></tr><tr><td><a class="helpLink" href="javascript://"
onclick="toggleMethodArguments( event, this ); return
false;">selectRange</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.selectRange(<span
class="methodArgument">iRowIndex</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iRowIndex</code></td><td><code>Number[]</code></td><td>Array
containing the row indexes to select.</td></tr></tbody></table><h4>Return
Type</h4><p><code>iErrorCode</code></p></div></div></td><td>Selects all rows
specified in the iRowIndex parameter.</td></tr><tr><td><a class="helpLink"
href="javascript://" onclick="toggleMethodArguments( event, this ); return
false;">selectRow</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.selectRow(<span
class="methodArgument">iRowIndex</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iRowIndex</code></td><td><code>Number</code></td><td>Index
of the row to select.</td></tr></tbody></table><h4>Return
Type</h4><p><code>iErrorCode</code></p></div></div></td><td>Selects the row
identified by the sequence number supplied.</td></tr><tr><td><a
class="helpLink" href="javascript://" onclick="toggleMethodArguments( event,
this ); return false;">setCellValue</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.setCellValue(<span
class="methodArgument">iRowIndex</span>, <span
class="methodArgument">iColIndex</span>, <span
class="methodArgument">sValue</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iRowIndex</code></td><td><code>Number</code></td><td>Row
index.</td></tr><tr><td><code>iColIndex</code></td><td><code>Number</code></td><td>Column
index.</td></tr><tr><td><code>sValue</code></td><td><code>String</code></td><td>Desired
value.</td></tr></tbody></table><h4>Return
Type</h4><p><code>iErrorCode</code></p></div></div></td><td>Sets the content of
the specified cell.</td></tr><tr><td><a class="helpLink" href="javascript://"
onclick="toggleMethodArguments( event, this ); return
false;">setColumnAlignment</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.setColumnAlignment(<span
class="methodArgument">iAlignment</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iAlignment</code></td><td><code>Number[]</code></td><td>An
array containing the alignment types. ALIGN_AUTO, ALIGN_LEFT, ALIGN_CENTER or
ALIGN_RIGHT.</td></tr></tbody></table><h4>Return
Type</h4><p><code>void</code></p></div></div></td><td>Sets column text
alignment.</td></tr><tr><td><a class="helpLink" href="javascript://"
onclick="toggleMethodArguments( event, this ); return
false;">setColumnTypes</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.setColumnTypes(<span
class="methodArgument">iTypesTypes</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iTypesTypes</code></td><td><code>Number[]</code></td><td>An
array containing the sort types. STRING, TYPE_NUMBER, TYPE_DATE,
TYPE_STRING_NO_CASE or custom string value that will be passed to sortable
table. Can be registered with the SortableTable.prototype.addSortType
method.</td></tr></tbody></table><h4>Return
Type</h4><p><code>void</code></p></div></div></td><td>Sets the column data
types. Used to determine alignment and sorting.</td></tr><tr><td><a
class="helpLink" href="javascript://" onclick="toggleMethodArguments( event,
this ); return false;">setSortTypes</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.setSortTypes(<span
class="methodArgument">iTypesTypes</span>)</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iTypesTypes</code></td><td><code>Number[]</code></td><td>An
array containing the sort types. STRING, TYPE_NUMBER, TYPE_DATE,
TYPE_STRING_NO_CASE or custom string value that will be passed to sortable
table. Can be registered with the SortableTable.prototype.addSortType
method.</td></tr></tbody></table><h4>Return
Type</h4><p><code>void</code></p></div></div></td><td>Sets the column data
types. Used to determine alignment and sorting.</td></tr><tr><td><a
class="helpLink" href="javascript://" onclick="toggleMethodArguments( event,
this ); return false;">sort</a><div class="methodContainer"><div
class="methodInfo"><h4>Syntax</h4><p><code><span
class="object">object</span>.sort(<span
class="methodArgument">iColumnIndex</span> [, <span
class="methodArgument">bDescending</span>])</code></p><h4>Arguments</h4><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>iColumnIndex</code></td><td><code>Number</code></td><td>Index
of column to sort
by.</td></tr><tr><td><code>bDescending</code></td><td><code>Boolean</code></td><td><span
class="optional">Optional.</span> Sort will be descending if true, ascending
if false..<span class="defaultSentence">
+ The default value is <code>false</code>.
+ </span></td></tr></tbody></table><h4>Return
Type</h4><p><code>void</code></p></div></div></td><td>Sorts the column list by
the specified
column.</td></tr></tbody></table><h3>Fields</h3><table><thead><tr><td>Name</td><td>Type</td><td>Descripton</td></tr></thead><tbody><tr><td><code>bodyColResize</code></td><td><code>Boolean</code></td><td>If
enabled the size of the body columns will be updated as the header column is
resized, if not the size of the body columns won't update until resize
operation has
completed.</td></tr><tr><td><code>colorEvenRows</code></td><td><code>Boolean</code></td><td>If
enabled odd and even rows will have different class names (odd and even) to
allow their background color to be
different.</td></tr><tr><td><code>columnAlign</code></td><td><code>Boolean</code></td><td>Enable
column text alignment. If enabled the text alignment of columns can be set
explicitly or determined implicit based on column data
type.</td></tr><tr><td><code>columnSorting</code></td><td><code>Boolean</code></td><td>Enable
column sorting. If enabled sort order can be set by clicking the column
headers.</td></tr><tr><td><code>error</code></td><td><code>String</code></td><td><span
class="readOnly">Read only.</span> If a method has returned an error code this
property will contain an error
message.</td></tr><tr><td><code>moveColumns</code></td><td><code>Boolean</code></td><td>Enable
column moving. If enabled columns can be reorganized using drag and
drop.</td></tr><tr><td><code>multiple</code></td><td><code>Boolean</code></td><td>If
true multiple selection is allowed, if false it's
not.</td></tr><tr><td><code>resizeColumns</code></td><td><code>Boolean</code></td><td>Enable
column resizing. If enabled the columns may be resized by dragging the border
between two column
headers.</td></tr><tr><td><code>rowSelection</code></td><td><code>Boolean</code></td><td>Enable
column selection. If enabled rows can be selected using either the mouse or
keyboard.</td></tr><tr><td><code>selectedRows</code></td><td><code>Number[]</code></td><td><span
class="readOnly">Read only.</span> An array containing the indexes of all
selected
rows.</td></tr><tr><td><code>sortAscImage</code></td><td><code>String</code></td><td>Image
used to indicate ascending sort
order</td></tr><tr><td><code>sortCol</code></td><td><code>Number</code></td><td><span
class="readOnly">Read only.</span> Indicates which column the column list is
sorted by or -1 if it is not
sorted.</td></tr><tr><td><code>sortDescending</code></td><td><code>Boolean</code></td><td><span
class="readOnly">Read only.</span> Indicates sort direction. False for
ascending, true for
descending.</td></tr><tr><td><code>sortDescImage</code></td><td><code>String</code></td><td>Image
used to indicate descending sort
order</td></tr></tbody></table><h3>Events</h3><table><thead><tr><td>Name</td><td>Descripton</td></tr></thead><tbody><tr><td><code>onresize</code></td><td>Reference
to function that will be called when the widget has been
resized.</td></tr><tr><td><code>onselect</code></td><td>Reference to function
that will be called when a row has been
selected.</td></tr><tr><td><code>onsort</code></td><td>Reference to function
that will be called when a sort operation has been
performed.</td></tr></tbody></table><h3>Remarks</h3><p>
+ None.
+ </p>
+ <p>
+ <a href="columnlist.html">Introduction</a><br />
+ <a
href="implementation.html">Implementation</a><br />
+ <a href="usage.html">Usage</a><br />
+ API<br />
+ <a href="demo.html">Demo</a><br />
+ <a
href="http://webfx.eae.net/download/collist103.zip">Download</a>
+ </p>
+ <p class="author">Author: Emil A Eklund</p>
+ <!-- end webfx-main-body -->
+ </div>
+ </body>
+</html>
Index: sitemgr/js/columnlist/original/api.xml
diff -u /dev/null sitemgr/js/columnlist/original/api.xml:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/api.xml Mon Mar 27 13:13:24 2006
@@ -0,0 +1,198 @@
+<?xml version="1.0"?>
+
+<?xml-stylesheet type="text/xsl" href="api.xsl"?>
+
+<documentation>
+
+<class name="ColumnList">
+
+ <description>
+ The class that represents a column list.<br/>
+ All indexes are zero based.
+ </description>
+
+ <syntax>new ColumnList();</syntax>
+
+ <methods>
+ <method name="create">
+ <description>Transforms the supplied container into an
empty column list.</description>
+ <arguments>
+ <argument name="eContent" type="HTML Element"
description="The target container which the column list will be based upon." />
+ <argument name="aColumns" type="String[]"
description="Array containing the desired column names." />
+ <argument name="aColumns" type="[][]"
description="Optionallt a two dimensional array can be specified instead for
the aColumns parameter. In that case the first child element is the column
header, the second the width (number and unit, ex '30%') and the third the data
type, see setColumnTypes for values." />
+ </arguments>
+ <returns type="iErrorCode" description="Error code, a
non-zero value indicates failure." />
+ </method>
+ <method name="bind">
+ <description>Binds column list to an existing HTML
structure. See the usage instructions for further information.</description>
+ <arguments>
+ <argument name="eCont" type="HTML Element"
description="The outer container." />
+ <argument name="eHead" type="HTML Element"
description="Container with the column list header." />
+ <argument name="eBody" type="HTML Element"
description="Container with the column list body." />
+ </arguments>
+ <returns type="MenuItem" />
+ </method>
+ <method name="calcSize">
+ <description>Recalculates the size of the column list
widget. Should be called if the size of the outermost container is
changed.</description>
+ <returns type="void" />
+ </method>
+ <method name="selectRow">
+ <description>Selects the row identified by the sequence
number supplied.</description>
+ <arguments>
+ <argument name="iRowIndex" type="Number"
description="Index of the row to select." />
+ <arguments name="bMultiple" type="Boolean"
description="If set to true and multi-select is allowed the the previously
selected row will not be deselected. If the specified row is already selected
it will be deselected." optional="true" default="false" />
+ </arguments>
+ <returns type="iErrorCode" description="Error code, a
non-zero value indicates failure." />
+ </method>
+ <method name="selectRange">
+ <description>Selects all rows in the range defined by
the iFromRowIndex and iToRowIndex parameters.</description>
+ <arguments>
+ <argument name="iFromRowIndex" type="Number"
description="Index of the first row to select." />
+ <arguments name="iToRowIndex" type="Number"
description="Index of the last row to select." />
+ </arguments>
+ <returns type="iErrorCode" description="Error code, a
non-zero value indicates failure." />
+ </method>
+ <method name="selectRange">
+ <description>Selects all rows specified in the
iRowIndex parameter.</description>
+ <arguments>
+ <argument name="iRowIndex" type="Number[]"
description="Array containing the row indexes to select." />
+ </arguments>
+ <returns type="iErrorCode" description="Error code, a
non-zero value indicates failure." />
+ </method>
+ <method name="resize">
+ <description>Resize the grid to the given dimensions,
the outer (border) size is given, not the inner (content) size.</description>
+ <arguments>
+ <argument name="iWidth" type="Number"
description="Desired width in pixels." />
+ <argument name="iHeight" type="Number"
description="Desired height in pixels." />
+ </arguments>
+ <returns type="void" />
+ </method>
+ <method name="addRow">
+ <description>Appends supplied row to the column
list.</description>
+ <arguments>
+ <argument name="aRowData" type="String[]"
description="Array containing data for the new row. Each element represents a
cell." />
+ </arguments>
+ <returns type="iErrorCode" description="Error code, a
non-zero value indicates failure." />
+ </method>
+ <method name="addRows">
+ <description>Appends supplied rows to the column
list.</description>
+ <arguments>
+ <argument name="aData" type="String[][]"
description="Two dimensional array containing the data. The first dimension
specifies the row and the second the column, thus each element represents a
cell." />
+ </arguments>
+ <returns type="iErrorCode" description="Error code, a
non-zero value indicates failure." />
+ </method>
+ <method name="removeRow">
+ <description>Removes the row identified by the sequence
number supplied.</description>
+ <arguments>
+ <argument name="iRowIndex" type="Number"
description="Index of the row to remove." />
+ </arguments>
+ <returns type="iErrorCode" description="Error code, a
non-zero value indicates failure." />
+ </method>
+ <method name="removeRange">
+ <description>Removes all rows in the range defined by
the iFromRowIndex and iToRowIndex parameters.</description>
+ <arguments>
+ <argument name="iFromRowIndex" type="Number"
description="Index of the first row to remove." />
+ <arguments name="iToRowIndex" type="Number"
description="Index of the last row to remove." />
+ </arguments>
+ <returns type="iErrorCode" description="Error code, a
non-zero value indicates failure." />
+ </method>
+ <method name="removeRange">
+ <description>Removes all rows specified in the
iRowIndex parameter.</description>
+ <arguments>
+ <argument name="iRowIndex" type="Number[]"
description="Array containing the row indexes to remove." />
+ </arguments>
+ <returns type="iErrorCode" description="Error code, a
non-zero value indicates failure." />
+ </method>
+ <method name="clear">
+ <description>Removes all rows from column
list.</description>
+ <arguments />
+ <returns type="iErrorCode" description="Error code, a
non-zero value indicates failure." />
+ </method>
+ <method name="getSelectedRow">
+ <description>Returns the row index of the selected row.
If multiple rows are selected the first one is returned.</description>
+ <returns type="Number" description="Index of selected
row or -1 if no row is selected." />
+ </method>
+ <method name="getSelectedRange">
+ <description>Returns an array containing the row
indexes of all selected rows.</description>
+ <returns type="Number[]" description="Indexes of
selected rows or an empty array of no rows are selected." />
+ </method>
+ <method name="getRowCount">
+ <description>Returns the number of rows in the column
list.</description>
+ <returns type="Number" description="Number of rows." />
+ </method>
+ <method name="getColumnCount">
+ <description>Returns the number of columns in the
column list.</description>
+ <returns type="Number" description="Number of columns."
/>
+ </method>
+ <method name="getCellValue">
+ <description>Returns the content of the specified
cell.</description>
+ <arguments>
+ <argument name="iRowIndex" type="Number"
description="Row index." />
+ <argument name="iColIndex" type="Number"
description="Column index." />
+ </arguments>
+ <returns type="String" />
+ </method>
+ <method name="setCellValue">
+ <description>Sets the content of the specified
cell.</description>
+ <arguments>
+ <argument name="iRowIndex" type="Number"
description="Row index." />
+ <argument name="iColIndex" type="Number"
description="Column index." />
+ <argument name="sValue" type="String"
description="Desired value." />
+ </arguments>
+ <returns type="iErrorCode" description="Error code, a
non-zero value indicates failure." />
+ </method>
+ <method name="setColumnAlignment">
+ <description>Sets column text alignment.</description>
+ <arguments>
+ <argument name="iAlignment" type="Number[]"
description="An array containing the alignment types. ALIGN_AUTO, ALIGN_LEFT,
ALIGN_CENTER or ALIGN_RIGHT." />
+ </arguments>
+ <returns type="void" />
+ </method>
+ <method name="setColumnTypes">
+ <description>Sets the column data types. Used to
determine alignment and sorting.</description>
+ <arguments>
+ <argument name="iTypesTypes" type="Number[]"
description="An array containing the sort types. STRING, TYPE_NUMBER,
TYPE_DATE, TYPE_STRING_NO_CASE or custom string value that will be passed to
sortable table. Can be registered with the SortableTable.prototype.addSortType
method." />
+ </arguments>
+ <returns type="void" />
+ </method>
+ <method name="setSortTypes">
+ <description>Sets the column data types. Used to
determine alignment and sorting.</description>
+ <arguments>
+ <argument name="iTypesTypes" type="Number[]"
description="An array containing the sort types. STRING, TYPE_NUMBER,
TYPE_DATE, TYPE_STRING_NO_CASE or custom string value that will be passed to
sortable table. Can be registered with the SortableTable.prototype.addSortType
method." />
+ </arguments>
+ <returns type="void" />
+ </method>
+ <method name="sort">
+ <description>Sorts the column list by the specified
column.</description>
+ <arguments>
+ <argument name="iColumnIndex" type="Number"
description="Index of column to sort by." />
+ <argument name="bDescending" type="Boolean"
optional="true" default="false" description="Sort will be descending if true,
ascending if false.." />
+ </arguments>
+ <returns type="void" />
+ </method>
+ </methods>
+ <fields>
+ <field name="multiple" type="Boolean" default="true"
description="If true multiple selection is allowed, if false it's not." />
+ <field name="colorEvenRows" type="Boolean" default="true"
description="If enabled odd and even rows will have different class names (odd
and even) to allow their background color to be different." />
+ <field name="resizeColumns" type="Boolean" default="true"
description="Enable column resizing. If enabled the columns may be resized by
dragging the border between two column headers." />
+ <field name="bodyColResize" type="Boolean" default="true"
description="If enabled the size of the body columns will be updated as the
header column is resized, if not the size of the body columns won't update
until resize operation has completed." />
+ <field name="moveColumns" type="Boolean" default="true"
description="Enable column moving. If enabled columns can be reorganized using
drag and drop." />
+ <field name="rowSelection" type="Boolean" default="true"
description="Enable column selection. If enabled rows can be selected using
either the mouse or keyboard." />
+ <field name="columnSorting" type="Boolean" default="true"
description="Enable column sorting. If enabled sort order can be set by
clicking the column headers." />
+ <field name="columnAlign" type="Boolean" default="true"
description="Enable column text alignment. If enabled the text alignment of
columns can be set explicitly or determined implicit based on column data
type." />
+ <field name="sortAscImage" type="String"
default="images/asc.png" description="Image used to indicate ascending sort
order" />
+ <field name="sortDescImage" type="String"
default="images/desc.png" description="Image used to indicate descending sort
order" />
+ <field name="sortCol" type="Number" readOnly="true"
description="Indicates which column the column list is sorted by or -1 if it is
not sorted." />
+ <field name="sortDescending" type="Boolean" readOnly="true"
description="Indicates sort direction. False for ascending, true for
descending." />
+ <field name="error" type="String" readOnly="true"
description="If a method has returned an error code this property will contain
an error message." />
+ <field name="selectedRows" type="Number[]" readOnly="true"
description="An array containing the indexes of all selected rows." />
+ </fields>
+ <events>
+ <event name="onresize" description="Reference to function that
will be called when the widget has been resized." />
+ <event name="onsort" description="Reference to function that
will be called when a sort operation has been performed." />
+ <event name="onselect" description="Reference to function that
will be called when a row has been selected." />
+ </events>
+
+</class>
+
+</documentation>
\ No newline at end of file
Index: sitemgr/js/columnlist/original/article-images/ie.png
Index: sitemgr/js/columnlist/original/article-images/moz.png
Index: sitemgr/js/columnlist/original/columnlist.html
diff -u /dev/null sitemgr/js/columnlist/original/columnlist.html:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/columnlist.html Mon Mar 27 13:13:24 2006
@@ -0,0 +1,85 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <title>ColumnList (WebFX)</title>
+ <meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
+ <script type="text/javascript"
src="local/webfxlayout.js"></script>
+ </head>
+ <body>
+ <!-- WebFX Layout Include -->
+ <script type="text/javascript">
+ //<![CDATA[
+ var articleMenu= new WebFXMenu;
+ articleMenu.left = 384;
+ articleMenu.top = 86;
+ articleMenu.width = 140;
+ articleMenu.add(new WebFXMenuItem("Introduction",
"columnlist.html"));
+ articleMenu.add(new WebFXMenuItem("Implementation",
"implementation.html"));
+ articleMenu.add(new WebFXMenuItem("Usage",
"usage.html"));
+ articleMenu.add(new WebFXMenuItem("API", "api.html"));
+ articleMenu.add(new WebFXMenuItem("Demo", "demo.html"));
+ articleMenu.add(new WebFXMenuSeparator);
+ articleMenu.add(new WebFXMenuItem("Download",
"http://webfx.eae.net/download/collist103.zip"));
+ webfxMenuBar.add(new WebFXMenuButton("Article Menu",
null, null, articleMenu));
+
+ webfxLayout.writeTitle("ColumnList");
+ webfxLayout.writeMenu();
+ webfxLayout.writeDesignedByEdger();
+ //]]>
+ </script>
+ <!-- End WebFX Layout Includes -->
+ <div class="webfx-main-body">
+ <p>
+ <span class="date">2004-10-28</span>: First
public version released.<br />
+ <span class="date">2004-11-23</span>: Fixed
column resizing in mozilla. It still can't make columns smaller than their
content, but otherwise it seems to work.
+ <span class="date">2005-05-22</span>: Fixed a
bug in the removeRange method for index based removal, where the rows where
deleted in the wrong order. Also added a clear method, that removes all
rows.<br />
+ <span class="date">2005-12-08</span>: Fixed bug
that caused rows to be colored even if colorEvenRows was false.
+ Added rowSelection, columnSorting,
moveColumns, sortAscImage and sortDescImage properties.
+ Implemented column moving and alignment.
+ Updated column resizing implementation.
+ Added support for making columns
smaller than their content in Mozilla, bringing the Mozilla support up to pair
with that for IE.
+ Added support for specifying column
width on create.
+ </p>
+ <h2>Introduction</h2>
+ <p>
+ Since Erik wrote the <a
href="../sortabletable/sortabletable.html">Sortable Table</a>
+ article a year and a half ago we've received
quite a few questions about
+ how to combine it with the fixed header
example, demonstrated in the
+ <a
href="../syncscroll/syncscroll.html">Synchronized Scroll</a> article, thus
creating
+ a sortable table with a fixed header. However
it's not that easy to combine those and
+ the result has often been a disappointment.
+ </p>
+ <p>
+ This ColumnList widget tries to overcome this,
it uses the Sortable Table script
+ to perform the sorting and has a table with a
fixed header. It also adds a few extras;
+ such as a clean object oriented interface,
column resizing and, row coloring,
+ to name a few.
+ </p>
+ <h3>Attach or Generate</h3>
+ <p>
+ The widget can either attach to a set of
existing html elements or create the
+ necessary elements on-the-fly from a javascript
data structure.
+ Both methods has its advantages, it's more
efficient to attach to an existing
+ structure than to generate it, but on-the-fly
creation allows for mor flexibility.
+ Either way the content can be accessed and
modified in the same way regardless
+ of how the widget was created.
+ </p>
+ <h3>Multiple Selection</h3>
+ <p>
+ There's also an option to allow multiple
selection which, if enabled, makes it
+ possible to select more than one row using the
control or shift keys.
+ Other keyboard bindings, such as the up and
down arrow keys, are supported as well.
+ </p>
+ <p>
+ Introduction<br />
+ <a
href="implementation.html">Implementation</a><br />
+ <a href="usage.html">Usage</a><br />
+ <a href="api.html">API</a><br />
+ <a href="demo.html">Demo</a><br />
+ <a
href="http://webfx.eae.net/download/collist103.zip">Download</a>
+ </p>
+ <p class="author">Author: Emil A Eklund</p>
+ <!-- end webfx-main-body -->
+ </div>
+ </body>
+</html>
Index: sitemgr/js/columnlist/original/demo.html
diff -u /dev/null sitemgr/js/columnlist/original/demo.html:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/demo.html Mon Mar 27 13:13:24 2006
@@ -0,0 +1,85 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <link type="text/css" rel="stylesheet"
href="includes/columnlist.css" />
+ <script type="text/javascript"
src="includes/sortabletable.js"></script>
+ <script type="text/javascript"
src="includes/columnlist.js"></script>
+ <style type="text/css">
+ body { background: threedface; }
+ </style>
+ </head>
+ <body>
+ <div id="container" class="webfx-columnlist"
style="margin-left: 50px; width: 640px; height: 480px;">
+ <div id="head" class="webfx-columnlist-head">
+ <table cellspacing="0" cellpadding="0"
style="width: 200px;">
+ <tr>
+ <td>Flavor<img
src="images/asc.png"/></td><td>Color<img
src="images/asc.png"/></td><td>Texture<img
src="images/asc.png"/></td><td>Price<img src="images/asc.png"/></td>
+ </tr>
+ </table>
+ </div>
+ <div id="body" class="webfx-columnlist-body">
+ <table cellspacing="0" cellpadding="0"
style="width: 200px;">
+ <colgroup span="4">
+ <col style="width: 30%;" />
+ <col style="width: 30%;" />
+ <col style="width: 30%;" />
+ <col style="width: 10%;" />
+ </colgroup>
+
<tr><td>Vanilla</td><td>White</td><td>Smooth</td><td>10</td></tr>
+
<tr><td>Pear</td><td>Green</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Strawberry</td><td>Pink</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Chocolate</td><td>Brown</td><td>Chunky</td><td>8</td></tr>
+ <tr><td>Pistachio</td><td>Light
green</td><td>Chunky</td><td>9</td></tr>
+
<tr><td>Vanilla</td><td>White</td><td>Smooth</td><td>10</td></tr>
+
<tr><td>Pear</td><td>Green</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Strawberry</td><td>Pink</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Chocolate</td><td>Brown</td><td>Chunky</td><td>8</td></tr>
+ <tr><td>Pistachio</td><td>Light
green</td><td>Chunky</td><td>9</td></tr>
+
<tr><td>Vanilla</td><td>White</td><td>Smooth</td><td>10</td></tr>
+
<tr><td>Pear</td><td>Green</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Strawberry</td><td>Pink</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Chocolate</td><td>Brown</td><td>Chunky</td><td>8</td></tr>
+ <tr><td>Pistachio</td><td>Light
green</td><td>Chunky</td><td>9</td></tr>
+
<tr><td>Vanilla</td><td>White</td><td>Smooth</td><td>10</td></tr>
+
<tr><td>Pear</td><td>Green</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Strawberry</td><td>Pink</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Chocolate</td><td>Brown</td><td>Chunky</td><td>8</td></tr>
+ <tr><td>Pistachio</td><td>Light
green</td><td>Chunky</td><td>9</td></tr>
+
<tr><td>Vanilla</td><td>White</td><td>Smooth</td><td>10</td></tr>
+
<tr><td>Pear</td><td>Green</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Strawberry</td><td>Pink</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Chocolate</td><td>Brown</td><td>Chunky</td><td>8</td></tr>
+ <tr><td>Pistachio</td><td>Light
green</td><td>Chunky</td><td>9</td></tr>
+
<tr><td>Vanilla</td><td>White</td><td>Smooth</td><td>10</td></tr>
+
<tr><td>Pear</td><td>Green</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Strawberry</td><td>Pink</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Chocolate</td><td>Brown</td><td>Chunky</td><td>8</td></tr>
+ <tr><td>Pistachio</td><td>Light
green</td><td>Chunky</td><td>9</td></tr>
+
<tr><td>Vanilla</td><td>White</td><td>Smooth</td><td>10</td></tr>
+
<tr><td>Pear</td><td>Green</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Strawberry</td><td>Pink</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Chocolate</td><td>Brown</td><td>Chunky</td><td>8</td></tr>
+ <tr><td>Pistachio</td><td>Light
green</td><td>Chunky</td><td>9</td></tr>
+
<tr><td>Vanilla</td><td>White</td><td>Smooth</td><td>10</td></tr>
+
<tr><td>Pear</td><td>Green</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Strawberry</td><td>Pink</td><td>Smooth</td><td>8</td></tr>
+
<tr><td>Chocolate</td><td>Brown</td><td>Chunky</td><td>8</td></tr>
+ <tr><td>Pistachio</td><td>Light
green</td><td>Chunky</td><td>9</td></tr>
+ </table>
+ </div>
+ </div>
+ <br/>
+ <button
onclick="o.removeRow(o.getSelectedRow())">o.removeRow(o.getSelectedRow())</button>
+ <button
onclick="o.removeRange(o.getSelectedRange())">o.removeRange(o.getSelectedRange())</button>
+ <button onclick="alert(o.getCellValue(o.getSelectedRow(),
1))">alert(o.getCellValue(o.getSelectedRow(), 1))</button>
+ <button onclick="o.setCellValue(o.getSelectedRow(), 1,
'test')">o.setCellValue(o.getSelectedRow(), 1, 'test')</button>
+ </body>
+ <script type="text/javascript">
+ var o = new WebFXColumnList();
+ var rc = o.bind(document.getElementById('container'),
document.getElementById('head'), document.getElementById('body'));
+ o.setSortTypes([TYPE_STRING, TYPE_STRING, TYPE_STRING,
TYPE_NUMBER]);
+ o._setAlignment();
+ //o.resize(640, 480);
+ //o.sort(0);
+ </script>
+</html>
Index: sitemgr/js/columnlist/original/demo2.html
diff -u /dev/null sitemgr/js/columnlist/original/demo2.html:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/demo2.html Mon Mar 27 13:13:24 2006
@@ -0,0 +1,59 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <link type="text/css" rel="stylesheet"
href="includes/columnlist.css" />
+ <script type="text/javascript"
src="includes/sortabletable.js"></script>
+ <script type="text/javascript"
src="includes/columnlist.js"></script>
+ <style type="text/css">
+ html, body { margin: 0px; padding: 0px; overflow:
hidden; border: none; }
+ body { background: threedface; }
+ </style>
+ </head>
+ <body>
+ <div id="container"></div>
+ </body>
+ <script type="text/javascript">
+ //<![CDATA[
+ var aColumns = [
+ ['Rank', '10%', TYPE_NUMBER],
+ ['Flavor', '40%', TYPE_STRING],
+ ['Color', '40%', TYPE_STRING],
+ ['Share', '10%', TYPE_NUMBER]
+ ];
+
+ var aData = [
+ ['1','Vanilla','White','29%'],
+ ['2','Chocolate','Brown','8.9%'],
+ ['3','Butter pecan','Light brown','5.3%'],
+ ['4','Strawberry','Pink','5.3%'],
+ ['5','Neapolitan','Greenish brown','4.2%'],
+ ['6','Chocolate chip','Brown','3.9%'],
+ ['7','French vanilla','Yellowish white','3.8%'],
+ ['8','Cookies and cream','Light brown','3.6%'],
+ ['9','Vanilla fudge ripple','White', '2.6%'],
+ ['10','Praline pecan','Brown','1.7%'],
+ ['11','Cherry','Red','1.6%'],
+ ['12','Chocolate almond','Brown','1.6%'],
+ ['13','Coffee','Dark brown', '1.6%'],
+ ['14','Rocky road','brown', '1.5%'],
+ ['15','Chocolate marshmallow','Light brown','1.3%']
+ ];
+
+ var el = document.getElementById('container');
+
+ var o = new WebFXColumnList();
+ o.create(el, aColumns);
+ o.addRows(aData);
+
+ function calcSize() {
+ var dw =
(window.innerWidth)?window.innerWidth:document.documentElement.clientWidth;
+ var dh =
(window.innerHeight)?window.innerHeight:document.documentElement.clientHeight;
+ o.resize(dw-2, dh-2);
+ }
+
+ calcSize();
+
+ window.onresize = calcSize;
+ //]]>
+ </script>
+</html>
Index: sitemgr/js/columnlist/original/images/asc.png
Index: sitemgr/js/columnlist/original/images/desc.png
Index: sitemgr/js/columnlist/original/implementation.html
diff -u /dev/null sitemgr/js/columnlist/original/implementation.html:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/implementation.html Mon Mar 27 13:13:24 2006
@@ -0,0 +1,133 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <title>ColumnList Usage (WebFX)</title>
+ <meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
+ <script type="text/javascript"
src="local/webfxlayout.js"></script>
+ <link type="text/css" rel="stylesheet" href="columnlist.css" />
+ <script src="columnlist.js" type="text/javascript"></script>
+ </head>
+ <body>
+ <!-- WebFX Layout Include -->
+ <script type="text/javascript">
+ //<![CDATA[
+ var articleMenu= new WebFXMenu;
+ articleMenu.left = 384;
+ articleMenu.top = 86;
+ articleMenu.width = 140;
+ articleMenu.add(new WebFXMenuItem("Introduction",
"columnlist.html"));
+ articleMenu.add(new WebFXMenuItem("Implementation",
"implementation.html"));
+ articleMenu.add(new WebFXMenuItem("Usage",
"usage.html"));
+ articleMenu.add(new WebFXMenuItem("API", "api.html"));
+ articleMenu.add(new WebFXMenuItem("Demo", "demo.html"));
+ articleMenu.add(new WebFXMenuSeparator);
+ articleMenu.add(new WebFXMenuItem("Download",
"http://webfx.eae.net/download/collist103.zip"));
+ webfxMenuBar.add(new WebFXMenuButton("Article Menu",
null, null, articleMenu));
+
+ webfxLayout.writeTitle("ColumnList Implementation");
+ webfxLayout.writeMenu();
+ webfxLayout.writeDesignedByEdger();
+ //]]>
+ </script>
+ <!-- End WebFX Layout Includes -->
+ <div class="webfx-main-body">
+ <h2>Implementation</h2>
+ <p>
+ A ColumnList widget is basically a table where
the header is fixed and the body
+ scrollable. In HTML/XHTML terms that means a
table divided into a thead and a tbody section.
+ Where the <code>overflow</code> property of the
tbody is set to <code>auto</code> (or <code>scroll</code>).
+ </p>
+ <p>
+ The markup for such a table would look
something like this, notice the style argument in red.
+ The <code>overflow</code> property is pretty
meaningless if the height is set to <code>auto</code>
+ or if the height specified is greather than the
height of the content. Thus to demonstrate the
+ behavior it's set to slightly less than
required for all rows to be visible.
+ </p>
+ <p>
+ <pre><table cellspacing="0"
cellpadding="0">
+ <thead>
+
<tr><th>Flavor</th><th>Color</th><th>Texture</th><th>Price</th></tr>
+ </thead>
+ <tbody style="<span style="color: red;">height: 75px; overflow:
auto</span>;">
+
<tr><td>Vanilla</td><td>White</td><td>Smooth</td><td>$
10</td></tr>
+
<tr><td>Pear</td><td>Green</td><td>Smooth</td><td>$
8</td></tr>
+
<tr><td>Strawberry</td><td>Pink</td><td>Smooth</td><td>$
8</td></tr>
+
<tr><td>Chocolate</td><td>Brown</td><td>Chunky</td><td>$
8</td></tr>
+ <tr><td>Pistachio</td><td>Light
green</td><td>Chunky</td><td>$ 9</td></tr>
+ </tbody>
+</table></pre>
+ </p>
+ <h2>The Problem</h2>
+ <p>
+ The screenshots below shows what the example
code, together with a few css rules, looks like in Mozilla (Firefox 1.0 PR)
+ and Internet Explorer (6.0).
+ <p>
+ <p style="font-weight: bold;">Result in Mozilla</p>
+ <p>
+ <img src="article-images/moz.png" style="width:
304px; height: 99px;" alt="Example as rendered in Mozilla." />
+ </p>
+ <p style="font-weight: bold;">Result in Internet
Explorer</p>
+ <p>
+ <img src="article-images/ie.png" style="width:
304px; height: 413px;" alt="Example as rendered in Internet Explorer" />
+ </p>
+ <p>
+ In Mozilla the result is pretty much what would
be expected. The horizontal scrollbar is clearly not desirable,
+ but that's easy enough to resolve by setting
the <code>overflow</code> property to the mozilla specifiec
+ <code>-moz-scrollbars-vertical</code> value, or
by setting the <code>overflow-x</code> property to <code>hidden</code>
+ (<code>overflow-x</code>/<code>y</code> will be
supported in Mozilla Firefox 1.1).
+ </p>
+ <p>
+ In Internet Explorer on the other hand, the
result is nothing like what one would expect. The <code>overflow</code>
+ property on the tbody is completely ignored,
and the height applies to all rows rather than the entire body section.
+ </p>
+ <h3>The Solution</h3>
+ <p>
+ Since Internet Explorer is still, by far, the
most common browser this approach,
+ no matter how conveniently, is not going to cut
it. Instead we'll have to use two
+ tables. One for the headers and the other for
the body. Then by placing the table
+ containing the body in a scrollable container
(a block element, such as a
+ <code>div</code>, with a fixed height and the
<code>overflow</code> property set
+ to <code>auto</code>) the body can be scrolled
vertically without affecting the header.
+ </p>
+ <p>
+ Of course, this approach results in a whole set
of new issues;
+ columns got different widths in the header and
body and scrolling the body
+ horizontally does not affect the header. Those
issues, luckily, are quite
+ easy to deal with. Each header column is simply
resized according to the
+ equivalent body column and the header's
<code>scrollLeft</code> property is
+ synchronized to that of the body.
+ </p>
+ <h3>Mozilla quirks</h3>
+ <p>
+ After overcoming all the Internet Explorer
quirks it's time to deal with the
+ Mozilla ones.
+ <p>
+ Since the horizontal scroll of the header is
synchronized with that of the
+ body the overflow property is set to hidden, as
we don't want a horizontal
+ scrollbar for header.
+ </p>
+ <p>
+ However, mozilla does not allow the
<code>scroll*</code> properties on elements
+ with the <code>overflow</code> property set to
<code>hidden</code> thus we'll
+ have to set it to
<code>-moz-scrollbars-none</code> which is basically the same
+ as <code>hidden</code> in IE, the container has
overflow type <code>scroll</code>
+ but no scrollbars are shown.
+ </p>
+ <p>
+ Recent versions of Mozilla handles
<code>overflow: hidden</code> the same way Internet
+ Explorer does, rendering this work around
obsolete. However to remain compatible with
+ older Mozilla versions this code is still used.
+ </p>
+ <p>
+ <a href="columnlist.html">Introduction</a><br />
+ Implementation<br />
+ <a href="usage.html">Usage</a><br />
+ <a href="api.html">API</a><br />
+ <a href="demo.html">Demo</a><br />
+ <a
href="http://webfx.eae.net/download/collist103.zip">Download</a>
+ </p>
+ <p class="author">Author: Emil A Eklund</p>
+ <!-- end webfx-main-body -->
+ </div>
+ </body>
+</html>
Index: sitemgr/js/columnlist/original/includes/columnlist.css
diff -u /dev/null sitemgr/js/columnlist/original/includes/columnlist.css:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/includes/columnlist.css Mon Mar 27
13:13:24 2006
@@ -0,0 +1,99 @@
+.webfx-columnlist {
+ border: 1px solid;
+ border-color: threedshadow threedhighlight threedhighlight threedshadow;
+ overflow: hidden;
+ display: block;
+ -moz-user-select: none;
+ -moz-user-focus: normal;
+ -moz-user-input: enabled;
+}
+
+.webfx-columnlist td {
+ font: menu;
+ padding: 1px;
+ white-space: nowrap;
+}
+
+.webfx-columnlist-head {
+ position: absolute;
+ background: threedface;
+ overflow: hidden;
+ -moz-user-select: none;
+}
+
+.webfx-columnlist-head table {
+ table-layout: fixed;
+}
+
+.webfx-columnlist-head td {
+ border: 1px solid;
+ border-color: threedhighlight threedshadow threedshadow threedhighlight;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.webfx-columnlist-head td img {
+ width: 8px;
+ height: 7px;
+ margin: 0px 5px 0px 5px;
+ display: none;
+}
+
+.webfx-columnlist-body {
+ border: 1px solid;
+ border-color: threedhighlight threedface threedface threedhighlight;
+ background: window;
+ overflow: auto;
+}
+
+.webfx-columnlist-body table {
+ table-layout: fixed;
+}
+
+.webfx-columnlist-body td {
+ border-bottom: solid white;
+ border-width: 0px 1px 1px 0px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: no-wrap;
+}
+
+.webfx-columnlist-body tr.selected td {
+ background: #C0C0FF;
+}
+
+.webfx-columnlist-body tr.odd td {
+ background: #FFFFC0;
+}
+
+.webfx-columnlist-body tr.even td {
+ background: window;
+}
+
+.webfx-columnlist-move-header {
+ position: absolute;
+ background: threedshadow;
+ top: 0px;
+ font: menu;
+ padding: 2px;
+ height: 1em;
+ filter: Alpha(Opacity=50);
+ -moz-opacity: 0.5;
+ -moz-user-select: none;
+}
+
+.webfx-columnlist-active-header {
+ border-color: threedface !important;
+}
+
+.webfx-columnlist-separator-header {
+ position: absolute;
+ top: 0px;
+ left: 10px;
+ font: menu;
+ height: 1em;
+ width: 1px;
+ overflow: hidden;
+ background: blue;
+ padding: 3px 0px;
+}
Index: sitemgr/js/columnlist/original/includes/columnlist.js
diff -u /dev/null sitemgr/js/columnlist/original/includes/columnlist.js:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/includes/columnlist.js Mon Mar 27
13:13:24 2006
@@ -0,0 +1,1258 @@
+/*----------------------------------------------------------------------------\
+| Column List Widget 1.03 |
+|-----------------------------------------------------------------------------|
+| Created by Emil A Eklund |
+| (http://webfx.eae.net/contact.html#emil) |
+| For WebFX (http://webfx.eae.net/) |
+|-----------------------------------------------------------------------------|
+| A DHTML column list widget. Can be generated from supplied data or attached |
+| to an existing html structure. Supports multiple selection, sorting, column |
+| resizing, column moving and keyboard navigation. |
+|-----------------------------------------------------------------------------|
+| Copyright (c) 2004, 205 Emil A Eklund |
+|-----------------------------------------------------------------------------|
+| This software is provided "as is", without warranty of any kind, express or |
+| implied, including but not limited to the warranties of merchantability, |
+| fitness for a particular purpose and noninfringement. In no event shall the |
+| authors or copyright holders be liable for any claim, damages or other |
+| liability, whether in an action of contract, tort or otherwise, arising |
+| from, out of or in connection with the software or the use or other |
+| dealings in the software. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| This software is available under the three different licenses mentioned |
+| below. To use this software you must chose, and qualify, for one of those. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| The WebFX Non-Commercial License http://webfx.eae.net/license.html |
+| Permits anyone the right to use the software in a non-commercial context |
+| free of charge. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| The WebFX Commercial license http://webfx.eae.net/commercial.html |
+| Permits the license holder the right to use the software in a commercial |
+| context. Such license must be specifically obtained, however it's valid for |
+| any number of implementations of the licensed software. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt |
+| Permits anyone the right to use and modify the software without limitations |
+| as long as proper credits are given and the original and modified source |
+| code are included. Requires that the final product, software derivate from |
+| the original source or any software utilizing a GPL component, such as |
+| this, is also licensed under the GPL license. |
+|-----------------------------------------------------------------------------|
+| Dependencies: columnlist.css Column list style declarations |
+| sortabletable.js Provides table sorting functionality |
+|-----------------------------------------------------------------------------|
+| Browser compatibility: IE Verified, 6.0+ |
+| Mozilla Verified, 1.7+ (Firefox 1.0+) |
+| Opera Not Verified |
+| Safari/KTML: Not Verified |
+|-----------------------------------------------------------------------------|
+| 2004-08-22 | Work started. |
+| 2004-10-24 | First version published. |
+| 2004-11-01 | Added resizeColumns property, allowing column resizing to be |
+| | enabled/disabled. Fixed a bug in the sort method that caused |
+| | getSelectedRow to return an invalid index when called from the |
+| | function triggered by onselect. Misc bugfixes for Mozilla. |
+| 2004-11-23 | Fixed column resizing in mozilla. It still can't make columns |
+| | smaller than their content, but otherwise it seems to work. |
+| 2005-05-22 | Fixed a bug in the removeRange method for index based removal, |
+| | where the rows where deleted in the wrong order. Also added a |
+| | clear method, that removes all rows. |
+| 2005-11-30 | Fixed bug that caused rows to be colored even if colorEvenRows |
+| | was false. Added rowSelection, columnSorting, moveColumns, |
+| | sortAscImage and sortDescImage properties. Implemented column |
+| | moving and alignment. Updated column resizing implementation. |
+| 2005-12-08 | Added support for making columns smaller than their content in |
+| | Mozilla, bringing the Mozilla support up to pair with that for |
+| | IE. Also added support for specifying column width on create. |
+| 2005-12-20 | Fixed bug in setCellValue method. |
+|-----------------------------------------------------------------------------|
+| Created 2004-08-22 | All changes are in the log above. | Updated 2005-12-20 |
+\----------------------------------------------------------------------------*/
+
+var TYPE_STRING = 0;
+var TYPE_NUMBER = 1;
+var TYPE_DATE = 2;
+var TYPE_STRING_NO_CASE = 3;
+
+var SORT_ASCENDING = 0;
+var SORT_DESCENDING = 1;
+
+var ALIGN_AUTO = 0;
+var ALIGN_LEFT = 1;
+var ALIGN_CENTER = 2;
+var ALIGN_RIGHT = 3;
+
+var COL_HEAD_NONE = 0;
+var COL_HEAD_EDGE = 1;
+var COL_HEAD_OVER = 2;
+var COL_HEAD_SIZE = 3;
+var COL_HEAD_DOWN = 4;
+var COL_HEAD_MOVE = 5;
+
+
+/*
+ * oColumnList = new WebFXColumnList()
+ * Default constructor
+ */
+function WebFXColumnList() {
+
+ /* public properties */
+ this.multiple = true;
// Allow multiple selection (true or false)
+ this.colorEvenRows = true;
// Mark even rows with different color (true or false)
+ this.resizeColumns = true;
// Enable column resizing (true or false)
+ this.bodyColResize = true;
// Resize body columns duing resize operation (true or false)
+ this.moveColumns = true;
// Enable column moving (true or false)
+ this.rowSelection = true;
// Enable row selection (true or false)
+ this.columnSorting = true;
// Enable sorting (true or false)
+ this.columnAlign = true;
// Enable column text alignment (true or false)
+ this.sortAscImage = 'images/asc.png';
// Image used to indicate ascending sort order
+ this.sortDescImage = 'images/desc.png';
// Image used to indicate descending sort order
+
+ /* public read only properties */
+ this.sortCol = -1;
// Column index currently sorted by, read only
+ this.sortDescending = 0;
// Column sort direction, read only (SORT_ASCENDING or SORT_DESCENDING)
+ this.error = '';
// Error message set if an error code was returned, read only.
+ this.selectedRows = [];
// Currently selected rows, read only.
+
+ /* events */
+ this.onresize = null;
+ this.onsort = null;
+ this.onselect = null;
+
+ /* private properties */
+ this._eCont = null;
+ this._eHead = null;
+ this._eBody = null;
+ this._eHeadTable = null;
+ this._eBodyTable = null;
+ this._eHeadCols = null;
+ this._eBodyCols = null;
+
+ this._aColumnTypes = [];
+ this._aColumnAlign = [];
+ this._rows = 0;
+ this._cols = 0;
+ this._headerOper = COL_HEAD_NONE;
+ this._headerData = null;
+}
+
+
+/*
+ * iError = create(eContainer, sColumn[])
+ * Transforms the supplied container into a column list.
+ * sColumn[] - Array containing column headers
+ * sColumn[][] - Two dimensional array with column headers, widths and types
+*/
+WebFXColumnList.prototype.create = function(eContainer, aColumns) {
+ var eRow, eCell, eDiv, eImg, eTableBody, eColGroup, eCol, a, b;
+
+ for (var i = eContainer.childNodes.length - 1; i >= 0; i--) {
+ eContainer.removeChild(eContainer.childNodes[i]);
+ }
+
+ /* Create container, header and body */
+ this._eCont = eContainer;
+ this._eHead = document.createElement('div');
+ this._eBody = document.createElement('div');
+ this._eCont.className = 'webfx-columnlist';
+ this._eHead.className = 'webfx-columnlist-head';
+ this._eBody.className = 'webfx-columnlist-body';
+ this._eCont.appendChild(this._eHead);
+ this._eCont.appendChild(this._eBody);
+
+ /* Populate header */
+ this._eHeadTable = document.createElement('table');
+ this._eHeadTable.style.width = '100px';
// if a width is not set here the overflow: hidden rule will be ignored
by mozilla
+ this._eHeadTable.cellSpacing = 0;
+ this._eHeadTable.cellPadding = 0;
+ this._eHead.appendChild(this._eHeadTable);
+ eTableBody = document.createElement('tbody');
+ this._eHeadTable.appendChild(eTableBody);
+ eRow = document.createElement('tr');
+ eTableBody.appendChild(eRow);
+ for (var i = 0; i < aColumns.length; i++) {
+ eCell = document.createElement('td');
+ eRow.appendChild(eCell);
+ eImg = document.createElement('img');
+ if (typeof(aColumns[i]) == 'object') {
eCell.appendChild(document.createTextNode(aColumns[i][0])); }
+ else { eCell.appendChild(document.createTextNode(aColumns[i]));
}
+ eCell.appendChild(eImg);
+ }
+
+ /* Create main table, colgroup and col elements */
+ this._eBodyTable = document.createElement('table');
+ this._eBodyTable.cellSpacing = 0;
+ this._eBodyTable.cellPadding = 0;
+ this._eBody.appendChild(this._eBodyTable);
+ eTableBody = document.createElement('tbody');
+ this._eBodyTable.appendChild(eTableBody);
+ eColGroup = document.createElement('colgroup');
+ this._eBodyTable.appendChild(eColGroup);
+ for (var i = 0; i < aColumns.length; i++) {
+ eCol = document.createElement('col');
+ if ((typeof(aColumns[i]) == 'object') && (aColumns[i].length)
&& (aColumns[i].length > 1)) { eCol.style.width = aColumns[i][1]; }
+ else { eCol.style.width = 'auto'; }
+ eColGroup.appendChild(eCol);
+ }
+
+ /* Init sortable table */
+ this._stl = new SortableTable(this._eBodyTable);
+
+ /* Set column data types */
+ a = new Array(); b = false;
+ for (var i = 0; i < aColumns.length; i++) {
+ if ((typeof(aColumns[i]) == 'object') && (aColumns[i].length)
&& (aColumns[i].length > 2)) { a.push(aColumns[i][2]); b = true; }
+ else { a.push(TYPE_STRING); }
+ }
+
+ /* Only set explicitly if type was specified for at least one column */
+ if (b) { this.setColumnTypes(a); }
+
+ this._eHeadCols = eRow.cells;
+ this._eBodyCols = null;
+
+ this._cols = aColumns.length;
+ this._rows = 0;
+
+ this._init();
+
+ return 0;
+};
+
+
+/*
+ * iError = bind(eContainer, eHeader, eBody)
+ * Binds column list to an existing HTML structure. Use create
+ * to generate the strucutr automatically.
+*/
+WebFXColumnList.prototype.bind = function(eCont, eHead, eBody) {
+ try {
+ this._eCont = eCont;
+ this._eHead = eHead;
+ this._eBody = eBody;
+ this._eHeadTable = this._eHead.getElementsByTagName('table')[0];
+ this._eBodyTable = this._eBody.getElementsByTagName('table')[0];
+ this._eHeadCols = this._eHeadTable.tBodies[0].rows[0].cells;
+ this._eBodyCols = this._eBodyTable.tBodies[0].rows[0].cells;
+ }
+ catch(oe) {
+ this.error = 'Unable to bind to elements: ' + oe.message;
+ return 1;
+ }
+ if (this._eHeadCols.length != this._eBodyCols.length) {
+ this.error = 'Unable to bind to elements: Number of columns in
header and body does not match.';
+ return 2;
+ }
+
+ this._eHeadCols = this._eHeadTable.tBodies[0].rows[0].cells;
+ this._eBodyCols = this._eBodyTable.tBodies[0].rows[0].cells;
+
+ this._cols = this._eHeadCols.length;
+ this._rows = this._eBodyTable.tBodies[0].rows.length;
+
+ this._stl = new SortableTable(this._eBodyTable);
+
+ /* Set column class names (used for alignment in mozilla) */
+ if ((!document.all) && (this.columnAlign)) {
+ aRows = this._eBodyTable.tBodies[0].rows;
+ this._rows = aRows.length;
+ for (i = 0; i < this._rows; i++) {
+ for (j = 0; j < this._cols; j++) {
+ aRows[i].cells[j].className =
'webfx-columnlist-col-' + j;
+ } } }
+
+ this._init();
+
+ return 0;
+};
+
+
+/*
+ * void _init(iWidth, iHeight)
+ * Initializes column list, called by create and bind
+*/
+WebFXColumnList.prototype._init = function(iWidth, iHeight) {
+ if (navigator.product == 'Gecko') {
+ /*
+ * Mozilla does not allow the scroll* properties of containers
with the
+ * overflow property set to 'hidden' thus we'll have to set it
to
+ * '-moz-scrollbars-none' which is basically the same as
'hidden' in IE,
+ * the container has overflow type 'scroll' but no scrollbars
are shown.
+ */
+ for (var n = 0; n < document.styleSheets.length; n++) {
+ if
(document.styleSheets[n].href.indexOf('columnlist.css') == -1) { continue; }
+ var rules = document.styleSheets[n].cssRules;
+ for (var i = 0; i < rules.length; i++) {
+ if ((rules[i].type == CSSRule.STYLE_RULE) &&
(rules[i].selectorText == '.webfx-columnlist-head')) {
+ rules[i].style.overflow =
'-moz-scrollbars-none';
+ } } } }
+
+ /*
+ * Set tab index to allow element to be focused using keyboard, also
allows
+ * keyboard events to be captured for Mozilla.
+ */
+ this._eCont.tabIndex = '0';
+
+ this.calcSize();
+ this._assignEventHandlers();
+ if (this.colorEvenRows) { this._colorEvenRows(); }
+ if (this.columnAlign) { this._setAlignment(); }
+}
+
+
+/*
+ * void _assignEventHandlers()
+ * Assigns event handlers to the grid elements, called by bind.
+*/
+WebFXColumnList.prototype._assignEventHandlers = function() {
+ var oThis = this;
+ this._eCont.onclick = function(e) { oThis._click(e); }
+ if (this.resizeColumns) {
+ this._eCont.onmousedown = function(e) { oThis._mouseDown(e); }
+ this._eCont.onmousemove = function(e) { oThis._mouseMove(e); }
+ }
+ this._eCont.onmouseup = function(e) { oThis._mouseUp(e); }
+ this._eCont.onselectstart = function(e) { return false; }
+ this._eBody.onscroll = function() {
+ oThis._eHead.scrollLeft = oThis._eBody.scrollLeft;
+ };
+ this._eCont.onkeydown = function(e) {
+ var el = (e)?e.target:window.event.srcElement;
+ var key = (e)?e.keyCode:window.event.keyCode;
+ if (oThis._handleRowKey(key)) { return; }
+ if (window.event) { window.event.cancelBubble = true; }
+ else { e.preventDefault(); e.stopPropagation() }
+ return false;
+ };
+};
+
+
+/*
+ * void calcSize()
+ * Used to calculate the desired size of the grid and size it accordingly.
+ */
+WebFXColumnList.prototype.calcSize = function() {
+ if (this._eCont.offsetWidth >= 4) {
+
+ /* Size body */
+ var h = this._eCont.clientHeight - this._eHead.offsetHeight - 2;
+ if (h >= 0) { this._eBody.style.height = h + 'px'; }
+ this._eBody.style.width = this._eCont.offsetWidth - 4 + 'px';
+ this._eBody.style.paddingTop = this._eHead.offsetHeight + 'px';
+ this._eBodyTable.style.width = this._eBody.clientWidth + 'px';
+
+ /* Size header */
+ var bNoScrollbar = ((this._eBody.offsetWidth -
this._eBody.clientWidth) == 2);
+ this._eHeadTable.style.width = this._eHead.style.width =
this._eBody.clientWidth + ((bNoScrollbar)?2:0) + 'px';
+
+ /* Size columns */
+ if (this._eBodyCols) {
+ var length = this._eBodyCols.length;
+ for (var i = 0; i < length; i++) {
+ this._eHeadCols[i].style.width =
(this._eBodyCols[i].offsetWidth - 4) + ((bNoScrollbar) && (i == length -
1)?2:0) + 'px';
+ } } }
+
+ this._eHeadTable.style.width = 'auto';
+};
+
+
+/*
+ * iErrorCode = selectRow(iRowIndex, bMultiple)
+ * Selects the row identified by the sequence number supplied,
+ *
+ * If bMultiple is specified and multi-select is allowed the
+ * the previously selected row will not be deselected. If the
+ * specified row is already selected it will be deselected.
+ */
+WebFXColumnList.prototype.selectRow = function(iRowIndex, bMultiple) {
+ if (!this.rowSelection) { return; }
+
+ if ((iRowIndex < 0) || (iRowIndex > this._rows - 1)) {
+ this.error = 'Unable to select row, index out of range.';
+ return 1;
+ }
+ var eRows = this._eBodyTable.tBodies[0].rows;
+ var bSelect = true;
+
+ /* Normal click */
+ if ((!bMultiple) || (!this.multiple)) {
+
+ /* Deselect previously selected rows */
+ while (this.selectedRows.length) {
+ if (this.colorEvenRows) {
eRows[this.selectedRows[0]].className = (this.selectedRows[0] &
1)?'odd':'even'; }
+ else { eRows[this.selectedRows[0]].className = ''; }
+ this.selectedRows.splice(0, 1);
+ } }
+
+ /* Control + Click */
+ else {
+ for (var i = 0; i < this.selectedRows.length; i++) {
+
+ /* Deselect clicked row */
+ if (this.selectedRows[i] == iRowIndex) {
+ if (this.colorEvenRows) {
eRows[this.selectedRows[i]].className = (i & 1)?'odd':'even'; }
+ else { eRows[this.selectedRows[i]].className =
''; }
+ this.selectedRows.splice(i, 1);
+ bSelect = false;
+ break;
+ } } }
+
+ /* Select clicked row */
+ if (bSelect) {
+ this.selectedRows.push(iRowIndex);
+ eRows[iRowIndex].className = 'selected';
+ }
+
+ var a = (eRows[iRowIndex].offsetTop + this._eHead.offsetHeight) +
eRows[iRowIndex].offsetHeight + 1;
+ var b = (this._eBody.clientHeight + this._eBody.scrollTop);
+ if (a > b) {
+ this._eBody.scrollTop = (a - this._eBody.clientHeight);
+ }
+ var c = eRows[iRowIndex].offsetTop;
+ var d = this._eBody.scrollTop;
+ if (c < d) {
+ this._eBody.scrollTop = c;
+ }
+
+ /* Call onselect if defined */
+ if (this.onselect) { this.onselect(this.selectedRows); }
+
+ return 0;
+};
+
+
+/*
+ * iErrorCode = selectRange(iRowIndex[])
+ * iErrorCode = selectRange(iFromRowIndex, iToRowIndex)
+ * Selects all rows between iFromRowIndex and iToRowIndex.
+ */
+WebFXColumnList.prototype.selectRange = function(a, b) {
+ var aRowIndex;
+
+ if (!this.rowSelection) { return; }
+
+ if (typeof a == 'number') {
+ aRowIndex = new Array();
+ for (var i = a; i <= b; i++) { aRowIndex.push(i); }
+ for (var i = b; i <= a; i++) { aRowIndex.push(i); }
+ }
+ else { aRowIndex = a; }
+
+ for (var i = 0; i < aRowIndex.length; i++) {
+ if ((aRowIndex[i] < 0) || (aRowIndex[i] > this._rows - 1)) {
+ this.error = 'Unable to select rows, index out of
range.';
+ return 1;
+ } }
+
+ /* Deselect previously selected rows */
+ var eRows = this._eBodyTable.tBodies[0].rows;
+ while (this.selectedRows.length) {
+ if (this.colorEvenRows) { eRows[this.selectedRows[0]].className
= (this.selectedRows[0] & 1)?'odd':'even'; }
+ else { eRows[this.selectedRows[0]].className = ''; }
+ this.selectedRows.splice(0, 1);
+ }
+
+ /* Select all rows indicated by range */
+ var eRows = this._eBodyTable.tBodies[0].rows;
+ var bMatch;
+ for (var i = 0; i < aRowIndex.length; i++) {
+ bMatch = false;
+ for (var j = 0; j < this.selectedRows.length; j++) {
+ if (this.selectedRows[j] == aRowIndex[i]) { bMatch =
true; break; }
+ }
+ if (!bMatch) {
+ /* Select row */
+ this.selectedRows.push(aRowIndex[i]);
+ eRows[aRowIndex[i]].className = 'selected';
+ } }
+
+ /* Call onselect if defined */
+ if (this.onselect) { this.onselect(this.selectedRows); }
+
+ return 0;
+};
+
+
+/*
+ * void resize(iWidth, iHeight)
+ * Resize the grid to the given dimensions, the outer (border) size is given,
not the inner (content) size.
+ */
+WebFXColumnList.prototype.resize = function(w, h) {
+ this._eCont.style.width = w + 'px';
+ this._eCont.style.height = h + 'px';
+ this.calcSize();
+
+ /* Call onresize if defined */
+ if (this.onresize) { this.onresize(); }
+};
+
+
+/*
+ * void _colorEvenRows()
+ * Changes the color of even rows (usually to light yellow) to make it easier
to read.
+ * Also updates the id column to a sequence counter rather than the row ids.
+ */
+WebFXColumnList.prototype._colorEvenRows = function() {
+ if (this._eBodyTable.tBodies.length) {
+ var nodes = this._eBodyTable.tBodies[0].rows;
+ var len = nodes.length;
+ for (var i = 0; i < len; i++) {
+ if (nodes[i].className != 'selected') {
+ nodes[i].className = (i & 1)?'odd':'even';
+ } } }
+};
+
+
+/*
+ * iErrorCode = addRow(aRowData)
+ * Appends supplied row to the column list.
+ */
+WebFXColumnList.prototype.addRow = function(aRowData) {
+ var rc = this._addRow(aRowData);
+ if (rc) { return rc; }
+ this.calcSize();
+ return 0;
+};
+
+
+/*
+ * iErrorCode = addRows(aData)
+ * Appends supplied rows to the column list.
+ */
+WebFXColumnList.prototype.addRows = function(aData) {
+ for (var i = 0; i < aData.length; i++) {
+ var rc = this._addRow(aData[i]);
+ if (rc) { return rc; }
+ }
+ this.calcSize();
+ return 0;
+};
+
+
+/*
+ * void _colorEvenRows()
+ * Changes the color of even rows (usually to light yellow) to make it easier
to read.
+ * Also updates the id column to a sequence counter rather than the row ids.
+ */
+WebFXColumnList.prototype._colorEvenRows = function() {
+ if (this._eBodyTable.tBodies.length) {
+ var nodes = this._eBodyTable.tBodies[0].rows;
+ for (var i = 0; i < nodes.length; i++) {
+ if (nodes[i].className != 'selected') {
+ nodes[i].className = (i & 1)?'odd':'even';
+ } } }
+};
+
+
+/*
+ * iErrorCode = _addRow(aRowData)
+ */
+WebFXColumnList.prototype._addRow = function(aRowData) {
+ var eBody, eRow, eCell, i, len;
+
+ /* Validate column count */
+ if (aRowData.length != this._cols) { return 1; }
+
+ /* Construct Body Row */
+ eBody = this._eBodyTable.tBodies[0];
+ eRow = document.createElement('tr');
+ if (this.colorEvenRows) {
+ eRow.className = (this._rows & 1)?'odd':'even';
+ }
+
+ for (i = 0; i < this._cols; i++) {
+ eCell = document.createElement('td');
+ eCell.className = 'webfx-columnlist-col-' + i;
+ eCell.appendChild(document.createTextNode(aRowData[i]));
+ eRow.appendChild(eCell);
+ }
+ eBody.appendChild(eRow);
+
+ /* Update row counter */
+ this._rows++;
+
+ if (this._eBodyCols == null) {
+ this._eBodyCols = this._eBodyTable.tBodies[0].rows[0].cells;
+ }
+
+ return 0;
+};
+
+
+/*
+ * iErrorCode = removeRow(iRowIndex)
+ * Appends supplied row to the grid.
+ */
+WebFXColumnList.prototype.removeRow = function(iRowIndex) {
+ /* Remove row */
+ var rc = this._removeRow(iRowIndex);
+ if (rc) { return rc; }
+
+ /* Update row counter and select previous row, if any */
+ this._rows--;
+ this.selectRow((iRowIndex > 1)?iRowIndex-1:0);
+
+ /* Recolor rows, if needed */
+ if (this.colorEvenRows) { this._colorEvenRows(); }
+ this.calcSize();
+
+ /* Call onselect if defined */
+ if (this.onselect) { this.onselect(this.selectedRows); }
+
+ return 0;
+};
+
+
+/*
+ * iErrorCode = removeRange(iRowIndex[])
+ * iErrorCode = removeRange(iFirstRowIndex, iLastRowIndex)
+ * Appends supplied row to the grid.
+ */
+WebFXColumnList.prototype.removeRange = function(a, b) {
+ var aRowIndex = new Array();
+ if (typeof a == 'number') {
+ for (var i = a; i <= b; i++) { aRowIndex.push(i); }
+ }
+ else {
+ for (var i = 0; i < a.length; i++) {
+ aRowIndex.push(a[i]);
+ }
+ aRowIndex.sort(compareNumericAsc);
+ }
+
+ while ((i = aRowIndex.pop()) >= 0) {
+ var rc = this._removeRow(i);
+ this._rows--;
+ }
+
+ /* Recolor rows, if needed */
+ if (this.colorEvenRows) { this._colorEvenRows(); }
+ this.calcSize();
+
+ /* Call onselect if defined */
+ if (this.onselect) { this.onselect(this.selectedRows); }
+
+ return 0;
+};
+
+
+/*
+ * iErrorCode = clear()
+ * Removes all rows from the column list.
+ */
+WebFXColumnList.prototype.clear = function() {
+ return this.removeRange(0, this._rows - 1);
+}
+
+/*
+ * iErrorCode = _removeRow(iRowIndex)
+ */
+WebFXColumnList.prototype._removeRow = function(iRowIndex) {
+ if ((iRowIndex < 0) || (iRowIndex > this._rows - 1)) {
+ this.error = 'Unable to remove row, row index out of range.';
+ return 1;
+ }
+
+ /* Remove from selected */
+ for (var i = this.selectedRows.length - 1; i >= 0; i--) {
+ if (this.selectedRows[i] == iRowIndex) {
+ this.selectedRows.splice(i, 1);
+ } }
+
+
this._eBodyTable.tBodies[0].removeChild(this._eBodyTable.tBodies[0].rows[iRowIndex]);
+ return 0;
+};
+
+
+/*
+ * iRowIndex getSelectedRow()
+ * Returns the index of the selected row or -1 if no row is selected.
+ */
+WebFXColumnList.prototype.getSelectedRow = function() {
+ return
(this.selectedRows.length)?this.selectedRows[this.selectedRows.length-1]:-1;
+};
+
+
+/*
+ * iRowIndex[] getSelectedRange()
+ * Returns an array with the row index of all selecteds row or null if no row
is selected.
+ */
+WebFXColumnList.prototype.getSelectedRange = function() {
+ return (this.selectedRows.length)?this.selectedRows:-1;
+};
+
+
+/*
+ * iRows getRowCount()
+ * Returns the nummer of rows.
+ */
+WebFXColumnList.prototype.getRowCount = function() {
+ return this._rows;
+};
+
+
+/*
+ * iRows getColumnCount()
+ * Returns the nummer of columns.
+ */
+WebFXColumnList.prototype.getColumnCount = function() {
+ return this._cols;
+};
+
+
+/*
+ * sValue = getCellValue(iRowIndex, iColumnIndex, bHTML)
+ * Returns the content of the specified cell.
+ */
+WebFXColumnList.prototype.getCellValue = function(iRowIndex, iColIndex) {
+ var el;
+
+ if ((iRowIndex < 0) || (iRowIndex > this._rows - 1)) {
+ this.error = 'Unable to get cell value , row index out of
range.';
+ return null;
+ }
+ if ((iColIndex < 0) || (iColIndex > this._cols - 1)) {
+ this.error = 'Unable to get cell value , row index out of
range.';
+ return null;
+ }
+
+ el = this._eBodyTable.tBodies[0].rows[iRowIndex].cells[iColIndex];
+
+ return (bHTML)?el.innerHTML:getInnerText(el);
+};
+
+
+/*
+ * iError = setCellValue(iRowIndex, iColumnIndex, sValue, bHTML)
+ * Sets the content of the specified cell.
+ */
+WebFXColumnList.prototype.setCellValue = function(iRowIndex, iColIndex,
sValue, bHTML) {
+ var el;
+
+ if ((iRowIndex < 0) || (iRowIndex > this._rows - 1)) {
+ this.error = 'Unable to set cell value , row index out of
range.';
+ return 1;
+ }
+ if ((iColIndex < 0) || (iColIndex > this._cols - 1)) {
+ this.error = 'Unable to set cell value , row index out of
range.';
+ return 2;
+ }
+
+ el = this._eBodyTable.tBodies[0].rows[iRowIndex].cells[iColIndex];
+ if (bHTML) { el.innerHTML = sValue; }
+ else {
+ while (el.firstChild != el.lastChild) {
el.removeChild(el.lastChild); }
+ if (el.firstChild) { el.firstChild.nodeValue = sValue; }
+ else { el.appendChild(document.createTextNode(sValue)); }
+ }
+
+ this.calcSize();
+
+ return 0;
+};
+
+
+/*
+ * void setSortTypes(sSortType[]) {
+ * Sets the column data types for sorting.
+ * Valid options: TYPE_STRING, TYPE_NUMBER, TYPE_DATE, TYPE_STRING_NO_CASE or
+ * custom string value that will be passed to sortable table. Can be registered
+ * with the SortableTable.prototype.addSortType method.
+ */
+WebFXColumnList.prototype.setSortTypes = function(aSortTypes) {
+ var i, a = new Array();
+
+ this._aColumnTypes = aSortTypes;
+ for (i = 0; i < this._cols; i++) {
+ switch (aSortTypes[i]) {
+ case TYPE_STRING: a.push('String');
break;
+ case TYPE_NUMBER: a.push('Number');
break;
+ case TYPE_DATE: a.push('Date');
break;
+ case TYPE_STRING_NO_CASE:
a.push('CaseInsensitiveString'); break;
+ default: a.push('String');
+ };
+ }
+ this._stl.setSortTypes(a);
+};
+
+
+/*
+ * void setColumnTypes(aColumnTypes[]) {
+ * Sets the column data types for sorting, also affects the alignment for
columns
+ * with alignment set to ALIGN_AUTO (which is the default), strings and dates
+ * are left aligned, numbers right aligned.
+ * Valid options: TYPE_STRING, TYPE_NUMBER, TYPE_DATE, TYPE_STRING_NO_CASE or
+ * custom string value that will be passed to sortable table. Can be registered
+ * with the SortableTable.prototype.addSortType method.
+ */
+WebFXColumnList.prototype.setColumnTypes = function(aColumnTypes) {
+ this.setSortTypes(aColumnTypes);
+};
+
+
+/*
+ * void setColumnAlignment(iAlignment[])
+ * Sets column text alignment, ALIGN_AUTO, ALIGN_LEFT, ALIGN_CENTER or
ALIGN_RIGHT.
+ */
+WebFXColumnList.prototype.setColumnAlignment = function(aAlignment) {
+ _aColumnAlign = aAlignment;
+};
+
+
+/*
+ * void sort(iColumnIndex, [bDescending])
+ * Sorts the grid by the specified column (zero based index) and, optionally,
in the specified direction.
+ */
+WebFXColumnList.prototype.sort = function(iCol, bDesc) {
+ if (!this.columnSorting) { return; }
+
+ /* Hide arrow from header for column currently sorted by */
+ if (this.sortCol != -1) {
+ var eImg =
this._eHeadTable.tBodies[0].rows[0].cells[this.sortCol].getElementsByTagName('img')[0];
+ eImg.style.display = 'none';
+ }
+
+ /* Determine sort direction */
+ if (bDesc == null) {
+ bDesc = false;
+ if ((!this.sortDescending) && (iCol == this.sortCol)) { bDesc =
true; }
+ }
+
+ /* Indicate sorting using arrow in header */
+ var eImg =
this._eHeadTable.tBodies[0].rows[0].cells[iCol].getElementsByTagName('img')[0];
+ eImg.src = (bDesc)?this.sortDescImage:this.sortAscImage;
+ eImg.style.display = 'inline';
+
+ /* Perform sort operation */
+ this._stl.sort(iCol, bDesc);
+ this.sortCol = iCol;
+ this.sortDescending = bDesc;
+
+ /* Update row coloring */
+ if (this.colorEvenRows) { this._colorEvenRows(); }
+
+ /* Update selection */
+ var nodes = this._eBodyTable.tBodies[0].rows;
+ var len = nodes.length;
+ var a = new Array();
+ for (var i = 0; i < len; i++) {
+ if (nodes[i].className == 'selected') { a.push(i); }
+ }
+ this.selectRange(a);
+
+ /* Call onsort if defined */
+ if (this.onsort) { this.onsort(this.sortCol, this.sortDescending); }
+
+};
+
+
+/*
+ * void _handleRowKey(iKeyCode)
+ * Key handler for events on row level.
+ */
+WebFXColumnList.prototype._handleRowKey = function(iKeyCode, bCtrl, bShift) {
+ var iActiveRow = -1;
+ if (this.selectedRows.length != 0) { iActiveRow =
this.selectedRows[this.selectedRows.length-1]; }
+ if ((!bCtrl) && (!bShift)) {
+ if (iKeyCode == 38) {
// Up
+ if (iActiveRow > 0) { this.selectRow(iActiveRow - 1); }
+ }
+ else if (iKeyCode == 40) {
// Down
+ if (iActiveRow < this._rows - 1) {
this.selectRow(iActiveRow + 1); }
+ }
+ else if (iKeyCode == 33) {
// Page Up
+ if (iActiveRow > 10) { this.selectRow(iActiveRow - 10);
}
+ else { this.selectRow(0); }
+ }
+ else if (iKeyCode == 34) {
// Page Down
+ if (iActiveRow < this._rows - 10) {
this.selectRow(iActiveRow + 10); }
+ else { this.selectRow(this._rows - 1); }
+ }
+ else if (iKeyCode == 36) { this.selectRow(0); }
// Home
+ else if (iKeyCode == 35) { this.selectRow(this._rows - 1); }
// End
+ else { return true; }
+ return false;
+ }
+};
+
+
+/*
+ * Event Handlers
+ */
+WebFXColumnList.prototype._mouseMove = function(e) {
+ var el, x, w, tw, ox, rx, i, l;
+
+ el = (e)?e.target:window.event.srcElement;
+ x = (e)?e.pageX:window.event.x + this._eBody.scrollLeft;
+
+ /*
+ * Column move operation started, create elements required to indicate
moving
+ * and set operation flag to COL_HEAD_MOVE.
+ */
+ if (this._headerOper == COL_HEAD_DOWN) {
+ this._headerOper = COL_HEAD_MOVE;
+ this._eCont.style.cursor = 'move';
+
+ w = this._headerData[2] + (x - this._headerData[1]);
+
+ if (!this._moveEl) {
+ this._moveEl = document.createElement('div');
+
this._moveEl.appendChild(document.createTextNode(this._headerData[0].firstChild.nodeValue));
+ this._moveEl.className = 'webfx-columnlist-move-header';
+ this._eHead.appendChild(this._moveEl);
+
+ if (this.columnAlign) {
+ switch
(this._aColumnAlign[this._headerData[0].cellIndex]) {
+ case ALIGN_LEFT:
this._moveEl.style.textAlign = 'left'; break;
+ case ALIGN_CENTER:
this._moveEl.style.textAlign = 'center'; break;
+ case ALIGN_RIGHT:
this._moveEl.style.textAlign = 'right'; break;
+ case ALIGN_AUTO:
+ default:
+
switch(this._aColumnTypes[this._headerData[0].cellIndex]) {
+ case TYPE_NUMBER:
this._moveEl.style.textAlign = 'right'; break;
+ default:
this._moveEl.style.textAlign = 'left';
+ };
+ };
+ }
+
+
+ }
+ else { this._moveEl.firstChild.nodeValue =
this._headerData[0].firstChild.nodeValue; }
+ this._moveEl.style.width = this._headerData[0].clientWidth +
'px';
+
+ if (!this._moveSepEl) {
+ this._moveSepEl = document.createElement('div');
+ this._moveSepEl.className =
'webfx-columnlist-separator-header';
+ this._eHead.appendChild(this._moveSepEl);
+ } }
+
+ /*
+ * Column move operation, determine position of column and move place
holder
+ * to that position. Also indicate in between which columns it will be
placed.
+ */
+ if (this._headerOper == COL_HEAD_MOVE) {
+ ox = this._headerData[1] + (x - this._headerData[2]);
+ this._moveEl.style.left = ox + 'px';
+
+ ox = 0, rx = x - this._headerData[3];
+ for (i = 0; i < this._cols; i++) {
+ ox += this._eHeadCols[i].offsetWidth;
+ if (ox >= rx) { break; }
+ }
+ if (i == this._cols) { this._moveSepEl.style.left =
(this._eHeadCols[this._cols-1].offsetLeft +
this._eHeadCols[this._cols-1].offsetWidth - 1) + 'px'; }
+ else { this._moveSepEl.style.left =
this._eHeadCols[i].offsetLeft + 'px'; }
+
+ this._headerData[4] = i;
+ }
+
+ /*
+ * Column resize operation, determine and set new size based on the
original
+ * size and the difference between the current mouse position and the
one that
+ * was recorded once the resize operation was started.
+ */
+ else if (this._headerOper == COL_HEAD_SIZE) {
+ w = this._headerData[1] + x - this._headerData[2];
+ tw = ((w - this._headerData[1]) + this._headerData[3]) + 1;
+ this._eHeadTable.style.width = tw + 'px';
+ if (w > 5) {
+ this._headerData[0].style.width = w + 'px';
+ if (this.bodyColResize) {
+ this._eBodyTable.style.width = tw + 'px';
+
this._eBodyTable.getElementsByTagName('colgroup')[0].getElementsByTagName('col')[this._headerData[0].cellIndex].style.width
= w + 'px';
+ } } }
+
+ else { this._checkHeaderOperation(el, x); }
+
+};
+
+
+WebFXColumnList.prototype._mouseDown = function(e) {
+ var el = (e)?e.target:window.event.srcElement;
+ var x = (e)?e.pageX:window.event.x + this._eBody.scrollLeft;
+
+ if ((el.tagName == 'TD') &&
(el.parentNode.parentNode.parentNode.parentNode.className ==
'webfx-columnlist-head')) {
+ this._checkHeaderOperation(el, x);
+
+ if (this._headerOper == COL_HEAD_EDGE) {
+ if (this.bodyColResize) {
this._sizeBodyAccordingToHeader(); }
+ this._headerOper = COL_HEAD_SIZE;
+ }
+ else if (this._headerOper == COL_HEAD_OVER) {
+ this._headerOper = COL_HEAD_DOWN;
+ this._headerData[0].className =
'webfx-columnlist-active-header';
+ } }
+};
+
+
+WebFXColumnList.prototype._mouseUp = function(e) {
+ var el = (e)?e.target:window.event.srcElement;
+ var x = (e)?e.pageX:window.event.x + this._eBody.scrollLeft;
+
+ if (this._headerOper == COL_HEAD_SIZE) {
+
+ }
+ else if (this._headerOper == COL_HEAD_MOVE) {
+ if (this._moveEl) { this._eHead.removeChild(this._moveEl);
this._moveEl = null; }
+ if (this._moveSepEl) {
this._eHead.removeChild(this._moveSepEl); this._moveSepEl = null; }
+ this._moveColumn(this._headerData[0].cellIndex,
this._headerData[4]);
+ }
+ else if (this._headerOper == COL_HEAD_DOWN) {
+ this.sort(el.cellIndex);
+ }
+
+ if (this._headerOper != COL_HEAD_NONE) {
+ this._headerOper = COL_HEAD_NONE;
+ this._eCont.style.cursor = 'default';
+ this._headerData[0].className = '';
+ this._headerData = null;
+ this._sizeBodyAccordingToHeader();
+ }
+
+};
+
+
+WebFXColumnList.prototype._click = function(e) {
+ var el = (e)?e.target:window.event.srcElement;
+ if (el.tagName == 'IMG') { el = el.parentNode; }
+ if (el.tagName == 'DIV') { el = el.parentNode; }
+ if ((el.tagName == 'TD') &&
(el.parentNode.parentNode.parentNode.parentNode.className ==
'webfx-columnlist-body')) {
+ if (((e)?e.shiftKey:window.event.shiftKey) &&
(this.selectedRows.length) && (this.multiple)) {
+
this.selectRange(this.selectedRows[this.selectedRows.length-1],
el.parentNode.rowIndex);
+ }
+ else { this.selectRow(el.parentNode.rowIndex,
(e)?e.ctrlKey:window.event.ctrlKey); }
+} };
+
+
+/*
+ * Event handler helpers
+ */
+
+WebFXColumnList.prototype._checkHeaderOperation = function(el, x) {
+ var prev, next, left, right, l, r;
+
+ /*
+ * Checks if the mouse cursor is near the edge of a header
+ * cell, in that case the cursor is set to 'e-resize' and
+ * the operation is set to COL_HEAD_EDGE, if it's over the
+ * header but not near the edge it's set to COL_HEAD_OVER
+ * and finnaly if it's not over the header it's set to
+ * COL_HEAD_NONE. The operation value is used to trigger
+ * column resize, move and sort commands.
+ */
+
+ if ((el.tagName == 'TD') &&
(el.parentNode.parentNode.parentNode.parentNode.className ==
'webfx-columnlist-head')) {
+ if (el.tagName == 'IMG') { el = el.parentNode; }
+
+ prev = el.previousSibling;
+ next = el.nextSibling;
+ left = getLeftPos(el);
+ right = left + el.offsetWidth;
+ l = (x - 5) - left;
+ r = right - x;
+
+ if ((l < 5) && (prev)) {
+ this._eCont.style.cursor = 'e-resize';
+ this._headerOper = COL_HEAD_EDGE;
+ this._headerData = [prev, prev.offsetWidth - 5,
x, this._eHeadTable.offsetWidth];
+ }
+ else if (r < 5) {
+ this._eCont.style.cursor = 'e-resize';
+ this._headerOper = COL_HEAD_EDGE;
+ this._headerData = [el, el.offsetWidth - 5, x,
this._eHeadTable.offsetWidth];
+ }
+ else {
+ this._eCont.style.cursor = 'default';
+ this._headerOper = COL_HEAD_OVER;
+ this._headerData = [el, el.offsetLeft, x,
getLeftPos(this._eHead), el.cellIndex];
+ } }
+ else {
+ this._eCont.style.cursor = 'default';
+ this._headerOper = COL_HEAD_NONE;
+ this._headerData = null;
+} };
+
+
+WebFXColumnList.prototype._sizeBodyAccordingToHeader = function() {
+ var aCols =
this._eBodyTable.getElementsByTagName('colgroup')[0].getElementsByTagName('col');
+ var length = aCols.length;
+ var bNoScrollbar = ((this._eBody.offsetWidth - this._eBody.clientWidth)
== 2);
+ this._eBodyTable.style.width = this._eHeadTable.offsetWidth -
((bNoScrollbar)?2:0) + 'px';
+ for (var i = 0; i < length; i++) {
+ aCols[i].style.width = (this._eHeadCols[i].offsetWidth -
((document.all)?2:0)) - (((bNoScrollbar && i) == (length - 1))?2:0) + 'px';
+} };
+
+
+/*
+ * void moveColumn(iColumnIndex, iNewColumnIndex)
+ * Moves column from givin column index to new index.
+ */
+WebFXColumnList.prototype._moveColumn = function(iCol, iNew) {
+ var i, oParent, oCol, oBefore, aRows, a;
+
+ if (iCol == iNew) { return; }
+
+ /* Move header */
+ oCol = this._eHeadCols[iCol];
+ oParent = oCol.parentNode;
+ if (iNew == this._cols) {
+ oParent.removeChild(oCol);
+ oParent.appendChild(oCol);
+ }
+ else {
+ oBefore = this._eHeadCols[iNew];
+ oParent.removeChild(oCol);
+ oParent.insertBefore(oCol, oBefore);
+ }
+
+ /* Move cols */
+ oCol =
this._eBodyTable.getElementsByTagName('colgroup')[0].getElementsByTagName('col')[iCol];
+ oParent = oCol.parentNode;
+ if (iNew == this._cols) {
+ oParent.removeChild(oCol);
+ oParent.appendChild(oCol);
+ }
+ else {
+ oBefore =
this._eBodyTable.getElementsByTagName('colgroup')[0].getElementsByTagName('col')[iNew];
+ oParent.removeChild(oCol);
+ oParent.insertBefore(oCol, oBefore);
+ }
+
+ /* Move cells */
+ aRows = this._eBodyTable.tBodies[0].rows;
+ this._rows = aRows.length;
+ for (i = 0; i < this._rows; i++) {
+ oCol = aRows[i].cells[iCol];
+ oParent = aRows[i];
+
+ if (iNew == this._cols) {
+ oParent.removeChild(oCol);
+ oParent.appendChild(oCol);
+ }
+ else {
+ oBefore = aRows[i].cells[iNew];
+ oParent.removeChild(oCol);
+ oParent.insertBefore(oCol, oBefore);
+ } }
+
+ /* Reorganize column type and sort data */
+ a = new Array();
+ oCol = this._aColumnTypes[iCol];
+ for (i = 0; i < this._aColumnTypes.length; i++) {
+ if (i == iCol) { continue; }
+ if (i == iNew) { a.push(oCol); }
+ a.push(this._aColumnTypes[i]);
+ }
+ if (iNew == this._aColumnTypes.length - 1) { a.push(oCol); }
+ this._aColumnTypes = a;
+ this.setSortTypes(a);
+
+ /* If sorted by column, update sortCol property */
+ if (iCol == this.sortCol) { this.sortCol = iNew; }
+};
+
+
+/*
+ * void _setAlignment()
+ * Sets column alignment
+ */
+WebFXColumnList.prototype._setAlignment = function() {
+ var i, aRows, aAlign, j;
+
+ aAlign = new Array();
+ for (i = 0; i < this._cols; i++) {
+ switch (this._aColumnAlign[i]) {
+ case ALIGN_LEFT: align = 'left'; break;
+ case ALIGN_CENTER: align = 'center'; break;
+ case ALIGN_RIGHT: align = 'right'; break;
+ case ALIGN_AUTO:
+ default:
+ switch(this._aColumnTypes[i]) {
+ case TYPE_NUMBER: align = 'right';
break;
+ default: align = 'left';
+ };
+ };
+ aAlign.push(align);
+ }
+
+ /* Set alignment for headers */
+ for (i = 0; i < this._cols; i++) {
+ this._eHeadCols[i].style.textAlign = aAlign[i];
+ }
+
+ /*
+ * Set alignment for rows.
+ * IE supports the align property on cols in colgorups. As thats the,
by far,
+ * fastest way of setting it, that what we'll use.
+ */
+ var aCols =
this._eBodyTable.getElementsByTagName('colgroup')[0].getElementsByTagName('col');
+ var length = aCols.length;
+ if (document.all) {
+ for (var i = 0; i < length; i++) {
+ aCols[i].align = aAlign[i];
+ } }
+
+ /*
+ * Mozilla does not support the align property, so we'll update the
style
+ * sheet rule for each column instead. Still a lot faster than setting
the
+ * style text-alignment property for all cells.
+ */
+ else {
+ var ss = null, rules = null;
+ for (var n = 0; n < document.styleSheets.length; n++) {
+ if
(document.styleSheets[n].href.indexOf('columnlist.css') == -1) { continue; }
+ ss = document.styleSheets[n];
+ rules = ss.cssRules;
+ }
+ if (!rules) { return; }
+
+ if (!this._aColRules) { this._aColRules = new Array(); }
+ for (var j = 0; j < length; j++) {
+ if (!this._aColRules[j]) {
+ for (var i = 0; i < rules.length; i++) {
+ if ((rules[i].type ==
CSSRule.STYLE_RULE) && (rules[i].selectorText == '.webfx-columnlist-col-' + j))
{
+ this._aColRules[j] = rules[i];
+ break;
+ } } }
+ if (this._aColRules[j]) {
+ this._aColRules[j].style.textAlign = aAlign[j];
+ }
+ else { this._aColRules[j] =
ss.insertRule('.webfx-columnlist-col-' + j + ' { text-align: ' + aAlign[j] +
'};', 0); }
+} } };
+
+
+/*
+ * Helper functions
+ */
+
+function getLeftPos(_el) {
+ var x = 0;
+ for (var el = _el; el; el = el.offsetParent) {
+ x += el.offsetLeft;
+ }
+ return x;
+}
+
+
+function compareNumericAsc(n1, n2) {
+ if (Number(n1) < Number(n2)) { return -1; }
+ if (Number(n1) > Number(n2)) { return 1; }
+ return 0;
+}
+
+
+function getInnerText(el) {
+ if (document.all) { return el.innerText; }
+ var str = '';
+ var cs = el.childNodes;
+ var l = cs.length;
+ for (var i = 0; i < l; i++) {
+ switch (cs[i].nodeType) {
+ case 1: //ELEMENT_NODE
+ str += getInnerText(cs[i]);
+ break;
+ case 3: //TEXT_NODE
+ str += cs[i].nodeValue;
+ break;
+ } }
+ return str;
+}
Index: sitemgr/js/columnlist/original/includes/sortabletable.js
diff -u /dev/null
sitemgr/js/columnlist/original/includes/sortabletable.js:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/includes/sortabletable.js Mon Mar 27
13:13:24 2006
@@ -0,0 +1,455 @@
+
+/*----------------------------------------------------------------------------\
+| Sortable Table 1.12 |
+|-----------------------------------------------------------------------------|
+| Created by Erik Arvidsson |
+| (http://webfx.eae.net/contact.html#erik) |
+| For WebFX (http://webfx.eae.net/) |
+|-----------------------------------------------------------------------------|
+| A DOM 1 based script that allows an ordinary HTML table to be sortable. |
+|-----------------------------------------------------------------------------|
+| Copyright (c) 1998 - 2004 Erik Arvidsson |
+|-----------------------------------------------------------------------------|
+| This software is provided "as is", without warranty of any kind, express or |
+| implied, including but not limited to the warranties of merchantability, |
+| fitness for a particular purpose and noninfringement. In no event shall the |
+| authors or copyright holders be liable for any claim, damages or other |
+| liability, whether in an action of contract, tort or otherwise, arising |
+| from, out of or in connection with the software or the use or other |
+| dealings in the software. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| This software is available under the three different licenses mentioned |
+| below. To use this software you must chose, and qualify, for one of those. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| The WebFX Non-Commercial License http://webfx.eae.net/license.html |
+| Permits anyone the right to use the software in a non-commercial context |
+| free of charge. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| The WebFX Commercial license http://webfx.eae.net/commercial.html |
+| Permits the license holder the right to use the software in a commercial |
+| context. Such license must be specifically obtained, however it's valid for |
+| any number of implementations of the licensed software. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt |
+| Permits anyone the right to use and modify the software without limitations |
+| as long as proper credits are given and the original and modified source |
+| code are included. Requires that the final product, software derivate from |
+| the original source or any software utilizing a GPL component, such as |
+| this, is also licensed under the GPL license. |
+|-----------------------------------------------------------------------------|
+| 2003-01-10 | First version |
+| 2003-01-19 | Minor changes to the date parsing |
+| 2003-01-28 | JScript 5.0 fixes (no support for 'in' operator) |
+| 2003-02-01 | Sloppy typo like error fixed in getInnerText |
+| 2003-07-04 | Added workaround for IE cellIndex bug. |
+| 2003-11-09 | The bDescending argument to sort was not correctly working |
+| | Using onclick DOM0 event if no support for addEventListener |
+| | or attachEvent |
+| 2004-01-13 | Adding addSortType and removeSortType which makes it a lot |
+| | easier to add new, custom sort types. |
+| 2004-01-27 | Switch to use descending = false as the default sort order. |
+| | Change defaultDescending to suit your needs. |
+| 2004-03-14 | Improved sort type None look and feel a bit |
+| 2004-08-26 | Made the handling of tBody and tHead more flexible. Now you |
+| | can use another tHead or no tHead, and you can chose some |
+| | other tBody. |
+|-----------------------------------------------------------------------------|
+| Created 2003-01-10 | All changes are in the log above. | Updated 2004-08-26 |
+\----------------------------------------------------------------------------*/
+
+
+function SortableTable(oTable, oSortTypes) {
+
+ this._sortTypes = oSortTypes || [];
+
+ this.sortColumn = null;
+ this.descending = null;
+
+ var oThis = this;
+ this._headerOnclick = function (e) {
+ oThis.headerOnclick(e);
+ };
+
+ if (oTable) {
+ this.setTable( oTable );
+ this.document = oTable.ownerDocument || oTable.document;
+ }
+ else {
+ this.document = document;
+ }
+
+
+ // only IE needs this
+ var win = this.document.defaultView || this.document.parentWindow;
+ this._onunload = function () {
+ oThis.destroy();
+ };
+ if (win && typeof win.attachEvent != "undefined") {
+ win.attachEvent("onunload", this._onunload);
+ }
+}
+
+SortableTable.gecko = navigator.product == "Gecko";
+SortableTable.msie = /msie/i.test(navigator.userAgent);
+// Mozilla is faster when doing the DOM manipulations on
+// an orphaned element. MSIE is not
+SortableTable.removeBeforeSort = SortableTable.gecko;
+
+SortableTable.prototype.onsort = function () {};
+
+// default sort order. true -> descending, false -> ascending
+SortableTable.prototype.defaultDescending = false;
+
+// shared between all instances. This is intentional to allow external files
+// to modify the prototype
+SortableTable.prototype._sortTypeInfo = {};
+
+SortableTable.prototype.setTable = function (oTable) {
+ if ( this.tHead )
+ this.uninitHeader();
+ this.element = oTable;
+ this.setTHead( oTable.tHead );
+ this.setTBody( oTable.tBodies[0] );
+};
+
+SortableTable.prototype.setTHead = function (oTHead) {
+ if (this.tHead && this.tHead != oTHead )
+ this.uninitHeader();
+ this.tHead = oTHead;
+ this.initHeader( this._sortTypes );
+};
+
+SortableTable.prototype.setTBody = function (oTBody) {
+ this.tBody = oTBody;
+};
+
+SortableTable.prototype.setSortTypes = function ( oSortTypes ) {
+ if ( this.tHead )
+ this.uninitHeader();
+ this._sortTypes = oSortTypes || [];
+ if ( this.tHead )
+ this.initHeader( this._sortTypes );
+};
+
+// adds arrow containers and events
+// also binds sort type to the header cells so that reordering columns does
+// not break the sort types
+SortableTable.prototype.initHeader = function (oSortTypes) {
+ if (!this.tHead) return;
+ var cells = this.tHead.rows[0].cells;
+ var doc = this.tHead.ownerDocument || this.tHead.document;
+ this._sortTypes = oSortTypes || [];
+ var l = cells.length;
+ var img, c;
+ for (var i = 0; i < l; i++) {
+ c = cells[i];
+ if (this._sortTypes[i] != null && this._sortTypes[i] != "None")
{
+ img = doc.createElement("IMG");
+ img.src = "images/blank.png";
+ c.appendChild(img);
+ if (this._sortTypes[i] != null)
+ c._sortType = this._sortTypes[i];
+ if (typeof c.addEventListener != "undefined")
+ c.addEventListener("click",
this._headerOnclick, false);
+ else if (typeof c.attachEvent != "undefined")
+ c.attachEvent("onclick", this._headerOnclick);
+ else
+ c.onclick = this._headerOnclick;
+ }
+ else
+ {
+ c.setAttribute( "_sortType", oSortTypes[i] );
+ c._sortType = "None";
+ }
+ }
+ this.updateHeaderArrows();
+};
+
+// remove arrows and events
+SortableTable.prototype.uninitHeader = function () {
+ if (!this.tHead) return;
+ var cells = this.tHead.rows[0].cells;
+ var l = cells.length;
+ var c;
+ for (var i = 0; i < l; i++) {
+ c = cells[i];
+ if (c._sortType != null && c._sortType != "None") {
+ c.removeChild(c.lastChild);
+ if (typeof c.removeEventListener != "undefined")
+ c.removeEventListener("click",
this._headerOnclick, false);
+ else if (typeof c.detachEvent != "undefined")
+ c.detachEvent("onclick", this._headerOnclick);
+ c._sortType = null;
+ c.removeAttribute( "_sortType" );
+ }
+ }
+};
+
+SortableTable.prototype.updateHeaderArrows = function () {
+ if (!this.tHead) return;
+ var cells = this.tHead.rows[0].cells;
+ var l = cells.length;
+ var img;
+ for (var i = 0; i < l; i++) {
+ if (cells[i]._sortType != null && cells[i]._sortType != "None")
{
+ img = cells[i].lastChild;
+ if (i == this.sortColumn)
+ img.className = "sort-arrow " +
(this.descending ? "descending" : "ascending");
+ else
+ img.className = "sort-arrow";
+ }
+ }
+};
+
+SortableTable.prototype.headerOnclick = function (e) {
+ // find TD element
+ var el = e.target || e.srcElement;
+ while (el.tagName != "TD")
+ el = el.parentNode;
+
+ this.sort(SortableTable.msie ? SortableTable.getCellIndex(el) :
el.cellIndex);
+};
+
+// IE returns wrong cellIndex when columns are hidden
+SortableTable.getCellIndex = function (oTd) {
+ var cells = oTd.parentNode.childNodes
+ var l = cells.length;
+ var i;
+ for (i = 0; cells[i] != oTd && i < l; i++)
+ ;
+ return i;
+};
+
+SortableTable.prototype.getSortType = function (nColumn) {
+ return this._sortTypes[nColumn] || "String";
+};
+
+// only nColumn is required
+// if bDescending is left out the old value is taken into account
+// if sSortType is left out the sort type is found from the sortTypes array
+
+SortableTable.prototype.sort = function (nColumn, bDescending, sSortType) {
+ if (!this.tBody) return;
+ if (sSortType == null)
+ sSortType = this.getSortType(nColumn);
+
+ // exit if None
+ if (sSortType == "None")
+ return;
+
+ if (bDescending == null) {
+ if (this.sortColumn != nColumn)
+ this.descending = this.defaultDescending;
+ else
+ this.descending = !this.descending;
+ }
+ else
+ this.descending = bDescending;
+
+ this.sortColumn = nColumn;
+
+ if (typeof this.onbeforesort == "function")
+ this.onbeforesort();
+
+ var f = this.getSortFunction(sSortType, nColumn);
+ var a = this.getCache(sSortType, nColumn);
+ var tBody = this.tBody;
+
+ a.sort(f);
+
+ if (this.descending)
+ a.reverse();
+
+ if (SortableTable.removeBeforeSort) {
+ // remove from doc
+ var nextSibling = tBody.nextSibling;
+ var p = tBody.parentNode;
+ p.removeChild(tBody);
+ }
+
+ // insert in the new order
+ var l = a.length;
+ for (var i = 0; i < l; i++)
+ tBody.appendChild(a[i].element);
+
+ if (SortableTable.removeBeforeSort) {
+ // insert into doc
+ p.insertBefore(tBody, nextSibling);
+ }
+
+ this.updateHeaderArrows();
+
+ this.destroyCache(a);
+
+ if (typeof this.onsort == "function")
+ this.onsort();
+};
+
+SortableTable.prototype.asyncSort = function (nColumn, bDescending, sSortType)
{
+ var oThis = this;
+ this._asyncsort = function () {
+ oThis.sort(nColumn, bDescending, sSortType);
+ };
+ window.setTimeout(this._asyncsort, 1);
+};
+
+SortableTable.prototype.getCache = function (sType, nColumn) {
+ if (!this.tBody) return [];
+ var rows = this.tBody.rows;
+ var l = rows.length;
+ var a = new Array(l);
+ var r;
+ for (var i = 0; i < l; i++) {
+ r = rows[i];
+ a[i] = {
+ value: this.getRowValue(r, sType, nColumn),
+ element: r
+ };
+ };
+ return a;
+};
+
+SortableTable.prototype.destroyCache = function (oArray) {
+ var l = oArray.length;
+ for (var i = 0; i < l; i++) {
+ oArray[i].value = null;
+ oArray[i].element = null;
+ oArray[i] = null;
+ }
+};
+
+SortableTable.prototype.getRowValue = function (oRow, sType, nColumn) {
+ // if we have defined a custom getRowValue use that
+ if (this._sortTypeInfo[sType] && this._sortTypeInfo[sType].getRowValue)
+ return this._sortTypeInfo[sType].getRowValue(oRow, nColumn);
+
+ var s;
+ var c = oRow.cells[nColumn];
+ if (typeof c.innerText != "undefined")
+ s = c.innerText;
+ else
+ s = SortableTable.getInnerText(c);
+ return this.getValueFromString(s, sType);
+};
+
+SortableTable.getInnerText = function (oNode) {
+ var s = "";
+ var cs = oNode.childNodes;
+ var l = cs.length;
+ for (var i = 0; i < l; i++) {
+ switch (cs[i].nodeType) {
+ case 1: //ELEMENT_NODE
+ s += SortableTable.getInnerText(cs[i]);
+ break;
+ case 3: //TEXT_NODE
+ s += cs[i].nodeValue;
+ break;
+ }
+ }
+ return s;
+};
+
+SortableTable.prototype.getValueFromString = function (sText, sType) {
+ if (this._sortTypeInfo[sType])
+ return this._sortTypeInfo[sType].getValueFromString( sText );
+ return sText;
+ /*
+ switch (sType) {
+ case "Number":
+ return Number(sText);
+ case "CaseInsensitiveString":
+ return sText.toUpperCase();
+ case "Date":
+ var parts = sText.split("-");
+ var d = new Date(0);
+ d.setFullYear(parts[0]);
+ d.setDate(parts[2]);
+ d.setMonth(parts[1] - 1);
+ return d.valueOf();
+ }
+ return sText;
+ */
+ };
+
+SortableTable.prototype.getSortFunction = function (sType, nColumn) {
+ if (this._sortTypeInfo[sType])
+ return this._sortTypeInfo[sType].compare;
+ return SortableTable.basicCompare;
+};
+
+SortableTable.prototype.destroy = function () {
+ this.uninitHeader();
+ var win = this.document.parentWindow;
+ if (win && typeof win.detachEvent != "undefined") { // only IE
needs this
+ win.detachEvent("onunload", this._onunload);
+ }
+ this._onunload = null;
+ this.element = null;
+ this.tHead = null;
+ this.tBody = null;
+ this.document = null;
+ this._headerOnclick = null;
+ this.sortTypes = null;
+ this._asyncsort = null;
+ this.onsort = null;
+};
+
+// Adds a sort type to all instance of SortableTable
+// sType : String - the identifier of the sort type
+// fGetValueFromString : function ( s : string ) : T - A function that takes a
+// string and casts it to a desired format. If left out the string is just
+// returned
+// fCompareFunction : function ( n1 : T, n2 : T ) : Number - A normal JS sort
+// compare function. Takes two values and compares them. If left out less
than,
+// <, compare is used
+// fGetRowValue : function( oRow : HTMLTRElement, nColumn : int ) : T - A
function
+// that takes the row and the column index and returns the value used to
compare.
+// If left out then the innerText is first taken for the cell and then the
+// fGetValueFromString is used to convert that string the desired value and
type
+
+SortableTable.prototype.addSortType = function (sType, fGetValueFromString,
fCompareFunction, fGetRowValue) {
+ this._sortTypeInfo[sType] = {
+ type: sType,
+ getValueFromString: fGetValueFromString ||
SortableTable.idFunction,
+ compare: fCompareFunction ||
SortableTable.basicCompare,
+ getRowValue: fGetRowValue
+ };
+};
+
+// this removes the sort type from all instances of SortableTable
+SortableTable.prototype.removeSortType = function (sType) {
+ delete this._sortTypeInfo[sType];
+};
+
+SortableTable.basicCompare = function compare(n1, n2) {
+ if (n1.value < n2.value)
+ return -1;
+ if (n2.value < n1.value)
+ return 1;
+ return 0;
+};
+
+SortableTable.idFunction = function (x) {
+ return x;
+};
+
+SortableTable.toUpperCase = function (s) {
+ return s.toUpperCase();
+};
+
+SortableTable.toDate = function (s) {
+ var parts = s.split("-");
+ var d = new Date(0);
+ d.setFullYear(parts[0]);
+ d.setDate(parts[2]);
+ d.setMonth(parts[1] - 1);
+ return d.valueOf();
+};
+
+
+// add sort types
+SortableTable.prototype.addSortType("Number", Number);
+SortableTable.prototype.addSortType("CaseInsensitiveString",
SortableTable.toUpperCase);
+SortableTable.prototype.addSortType("Date", SortableTable.toDate);
+SortableTable.prototype.addSortType("String");
+// None is a special case
Index: sitemgr/js/columnlist/original/local/helptip.css
diff -u /dev/null sitemgr/js/columnlist/original/local/helptip.css:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/local/helptip.css Mon Mar 27 13:13:24 2006
@@ -0,0 +1,36 @@
+/*
+ Notice that IE has a display problem if the help link is on
+ the last line of a container with no padding. If this is the
+ case increase the padding bottom to at least 1px
+*/
+
+a.helpLink {
+ color: Green;
+ text-decoration: none;
+ border-bottom: 1px dashed Green;
+}
+
+a.helpLink:hover {
+ color: Red;
+ text-decoration: none;
+ border-bottom: 1px dashed Red;
+}
+
+.help-tooltip {
+ position: absolute;
+ width: 250px;
+ border: 1px Solid WindowFrame;
+ background: Infobackground;
+ color: InfoText;
+ font: StatusBar;
+ font: Status-Bar;
+ padding: 3px;
+ filter:
progid:DXImageTransform.Microsoft.Shadow(color="#777777", Direction=135,
Strength=3);
z-index: 10000;
+}
+
+
+.help-tooltip a,
+.help-tooltip a:hover {
+ color: blue !important;
+ background: none;
+}
Index: sitemgr/js/columnlist/original/local/helptip.js
diff -u /dev/null sitemgr/js/columnlist/original/local/helptip.js:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/local/helptip.js Mon Mar 27 13:13:24 2006
@@ -0,0 +1,91 @@
+/*
+ * This script was created by Erik Arvidsson (erik(at)eae.net)
+ * for WebFX (http://webfx.eae.net)
+ * Copyright 2001
+ *
+ * For usage see license at http://webfx.eae.net/license.html
+ *
+ * Version: 1.0
+ * Created: 2001-09-27
* Updated: 2001-11-25 Added a resize to the tooltip if the document width is
too small
+ *
+ * Dependencies: helptip.css (To set up the CSS of the help-tooltip class)
+ *
+ * Usage:
+ *
+ * <script type="text/javascript" src="helptip.js"></script>
+ * <link type="text/css" rel="StyleSheet" href="helptip.css" />
+ *
+ * <a class="helpLink" href="?" onclick="showHelp(event, 'String to show');
return false">Help</a>
+ *
+ */
+
+function showHelpTip(e, s) {
+ // find anchor element
+ var el = e.target ? e.target : e.srcElement;
+ while (el.tagName != "A")
+ el = el.parentNode;
+
+ // is there already a tooltip? If so, remove it
+ if (el._helpTip) {
+ document.body.removeChild(el._helpTip);
+ el._helpTip = null;
+ el.onblur = null;
+ return;
+ }
+
+ // create element and insert last into the body
+ var d = document.createElement("DIV");
+ d.className = "help-tooltip";
+ document.body.appendChild(d);
+ d.innerHTML = s;
+
+ // Allow clicks on A elements inside tooltip
+ d.onmousedown = function (e) {
+ if (!e) e = event;
+ var t = e.target ? e.target : e.srcElement;
+ while (t.tagName != "A" && t != d)
+ t = t.parentNode;
+ if (t == d) return;
+
+ el._onblur = el.onblur;
+ el.onblur = null;
+ };
+ d.onmouseup = function () {
+ el.onblur = el._onblur;
+ el.focus();
+ };
+
+ // position tooltip
+ var dw = document.width ? document.width :
document.documentElement.offsetWidth - 25;
+ if (d.offsetWidth >= dw)
+ d.style.width = dw - 10 + "px";
else
+ d.style.width = "";
+ var scroll = getScroll();
+ if (e.clientX > dw - d.offsetWidth)
+ d.style.left = dw - d.offsetWidth + scroll.x + "px";
+ else
+ d.style.left = e.clientX - 2 + scroll.x + "px";
+ d.style.top = e.clientY + 18 + scroll.y + "px";
+
+ // add a listener to the blur event. When blurred remove tooltip and
restore anchor
+ el.onblur = function () {
+ document.body.removeChild(d);
+ el.onblur = null;
+ el._helpTip = null;
+ };
+
+ // store a reference to the tooltip div
+ el._helpTip = d;
+}
+
+// returns the scroll left and top for the browser viewport.
+function getScroll() {
+ if (document.all && document.body.scrollTop != undefined) { // IE
model
+ var ieBox = document.compatMode != "CSS1Compat";
+ var cont = ieBox ? document.body : document.documentElement;
+ return {x : cont.scrollLeft, y : cont.scrollTop};
+ }
+ else {
+ return {x : window.pageXOffset, y : window.pageYOffset};
+ }
+}
\ No newline at end of file
Index: sitemgr/js/columnlist/original/local/title-background.png
Index: sitemgr/js/columnlist/original/local/webfxapi.css
diff -u /dev/null sitemgr/js/columnlist/original/local/webfxapi.css:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/local/webfxapi.css Mon Mar 27 13:13:24 2006
@@ -0,0 +1,47 @@
+/* This style sheet is used for WebFX Api pages */
a.helpLink,
+a.helpLink:hover {
+ color: rgb(0,66,174);
+ border-bottom-color:rgb(0,66,174);
+}
+
+.help-tooltip {
+ width: auto;
+}
+
+.help-tooltip h4,
+.help-tooltip table,
+.help-tooltip p {
+ width: auto;
+}
+
+.methodContainer {
+ display: none;
+}
+
+.methodInfo h4,
+.methodInfo thead td {
+ font-size: 13px;
+ background: none;
+ border-bottom: 0;
+}
+
+.methodInfo h4,
+.methodInfo p,
+.methodInfo table {
+ margin: 5px;
+ padding: 0;
+}
+
+td {
+ vertical-align: top;
+}
+
+td code {
+ white-space: nowrap;
+}
+
+code a:visited,
+code a:hover {
+ color: rgb(0,66,174);
+ background: transparent;
+}
\ No newline at end of file
Index: sitemgr/js/columnlist/original/local/webfxapi.js
diff -u /dev/null sitemgr/js/columnlist/original/local/webfxapi.js:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/local/webfxapi.js Mon Mar 27 13:13:24 2006
@@ -0,0 +1,20 @@
+/*
+ * This script is used for WebFX Api pages
+ *
+ * It defines one funtion and includes helptip.js, helptip.css and
webfxapi.css
+ */
+
+document.write( "<script type='text/javascript'
src='local/helptip.js'><\/script>" );
+document.write( "<link type='text/css' rel='stylesheet'
href='local/helptip.css' />" );
+document.write( "<link type='text/css' rel='stylesheet'
href='local/webfxapi.css' />" );
+
+function toggleMethodArguments( e, a ) {
+ if ( a && a.nextSibling &&
+ typeof a.nextSibling.innerHTML != "undefined" &&
+ typeof showHelpTip != "undefined" ) {
+
+ showHelpTip( e, a.nextSibling.innerHTML );
+
+ }
+}
+
\ No newline at end of file
Index: sitemgr/js/columnlist/original/local/webfxlayout.css
diff -u /dev/null sitemgr/js/columnlist/original/local/webfxlayout.css:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/local/webfxlayout.css Mon Mar 27
13:13:24 2006
@@ -0,0 +1,297 @@
+
+/*
+
+bright: rgb(234,242,255);
+normal: rgb(120,172,255);
+dark: rgb(0,66,174);
+
+*/
+
+/* import menu css */
+/*
@import "dhtml/xmenu/xmenu.css";
*/
+
+#webfx-about {
+ position: absolute;
+ background: white;
+ top: 102px;
+ right: 10px;
+ width: 20px;
+ writing-mode: tb-rl;
+ filter: flipH() flipV() alpha(opacity=50);
+}
+
+/* headers css */
+
+#webfx-title {
+ position: absolute;
+ left: 90px;
+ top: -5px;
+ color: black;
+ background: transparent;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ font-family: Arial Black, Verdana, Helvetica, Sans-Serif;
+ font-weight: bold;
+ font-style: italic;
+ font-size: 45px;
+ letter-spacing: -5px;
+}
+
+#webfx-title-background {
+ width: 100%;
+ height: 67px;
+ background: white
no-repeat;/*rgb(100,100,100) no-repeat;*/
+ background-image: url("images/title-background.png");
+ background-position: 0 0;
+}
+
+#webfx-sub-title {
+ position: absolute;
+ left: 96px;
+ top: 45px;
+ color: black;
+ background: transparent;
+ padding: 0;
+ margin: 0;
+ border: 0;
+ font-family: Verdana, Helvetica, Sans-Serif;
+ font-size: 11px;
+}
+
+#webfx-menu-bar-1,
+#webfx-menu-bar-2,
+#webfx-menu-bar-3,
+#webfx-menu-bar-4,
+#webfx-menu-bar-5 {
+ height: 2px;
+ font-size: 0;
+ overflow: hidden;
+ background: rgb(120,172,255);/*#ff8800;*/
+ padding: 0;
+}
+
+#webfx-menu-bar-1 {
+ background:
rgb(0,66,174);/*rgb(120,172,255);/*black;/*rgb(234,242,255);*/
+ height: 1px;
+}
+
+#webfx-menu-bar-2 {
+ background: rgb(120,172,255);/*#ff8800;*/
+ height: 1px;
+}
+
+#webfx-menu-bar-3 {
+ background: rgb(120,172,255);/*#ff8800;*/
+ height: 1px;
+}
+
+#webfx-menu-bar-4 {
+ background: rgb(0,66,174);
+ height: 1px;
+}
+
+#webfx-menu-bar-5 {
+ background: #dddddd;
+ height: 3px;
+}
+
+/* headers css end */
+
+
+html, body {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ background: url("images/background-shadow.gif") repeat-y white;
+ color: black;
+
+ font-size: 13px;
+ font-family: "Verdana", "Tahoma", "Helvetica", "Sans-Serif";
+}
+
+.webfx-main-body {
+ margin-left: 100px;
width: 500px;
border-left: 1px solid rgb(120,172,255);
+}
+
+/* h1 only used in header */
+h2,h3,h4,h5,h6 {
margin-top: 10px;
+ margin-left: 10px;
+ margin-right: 10px;
+ padding: 2px 10px 2px 10px;
+ background: rgb(234,242,255);
+ border-bottom: 1px solid rgb(120,172,255);
+}
+
+h1,h2 {
+ font-weight: normal;
+}
+
+h3,h4,h5,h6 {
+ font-weight: bold;
+}
+
+h1 {
+ font-size: 50px;
+}
+
+h2 {
+ font-size: 20px;
+}
+
+h3 {
+ font-size: 15px;
+}
+
h4 {
+ font-size: 12px;
+}
+
+p {
+ margin: 10px;
+ font-size: 13px;
color: black;
text-align: justify;
+}
+
+td {
+ font-size: 13px;
+ font-family: "Verdana", "Tahoma", "Helvetica", "Sans-Serif";
+}
+
+pre {
margin: 20px;
margin-right: 10px;
+ background: #eeeeee;
+ padding: 10px;
+ border: 1px solid #dddddd;
+ color: black;
+}
+
+code {
+ background: #eeeeee;
+ border: 1px solid #dddddd;
+ color: black;
+}
+
+a {
+ text-decoration:underline;
+ color: rgb(0,66,174);
+}
+
+a:hover {/*rgb(0,66,174)*/
+ color: rgb(0,66,174);
+ background: rgb(234,242,255);
+}
+
+a:visited {
+ color: rgb(120,172,255);
+}
+
+a:visited:hover {
+ color: rgb(0,66,174);
+}
+
+hr {
+ margin-left: 10px;
+ margin-right: 10px;
+ padding: 0;
+ text-align: left;
+ height: 1px;
+ color: rgb(120,172,255);
+ background-color: rgb(120,172,255);
+ border-bottom: 1px solid rgb(120,172,255);
+ border: 0;
+}
+
+h2 a, h3 a {
+ display: block;
+ text-decoration: none;
+ width: expression("100%");
+}
+
+table {
+ margin: 10px;
+ font-size: 13px;
+ color: black;
+}
+
+thead td {
+ background: rgb(234,242,255);
+ border-bottom: 1px solid rgb(120,172,255);
+ font-weight: bold;
+}
+
+.author {
+ margin-top: 50px;
+ font-style: italic;
+}
+
+.date {
+ color: rgb(0,66,174);
+}
+
+.warning,
+.warning a {
+ color: red;
+}
+
+
+.warning a:visited,
+.warning a:hover {
+ color: red;
+}
+
+.warning a:hover {
+ background: rgb(255,230,230);
+}
+
+
+
+
+/* copied from xmenu.css */
+
+.webfx-menu-bar {
+ background: rgb(120,172,255);/*rgb(255,128,0);*/
+
+ padding: 2px;
+
+ font-family: Verdana, Helvetica, Sans-Serif;
+ font-size: 11px;
+
+}
+
+.webfx-menu-bar a,
+.webfx-menu-bar a:visited {
+ color: black;
+ border: 1px solid
rgb(120,172,255);/*rgb(255,128,0);*/
+
+ text-decoration: none;
+ padding: 1px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+.webfx-menu-bar a:hover {
+ color: black;
+ background: rgb(120,172,255);
+ border-left: 1px solid rgb(234,242,255);/*#ffcc88;*/
+ border-right: 1px solid rgb(0,66,174);/*#884400;*/
+ border-top: 1px solid rgb(234,242,255);/*#ffcc88;*/
+ border-bottom: 1px solid rgb(0,66,174);/*#884400;*/
+}
+
+.webfx-menu-bar a .arrow {
+ border: 0;
+ float: none;
+/*
+ float: right;
+ width: 6px;
+ height: 16px;
+
+ margin-right: 2px;
+ background: red;
+*/
+}
+
+.webfx-menu-bar a:active, .webfx-menu-bar a:focus {
+ -moz-outline: none;
+ outline: none;
+}
+
+/* end xmenu.css copy */
\ No newline at end of file
Index: sitemgr/js/columnlist/original/local/webfxlayout.js
diff -u /dev/null sitemgr/js/columnlist/original/local/webfxlayout.js:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/local/webfxlayout.js Mon Mar 27 13:13:24 2006
@@ -0,0 +1,111 @@
+/* this is a dummy webfxlayout file to be used in download zip files */
+
+
+/* Do includes */
+
+if (window.pathToRoot == null)
+ pathToRoot = "./";
+
+document.write('<link type="text/css" rel="stylesheet"
href="local/webfxlayout.css">');
+webfxMenuDefaultImagePath = pathToRoot + "images/";
+
+/* end includes */
+
+/* set up browser checks and add a simple emulation for IE4 */
+
+// check browsers
+var op = /opera 5|opera\/5/i.test(navigator.userAgent);
+var ie = !op && /msie/i.test(navigator.userAgent); // preventing opera to
be identified as ie
+var mz = !op && /mozilla\/5/i.test(navigator.userAgent); // preventing
opera to be identified as mz
+
+if (ie && document.getElementById == null) { // ie4
+ document.getElementById = function(sId) {
+ return document.all[sId];
+ };
+}
+
+/* end browser checks */
+
+webfxLayout = {
+ writeTitle : function (s, s2) {
+ document.write("<div id='webfx-title-background'></div>");
+ if (op) {
+ document.write("<h1 id='webfx-title' style='top:9px;'>"
+ s + "</h1>");
+ }
+ else {
+ document.write("<h1 id='webfx-title'>" + s + "</h1>");
+ }
+
+ if (s2 == null)
+ s2 = "WebFX - What you never thought possible!";
+
+ if (op) {
+ document.write("<span id='webfx-sub-title'
style='top:46px;'>" + s2 + "</span>");
+ }
+ else {
+ document.write("<span id='webfx-sub-title'>" + s2 +
"</span>");
+ }
+ },
+ writeMainTitle : function () {
+ this.writeTitle("WebFX", "What you never thought possible!");
+ },
+ writeTopMenuBar : function () {
+ document.write("<div id='webfx-menu-bar-1'></div>");
+ if (op) {
+ document.write("<style>.webfx-menu-bar a
{padding-top:3px;}</style>");
+ document.write("<div id='webfx-menu-bar-2'
style='height:2px;'></div>");
+ }
+ else
+ document.write("<div id='webfx-menu-bar-2'></div>");
+ document.write("<div id='webfx-menu-bar'>");// div is closed in
writeBottomMenuBar
+ },
+ writeBottomMenuBar : function () {
+ document.write("</div>");
+ if (op)
+ document.write("<div id='webfx-menu-bar-3'
style='height:0px;'></div>");
+ else
+ document.write("<div id='webfx-menu-bar-3'></div>");
+ document.write("<div id='webfx-menu-bar-4'></div>");
+ document.write("<div id='webfx-menu-bar-5'></div>");
+ },
+ writeMenu : function () {
+ this.writeTopMenuBar();
+ //document.write(webfxMenuBar);
+ document.write("<div class='webfx-menu-bar'><a
href='http://webfx.eae.net'>WebFX Home</a></div>");
+ this.writeBottomMenuBar();
+ },
+ writeDesignedByEdger : function () {
+ if (ie && document.body.currentStyle.writingMode != null)
+ document.write("<div id='webfx-about'>Page designed and
maintained by " +
+ "<a href='mailto:address@hidden'>Erik
Arvidsson</a> & " +
+ "<a href='mailto:address@hidden'>Emil A
Eklund</a>.</div>");
+ }
+};
+
+if (ie && window.attachEvent) {
+ window.attachEvent("onload", function () {
+ var scrollBorderColor = "rgb(120,172,255)";
+ var scrollFaceColor = "rgb(234,242,255)";
+ with (document.body.style) {
+ scrollbarDarkShadowColor =
scrollBorderColor;
+ scrollbar3dLightColor =
scrollBorderColor;
+ scrollbarArrowColor = "black";
+ scrollbarBaseColor =
scrollFaceColor;
+ scrollbarFaceColor =
scrollFaceColor;
+ scrollbarHighlightColor = scrollFaceColor;
+ scrollbarShadowColor = scrollFaceColor;
+ scrollbarTrackColor = "white";
+ }
+ });
+}
+
+/* we also need some dummy constructors */
+webfxMenuBar = {
+ add : function () {}
+};
+function WebFXMenu() {
+ this.add = function () {};
+}
+function WebFXMenuItem() {}
+function WebFXMenuSeparator() {}
+function WebFXMenuButton() {}
\ No newline at end of file
Index: sitemgr/js/columnlist/original/usage.html
diff -u /dev/null sitemgr/js/columnlist/original/usage.html:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/original/usage.html Mon Mar 27 13:13:24 2006
@@ -0,0 +1,173 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <title>ColumnList Usage (WebFX)</title>
+ <meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
+ <script type="text/javascript"
src="local/webfxlayout.js"></script>
+ <link type="text/css" rel="stylesheet" href="columnlist.css" />
+ <script src="columnlist.js" type="text/javascript"></script>
+ </head>
+ <body>
+ <!-- WebFX Layout Include -->
+ <script type="text/javascript">
+ //<![CDATA[
+ var articleMenu= new WebFXMenu;
+ articleMenu.left = 384;
+ articleMenu.top = 86;
+ articleMenu.width = 140;
+ articleMenu.add(new WebFXMenuItem("Introduction",
"columnlist.html"));
+ articleMenu.add(new WebFXMenuItem("Implementation",
"implementation.html"));
+ articleMenu.add(new WebFXMenuItem("Usage",
"usage.html"));
+ articleMenu.add(new WebFXMenuItem("API", "api.html"));
+ articleMenu.add(new WebFXMenuItem("Demo", "demo.html"));
+ articleMenu.add(new WebFXMenuSeparator);
+ articleMenu.add(new WebFXMenuItem("Download",
"http://webfx.eae.net/download/collist103.zip"));
+ webfxMenuBar.add(new WebFXMenuButton("Article Menu",
null, null, articleMenu));
+
+ webfxLayout.writeTitle("ColumnList Usage");
+ webfxLayout.writeMenu();
+ webfxLayout.writeDesignedByEdger();
+ //]]>
+ </script>
+ <!-- End WebFX Layout Includes -->
+ <div class="webfx-main-body">
+ <h2>Usage</h2>
+ <p>
+ To use the ColumnList widget the
<i>columnlist.js</i>, <i>sortabletable.js</i>
+ and <i>columnlist.css</i> files needs to be
included and two images used to
+ indicate sorting direction <i>asc.png</i> and
<i>desc.png</i> should be
+ placed in a the same directory (if their
located elsewhere change the
+ <code>IMG_DESC</code> and <code>IMG_ASC</code>
settings at the top of
+ the <i>columnlist.js</i> file).
+ <pre><link type="text/css" rel="stylesheet"
href="columnlist.css" />
+<script type="text/javascript" src="sortabletable.js"></script>
+<script type="text/javascript" src="columnlist.js"></script></pre>
+ </p>
+ <p>
+ As mentioned in the introduction the columnlist
can be created in two different
+ ways, either by attaching to an existing
structure or by generating it. Let's
+ begin with the later of the two.
+ </p>
+ <h3>Generating a new structure</h3>
+ <p>
+ The first step is to create an instance of the
WebFXColumnList class using
+ the default constructor <code>o = new
WebFXColumnList()</code>. Then the
+ <code>create</code> method is called, with the
target element and an array
+ with column labels as the arguments. This will
create a new, emtpy, column
+ list widget out of the container element. Once
it's created rows can be added
+ using the <code>addRow</code> method (or
<code>addRows</code> to add multiple
+ rows at once).
+ </p>
+ <h3>HTML</h3>
+ <p>
+ The base of the column list is the container
element and it has to be an
+ existing element. The size of this element
controls the size of the widget.
+ <pre><div id="container" style="width:
320px; height: 240px;"></pre>
+ </p>
+ <h3>JavaScript</h3>
+ <p>
+ The following JavaScript code will create a
ColumnList widget with the 15
+ most popular kinds of ice cream (according to
the International Ice Cream Association).
+ <pre>var aColumns = [
+ 'Rank',
+ 'Flavor',
+ 'Color',
+ 'Share'
+];
+
+var aData = [
+ ['1','Vanilla','White','29%'],
+ ['2','Chocolate','Brown','8.9%'],
+ ['3','Butter pecan','Light brown','5.3%'],
+ ['4','Strawberry','Pink','5.3%'],
+ ['5','Neapolitan','Greenish brown','4.2%'],
+ ['6','Chocolate chip','Brown','3.9%'],
+ ['7','French vanilla','Yellowish white','3.8%'],
+ ['8','Cookies and cream','Light brown','3.6%'],
+ ['9','Vanilla fudge ripple','White', '2.6%'],
+ ['10','Praline pecan','Brown','1.7%'],
+ ['11','Cherry','Red','1.6%'],
+ ['12','Chocolate almond','Brown','1.6%'],
+ ['13','Coffee','Dark brown', '1.6%'],
+ ['14','Rocky road','brown', '1.5%'],
+ ['15','Chocolate marshmallow','Light brown','1.3%']
+];
+
+var el = document.getElementById('container');
+
+var o = new WebFXColumnList();
+o.create(el, aColumns);
+o.addRows(aData);</pre>
+ </p>
+ <h3>Result</h3>
+ <p>
+ <iframe src="demo2.html" style="width: 500px;
height: 240px;" onkeydown="if (window.event) { window.event.cancelBubble =
true; } else { preventDefault(); } return false;"></iframe>
+ </p>
+ <h3>Attaching to existing structure</h3>
+ <p>
+ The other method that can be used to create a
column list widget
+ is to attach it to an existing structure. This
method is preferred
+ if the content is being generated by a server
side script of some
+ sort as it's quite a lot faster for larger
amounts of date. The major
+ drawbacks are that it's not as convenient and
requires more markup.
+ </p>
+ <p>
+ The idea here is to manually create the
structure that would be generated
+ by the create method (described above) and then
simply attach the widget
+ to it.
+ </p>
+ <p>
+ The main difference here is that the content
(header columns and data)
+ is defined using HTML rather than JavaScript.
Thus there's a lot of HTML
+ markup but very little JavaScript, quite the
opposite of the create method.
+ <h3>HTML</h3>
+ <pre><div id="container" class="webfx-columnlist"
style="margin-left: 50px; width: 640px; height: 480px;">
+<div id="head" class="webfx-columnlist-head">
+ <table cellspacing="0" cellpadding="0">
+ <tr>
+ <td>Flavor<img
src="images/asc.png"/></td>
+ <td>Color<img
src="images/asc.png"/></td>
+ <td>Texture<img
src="images/asc.png"/></td>
+ <td>Price<img
src="images/asc.png"/></td>
+ </tr>
+ </table>
+</div>
+<div id="body" class="webfx-columnlist-body">
+ <table cellspacing="0" cellpadding="0">
+ <colgroup span="4">
+ <col style="width: auto;" />
+ <col style="width: auto;" />
+ <col style="width: auto;" />
+ <col style="width: auto;" />
+ </colgroup>
+
<tr><td>Vanilla</td><td>White</td><td>Smooth</td><td>$
10</td></tr>
+
<tr><td>Pear</td><td>Green</td><td>Smooth</td><td>$
8</td></tr>
+
<tr><td>Strawberry</td><td>Pink</td><td>Smooth</td><td>$
8</td></tr>
+
<tr><td>Chocolate</td><td>Brown</td><td>Chunky</td><td>$
8</td></tr>
+ <tr><td>Pistachio</td><td>Light
green</td><td>Chunky</td><td>$ 9</td></tr>
+ </table>
+</div></pre>
+ </p>
+ <h3>JavaScript</h3>
+ <p>
+ <pre>var o = new WebFXColumnList();
+var rc = o.bind(document.getElementById('container'),
document.getElementById('head'), document.getElementById('body'));</pre>
+ </p>
+ <h3>Result</h3>
+ <p>
+ The example code above is actually a shortened
version of the demo linked below.
+ Please see that demo for the full source and
the result.
+ </p>
+ <p>
+ <a href="columnlist.html">Introduction</a><br />
+ <a
href="implementation.html">Implementation</a><br />
+ Usage<br />
+ <a href="api.html">API</a><br />
+ <a href="demo.html">Demo</a><br />
+ <a
href="http://webfx.eae.net/download/collist103.zip">Download</a>
+ </p>
+ <p class="author">Author: Emil A Eklund</p>
+ <!-- end webfx-main-body -->
+ </div>
+ </body>
+</html>
Index: sitemgr/js/columnlist/sortabletable.js
diff -u /dev/null sitemgr/js/columnlist/sortabletable.js:1.1.2.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/js/columnlist/sortabletable.js Mon Mar 27 13:13:24 2006
@@ -0,0 +1,455 @@
+
+/*----------------------------------------------------------------------------\
+| Sortable Table 1.12 |
+|-----------------------------------------------------------------------------|
+| Created by Erik Arvidsson |
+| (http://webfx.eae.net/contact.html#erik) |
+| For WebFX (http://webfx.eae.net/) |
+|-----------------------------------------------------------------------------|
+| A DOM 1 based script that allows an ordinary HTML table to be sortable. |
+|-----------------------------------------------------------------------------|
+| Copyright (c) 1998 - 2004 Erik Arvidsson |
+|-----------------------------------------------------------------------------|
+| This software is provided "as is", without warranty of any kind, express or |
+| implied, including but not limited to the warranties of merchantability, |
+| fitness for a particular purpose and noninfringement. In no event shall the |
+| authors or copyright holders be liable for any claim, damages or other |
+| liability, whether in an action of contract, tort or otherwise, arising |
+| from, out of or in connection with the software or the use or other |
+| dealings in the software. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| This software is available under the three different licenses mentioned |
+| below. To use this software you must chose, and qualify, for one of those. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| The WebFX Non-Commercial License http://webfx.eae.net/license.html |
+| Permits anyone the right to use the software in a non-commercial context |
+| free of charge. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| The WebFX Commercial license http://webfx.eae.net/commercial.html |
+| Permits the license holder the right to use the software in a commercial |
+| context. Such license must be specifically obtained, however it's valid for |
+| any number of implementations of the licensed software. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt |
+| Permits anyone the right to use and modify the software without limitations |
+| as long as proper credits are given and the original and modified source |
+| code are included. Requires that the final product, software derivate from |
+| the original source or any software utilizing a GPL component, such as |
+| this, is also licensed under the GPL license. |
+|-----------------------------------------------------------------------------|
+| 2003-01-10 | First version |
+| 2003-01-19 | Minor changes to the date parsing |
+| 2003-01-28 | JScript 5.0 fixes (no support for 'in' operator) |
+| 2003-02-01 | Sloppy typo like error fixed in getInnerText |
+| 2003-07-04 | Added workaround for IE cellIndex bug. |
+| 2003-11-09 | The bDescending argument to sort was not correctly working |
+| | Using onclick DOM0 event if no support for addEventListener |
+| | or attachEvent |
+| 2004-01-13 | Adding addSortType and removeSortType which makes it a lot |
+| | easier to add new, custom sort types. |
+| 2004-01-27 | Switch to use descending = false as the default sort order. |
+| | Change defaultDescending to suit your needs. |
+| 2004-03-14 | Improved sort type None look and feel a bit |
+| 2004-08-26 | Made the handling of tBody and tHead more flexible. Now you |
+| | can use another tHead or no tHead, and you can chose some |
+| | other tBody. |
+|-----------------------------------------------------------------------------|
+| Created 2003-01-10 | All changes are in the log above. | Updated 2004-08-26 |
+\----------------------------------------------------------------------------*/
+
+
+function SortableTable(oTable, oSortTypes) {
+
+ this._sortTypes = oSortTypes || [];
+
+ this.sortColumn = null;
+ this.descending = null;
+
+ var oThis = this;
+ this._headerOnclick = function (e) {
+ oThis.headerOnclick(e);
+ };
+
+ if (oTable) {
+ this.setTable( oTable );
+ this.document = oTable.ownerDocument || oTable.document;
+ }
+ else {
+ this.document = document;
+ }
+
+
+ // only IE needs this
+ var win = this.document.defaultView || this.document.parentWindow;
+ this._onunload = function () {
+ oThis.destroy();
+ };
+ if (win && typeof win.attachEvent != "undefined") {
+ win.attachEvent("onunload", this._onunload);
+ }
+}
+
+SortableTable.gecko = navigator.product == "Gecko";
+SortableTable.msie = /msie/i.test(navigator.userAgent);
+// Mozilla is faster when doing the DOM manipulations on
+// an orphaned element. MSIE is not
+SortableTable.removeBeforeSort = SortableTable.gecko;
+
+SortableTable.prototype.onsort = function () {};
+
+// default sort order. true -> descending, false -> ascending
+SortableTable.prototype.defaultDescending = false;
+
+// shared between all instances. This is intentional to allow external files
+// to modify the prototype
+SortableTable.prototype._sortTypeInfo = {};
+
+SortableTable.prototype.setTable = function (oTable) {
+ if ( this.tHead )
+ this.uninitHeader();
+ this.element = oTable;
+ this.setTHead( oTable.tHead );
+ this.setTBody( oTable.tBodies[0] );
+};
+
+SortableTable.prototype.setTHead = function (oTHead) {
+ if (this.tHead && this.tHead != oTHead )
+ this.uninitHeader();
+ this.tHead = oTHead;
+ this.initHeader( this._sortTypes );
+};
+
+SortableTable.prototype.setTBody = function (oTBody) {
+ this.tBody = oTBody;
+};
+
+SortableTable.prototype.setSortTypes = function ( oSortTypes ) {
+ if ( this.tHead )
+ this.uninitHeader();
+ this._sortTypes = oSortTypes || [];
+ if ( this.tHead )
+ this.initHeader( this._sortTypes );
+};
+
+// adds arrow containers and events
+// also binds sort type to the header cells so that reordering columns does
+// not break the sort types
+SortableTable.prototype.initHeader = function (oSortTypes) {
+ if (!this.tHead) return;
+ var cells = this.tHead.rows[0].cells;
+ var doc = this.tHead.ownerDocument || this.tHead.document;
+ this._sortTypes = oSortTypes || [];
+ var l = cells.length;
+ var img, c;
+ for (var i = 0; i < l; i++) {
+ c = cells[i];
+ if (this._sortTypes[i] != null && this._sortTypes[i] != "None")
{
+ img = doc.createElement("IMG");
+ img.src = "images/blank.png";
+ c.appendChild(img);
+ if (this._sortTypes[i] != null)
+ c._sortType = this._sortTypes[i];
+ if (typeof c.addEventListener != "undefined")
+ c.addEventListener("click",
this._headerOnclick, false);
+ else if (typeof c.attachEvent != "undefined")
+ c.attachEvent("onclick", this._headerOnclick);
+ else
+ c.onclick = this._headerOnclick;
+ }
+ else
+ {
+ c.setAttribute( "_sortType", oSortTypes[i] );
+ c._sortType = "None";
+ }
+ }
+ this.updateHeaderArrows();
+};
+
+// remove arrows and events
+SortableTable.prototype.uninitHeader = function () {
+ if (!this.tHead) return;
+ var cells = this.tHead.rows[0].cells;
+ var l = cells.length;
+ var c;
+ for (var i = 0; i < l; i++) {
+ c = cells[i];
+ if (c._sortType != null && c._sortType != "None") {
+ c.removeChild(c.lastChild);
+ if (typeof c.removeEventListener != "undefined")
+ c.removeEventListener("click",
this._headerOnclick, false);
+ else if (typeof c.detachEvent != "undefined")
+ c.detachEvent("onclick", this._headerOnclick);
+ c._sortType = null;
+ c.removeAttribute( "_sortType" );
+ }
+ }
+};
+
+SortableTable.prototype.updateHeaderArrows = function () {
+ if (!this.tHead) return;
+ var cells = this.tHead.rows[0].cells;
+ var l = cells.length;
+ var img;
+ for (var i = 0; i < l; i++) {
+ if (cells[i]._sortType != null && cells[i]._sortType != "None")
{
+ img = cells[i].lastChild;
+ if (i == this.sortColumn)
+ img.className = "sort-arrow " +
(this.descending ? "descending" : "ascending");
+ else
+ img.className = "sort-arrow";
+ }
+ }
+};
+
+SortableTable.prototype.headerOnclick = function (e) {
+ // find TD element
+ var el = e.target || e.srcElement;
+ while (el.tagName != "TD")
+ el = el.parentNode;
+
+ this.sort(SortableTable.msie ? SortableTable.getCellIndex(el) :
el.cellIndex);
+};
+
+// IE returns wrong cellIndex when columns are hidden
+SortableTable.getCellIndex = function (oTd) {
+ var cells = oTd.parentNode.childNodes
+ var l = cells.length;
+ var i;
+ for (i = 0; cells[i] != oTd && i < l; i++)
+ ;
+ return i;
+};
+
+SortableTable.prototype.getSortType = function (nColumn) {
+ return this._sortTypes[nColumn] || "String";
+};
+
+// only nColumn is required
+// if bDescending is left out the old value is taken into account
+// if sSortType is left out the sort type is found from the sortTypes array
+
+SortableTable.prototype.sort = function (nColumn, bDescending, sSortType) {
+ if (!this.tBody) return;
+ if (sSortType == null)
+ sSortType = this.getSortType(nColumn);
+
+ // exit if None
+ if (sSortType == "None")
+ return;
+
+ if (bDescending == null) {
+ if (this.sortColumn != nColumn)
+ this.descending = this.defaultDescending;
+ else
+ this.descending = !this.descending;
+ }
+ else
+ this.descending = bDescending;
+
+ this.sortColumn = nColumn;
+
+ if (typeof this.onbeforesort == "function")
+ this.onbeforesort();
+
+ var f = this.getSortFunction(sSortType, nColumn);
+ var a = this.getCache(sSortType, nColumn);
+ var tBody = this.tBody;
+
+ a.sort(f);
+
+ if (this.descending)
+ a.reverse();
+
+ if (SortableTable.removeBeforeSort) {
+ // remove from doc
+ var nextSibling = tBody.nextSibling;
+ var p = tBody.parentNode;
+ p.removeChild(tBody);
+ }
+
+ // insert in the new order
+ var l = a.length;
+ for (var i = 0; i < l; i++)
+ tBody.appendChild(a[i].element);
+
+ if (SortableTable.removeBeforeSort) {
+ // insert into doc
+ p.insertBefore(tBody, nextSibling);
+ }
+
+ this.updateHeaderArrows();
+
+ this.destroyCache(a);
+
+ if (typeof this.onsort == "function")
+ this.onsort();
+};
+
+SortableTable.prototype.asyncSort = function (nColumn, bDescending, sSortType)
{
+ var oThis = this;
+ this._asyncsort = function () {
+ oThis.sort(nColumn, bDescending, sSortType);
+ };
+ window.setTimeout(this._asyncsort, 1);
+};
+
+SortableTable.prototype.getCache = function (sType, nColumn) {
+ if (!this.tBody) return [];
+ var rows = this.tBody.rows;
+ var l = rows.length;
+ var a = new Array(l);
+ var r;
+ for (var i = 0; i < l; i++) {
+ r = rows[i];
+ a[i] = {
+ value: this.getRowValue(r, sType, nColumn),
+ element: r
+ };
+ };
+ return a;
+};
+
+SortableTable.prototype.destroyCache = function (oArray) {
+ var l = oArray.length;
+ for (var i = 0; i < l; i++) {
+ oArray[i].value = null;
+ oArray[i].element = null;
+ oArray[i] = null;
+ }
+};
+
+SortableTable.prototype.getRowValue = function (oRow, sType, nColumn) {
+ // if we have defined a custom getRowValue use that
+ if (this._sortTypeInfo[sType] && this._sortTypeInfo[sType].getRowValue)
+ return this._sortTypeInfo[sType].getRowValue(oRow, nColumn);
+
+ var s;
+ var c = oRow.cells[nColumn];
+ if (typeof c.innerText != "undefined")
+ s = c.innerText;
+ else
+ s = SortableTable.getInnerText(c);
+ return this.getValueFromString(s, sType);
+};
+
+SortableTable.getInnerText = function (oNode) {
+ var s = "";
+ var cs = oNode.childNodes;
+ var l = cs.length;
+ for (var i = 0; i < l; i++) {
+ switch (cs[i].nodeType) {
+ case 1: //ELEMENT_NODE
+ s += SortableTable.getInnerText(cs[i]);
+ break;
+ case 3: //TEXT_NODE
+ s += cs[i].nodeValue;
+ break;
+ }
+ }
+ return s;
+};
+
+SortableTable.prototype.getValueFromString = function (sText, sType) {
+ if (this._sortTypeInfo[sType])
+ return this._sortTypeInfo[sType].getValueFromString( sText );
+ return sText;
+ /*
+ switch (sType) {
+ case "Number":
+ return Number(sText);
+ case "CaseInsensitiveString":
+ return sText.toUpperCase();
+ case "Date":
+ var parts = sText.split("-");
+ var d = new Date(0);
+ d.setFullYear(parts[0]);
+ d.setDate(parts[2]);
+ d.setMonth(parts[1] - 1);
+ return d.valueOf();
+ }
+ return sText;
+ */
+ };
+
+SortableTable.prototype.getSortFunction = function (sType, nColumn) {
+ if (this._sortTypeInfo[sType])
+ return this._sortTypeInfo[sType].compare;
+ return SortableTable.basicCompare;
+};
+
+SortableTable.prototype.destroy = function () {
+ this.uninitHeader();
+ var win = this.document.parentWindow;
+ if (win && typeof win.detachEvent != "undefined") { // only IE
needs this
+ win.detachEvent("onunload", this._onunload);
+ }
+ this._onunload = null;
+ this.element = null;
+ this.tHead = null;
+ this.tBody = null;
+ this.document = null;
+ this._headerOnclick = null;
+ this.sortTypes = null;
+ this._asyncsort = null;
+ this.onsort = null;
+};
+
+// Adds a sort type to all instance of SortableTable
+// sType : String - the identifier of the sort type
+// fGetValueFromString : function ( s : string ) : T - A function that takes a
+// string and casts it to a desired format. If left out the string is just
+// returned
+// fCompareFunction : function ( n1 : T, n2 : T ) : Number - A normal JS sort
+// compare function. Takes two values and compares them. If left out less
than,
+// <, compare is used
+// fGetRowValue : function( oRow : HTMLTRElement, nColumn : int ) : T - A
function
+// that takes the row and the column index and returns the value used to
compare.
+// If left out then the innerText is first taken for the cell and then the
+// fGetValueFromString is used to convert that string the desired value and
type
+
+SortableTable.prototype.addSortType = function (sType, fGetValueFromString,
fCompareFunction, fGetRowValue) {
+ this._sortTypeInfo[sType] = {
+ type: sType,
+ getValueFromString: fGetValueFromString ||
SortableTable.idFunction,
+ compare: fCompareFunction ||
SortableTable.basicCompare,
+ getRowValue: fGetRowValue
+ };
+};
+
+// this removes the sort type from all instances of SortableTable
+SortableTable.prototype.removeSortType = function (sType) {
+ delete this._sortTypeInfo[sType];
+};
+
+SortableTable.basicCompare = function compare(n1, n2) {
+ if (n1.value < n2.value)
+ return -1;
+ if (n2.value < n1.value)
+ return 1;
+ return 0;
+};
+
+SortableTable.idFunction = function (x) {
+ return x;
+};
+
+SortableTable.toUpperCase = function (s) {
+ return s.toUpperCase();
+};
+
+SortableTable.toDate = function (s) {
+ var parts = s.split("-");
+ var d = new Date(0);
+ d.setFullYear(parts[0]);
+ d.setDate(parts[2]);
+ d.setMonth(parts[1] - 1);
+ return d.valueOf();
+};
+
+
+// add sort types
+SortableTable.prototype.addSortType("Number", Number);
+SortableTable.prototype.addSortType("CaseInsensitiveString",
SortableTable.toUpperCase);
+SortableTable.prototype.addSortType("Date", SortableTable.toDate);
+SortableTable.prototype.addSortType("String");
+// None is a special case
Index: sitemgr/modules/class.module_html.inc.php
diff -u sitemgr/modules/class.module_html.inc.php:1.1.2.2.4.1
sitemgr/modules/class.module_html.inc.php:1.1.2.2.4.2
--- sitemgr/modules/class.module_html.inc.php:1.1.2.2.4.1 Sat Nov 12
14:11:58 2005
+++ sitemgr/modules/class.module_html.inc.php Mon Mar 27 13:13:24 2006
@@ -10,7 +10,7 @@
'type' => 'richtext', //'textarea',
'label' => lang('Enter the block
content here'),
'i18n' => True,
- 'params' => array('width' => 650,
'height' => 250)
+ 'params' => array('cols' => 80, 'rows'
=> 20)
)
);
$this->properties = array('striphtml' => array('type'
=> 'checkbox', 'label' => lang('Strip HTML from block content?')));
Index: sitemgr/setup/setup.inc.php
diff -u sitemgr/setup/setup.inc.php:1.12.2.2.4.2
sitemgr/setup/setup.inc.php:1.12.2.2.4.3
--- sitemgr/setup/setup.inc.php:1.12.2.2.4.2 Sat Nov 12 14:11:58 2005
+++ sitemgr/setup/setup.inc.php Mon Mar 27 13:13:24 2006
@@ -9,11 +9,11 @@
* option) any later version.
*
\**************************************************************************/
- /* $Id: setup.inc.php,v 1.12.2.2.4.2 2005/11/12 14:11:58 skwashd Exp $
*/
+ /* $Id: setup.inc.php,v 1.12.2.2.4.3 2006/03/27 13:13:24 skwashd Exp $
*/
$setup_info['sitemgr']['name'] = 'sitemgr';
$setup_info['sitemgr']['title'] = 'SiteMgr Web Content Manager';
- $setup_info['sitemgr']['version'] = '0.9.16.000';
+ $setup_info['sitemgr']['version'] = '0.9.16.001';
$setup_info['sitemgr']['app_order'] = 8;
$setup_info['sitemgr']['tables'] =
array('phpgw_sitemgr_pages','phpgw_sitemgr_pages_lang','phpgw_sitemgr_categories_state','phpgw_sitemgr_categories_lang','phpgw_sitemgr_modules','phpgw_sitemgr_blocks','phpgw_sitemgr_blocks_lang','phpgw_sitemgr_content','phpgw_sitemgr_content_lang','phpgw_sitemgr_active_modules','phpgw_sitemgr_properties','phpgw_sitemgr_sites');
$setup_info['sitemgr']['enable'] = 1;
@@ -38,4 +38,4 @@
'appname' =>
'news_admin',
'versions' =>
array('0.9.17')
);
-?>
+
Index: sitemgr/setup/tables_current.inc.php
diff -u sitemgr/setup/tables_current.inc.php:1.11.2.1.4.1
sitemgr/setup/tables_current.inc.php:1.11.2.1.4.2
--- sitemgr/setup/tables_current.inc.php:1.11.2.1.4.1 Sat Nov 12 13:15:38 2005
+++ sitemgr/setup/tables_current.inc.php Mon Mar 27 13:13:24 2006
@@ -9,7 +9,7 @@
* option) any later version.
*
\**************************************************************************/
- /* $Id: tables_current.inc.php,v 1.11.2.1.4.1 2005/11/12 13:15:38
skwashd Exp $ */
+ /* $Id: tables_current.inc.php,v 1.11.2.1.4.2 2006/03/27 13:13:24
skwashd Exp $ */
$phpgw_baseline = array(
'phpgw_sitemgr_pages' => array(
@@ -42,7 +42,8 @@
'fd' => array(
'cat_id' => array('type' => 'int','precision'
=> '4','nullable' => False),
'state' => array('type' => 'int','precision' =>
'2','nullable' => False),
- 'def_page' => array('type' => 'int','precision'
=> '4','nullable' => False,'default' => '0')
+ 'def_page' => array('type' => 'int','precision'
=> '4','nullable' => False,'default' => '0'),
+ 'template_set' => array('type' =>
'varchar','precision' => '50','nullable' => True)
),
'pk' => array('cat_id'),
'fk' => array(),
Index: sitemgr/setup/tables_update.inc.php
diff -u sitemgr/setup/tables_update.inc.php:1.11.2.4.4.1
sitemgr/setup/tables_update.inc.php:1.11.2.4.4.2
--- sitemgr/setup/tables_update.inc.php:1.11.2.4.4.1 Sat Nov 12 13:15:38 2005
+++ sitemgr/setup/tables_update.inc.php Mon Mar 27 13:13:24 2006
@@ -9,7 +9,7 @@
* option) any later version.
*
\**************************************************************************/
- /* $Id: tables_update.inc.php,v 1.11.2.4.4.1 2005/11/12 13:15:38
skwashd Exp $ */
+ /* $Id: tables_update.inc.php,v 1.11.2.4.4.2 2006/03/27 13:13:24
skwashd Exp $ */
$test[] = '0.9.13.001';
function sitemgr_upgrade0_9_13_001()
@@ -655,4 +655,19 @@
$GLOBALS['setup_info']['sitemgr']['currentver'] = '0.9.16.000';
return $GLOBALS['setup_info']['sitemgr']['currentver'];
}
+
+
+ $test[] = '0.9.16.000';
+ function sitemgr_upgrade0_9_16_000()
+ {
+
$GLOBALS['phpgw_setup']->oProc->AddColumn('phpgw_sitemgr_categories_state','template_set',array(
+ 'type' => 'varchar',
+ 'precision' => '50',
+ 'nullable' => True
+ ));
+
+
+ $GLOBALS['setup_info']['sitemgr']['currentver'] = '0.9.16.001';
+ return $GLOBALS['setup_info']['sitemgr']['currentver'];
+ }
?>
Index: sitemgr/sitemgr-site/inc/class.sitebo.inc.php
diff -u /dev/null sitemgr/sitemgr-site/inc/class.sitebo.inc.php:1.1.2.3.4.1
--- /dev/null Mon Mar 27 13:13:25 2006
+++ sitemgr/sitemgr-site/inc/class.sitebo.inc.php Mon Mar 27 13:13:24 2006
@@ -0,0 +1,359 @@
+<?php
+
/*************************************************************************\
+ * phpGroupWare - Web Content Manager
*
+ * http://www.phpgroupware.org
*
+ * -------------------------------------------------
*
+ * This program is free software; you can redistribute it and/or modify
it *
+ * under the terms of the GNU General Public License as published by the
*
+ * Free Software Foundation; either version 2 of the License, or (at
your *
+ * option) any later version.
*
+
\*************************************************************************/
+ /* $Id: class.sitebo.inc.php,v 1.1.2.3.4.1 2006/03/27 13:13:24 skwashd
Exp $ */
+
+ class sitebo
+ {
+ var $pages_bo;
+ var $catbo;
+ var $acl;
+
+ function sitebo()
+ {
+ $this->catbo = &$GLOBALS['Common_BO']->cats;
+ $this->pages_bo = &$GLOBALS['Common_BO']->pages;
+ $this->acl = &$GLOBALS['Common_BO']->acl;
+ $this->isadmin = $this->acl->is_admin;
+ //$anonymous_user is globally set in config.inc.php
+ $this->isuser =
($GLOBALS['phpgw_info']['user']['account_lid'] != $GLOBALS['anonymous_user']);
+ }
+
+ function getcatwrapper($cat_id)
+ {
+ $availablelangsforcat =
$this->catbo->getlangarrayforcategory($cat_id);
+ if
(in_array($GLOBALS['sitemgr_info']['userlang'],$availablelangsforcat))
+ {
+ return
$this->catbo->getCategory($cat_id,$GLOBALS['sitemgr_info']['userlang']);
+ }
+ else
+ {
+ foreach
($GLOBALS['sitemgr_info']['sitelanguages'] as $lang)
+ {
+ if
(in_array($lang,$availablelangsforcat))
+ {
+ return
$this->catbo->getCategory($cat_id,$lang);
+ }
+ }
+ }
+ //fall back to a category in "default" lang
+ return $this->catbo->getCategory($cat_id);
+ }
+
+ function getpagewrapper($page_id)
+ {
+ $availablelangsforpage =
$this->pages_bo->getlangarrayforpage($page_id);
+ if
(in_array($GLOBALS['sitemgr_info']['userlang'],$availablelangsforpage))
+ {
+ return
$this->pages_bo->GetPage($page_id,$GLOBALS['sitemgr_info']['userlang']);
+ }
+ else
+ {
+ foreach
($GLOBALS['sitemgr_info']['sitelanguages'] as $lang)
+ {
+ if
(in_array($lang,$availablelangsforpage))
+ {
+ return
$this->pages_bo->GetPage($page_id,$lang);
+ }
+ }
+ }
+ //fall back to a page in "default" lang
+ return $this->pages_bo->GetPage($page_id);
+ }
+
+ function get_themesel()
+ {
+ $theme = $sitemgr_info['themesel'];
+
+ if ( isset($_GET['page_name']) && $_GET['page_name'] )
+ {
+ $page =
$GLOBALS['Common_BO']->pages->getPage($GLOBALS['Common_BO']->pages->so->PageToID($_GET['page_name'])
);
+ if ( isset($page->cat_id) && $page->cat_id )
+ {
+ $cat =
$GLOBALS['Common_BO']->cats->getCategory($page->cat_id);
+ if ( isset($cat->cat_tpl) &&
$cat->cat_tpl )
+ {
+ return $cat->cat_tpl;
+ }
+ }
+ }
+ elseif ( isset($_GET['category_id']) &&
$_GET['category_id'] )
+ {
+ $cat =
$GLOBALS['Common_BO']->cats->getCategory($_GET['category_id']);
+ if ( isset($cat->cat_tpl) && $cat->cat_tpl )
+ {
+ return $cat->cat_tpl;
+ }
+ }
+ elseif ( isset($_GET['page_id']) && $_GET['page_id'])
+ {
+ $page =
$GLOBALS['Common_BO']->pages->getPage($_GET['page_id']);
+ if ( isset($page->cat_id) && $page->cat_id )
+ {
+ $cat =
$GLOBALS['Common_BO']->cats->getCategory($page->cat_id);
+ if ( isset($cat->cat_tpl) &&
$cat->cat_tpl )
+ {
+ return $cat->cat_tpl;
+ }
+ }
+ }
+ elseif (isset($_GET['index']))
+ {
+ //do nothing
+ }
+ elseif (isset($_GET['toc']))
+ {
+ //do nothing
+ }
+ else
+ {
+ if ($sitemgr_info['home_page_id'])
+ {
+ $page =
$GLOBALS['Common_BO']->pages->getPage($sitemgr_info['home_page_id']);
+ if ( isset($page->cat_id) &&
$page->cat_id )
+ {
+ $cat =
$GLOBALS['Common_BO']->cats->getCategory($page->cat_id);
+ if ( isset($cat->cat_tpl) &&
$cat->cat_tpl )
+ {
+ return $cat->cat_tpl;
+ }
+ }
+ }
+ }
+ return $theme;
+ }
+
+ function loadPage($page_id)
+ {
+ global $page;
+ $page = $this->getpagewrapper($page_id);
+ }
+
+ function loadIndex()
+ {
+ global $page;
+ $page->title = lang('Site Index');
+ $page->subtitle = '';
+ $page->index = True;
+ $page->block = CreateObject('sitemgr.Block_SO',True);
+ $page->block->module_name = 'index';
+ $page->block->module_id =
$GLOBALS['Common_BO']->modules->getmoduleid('index');
+ $page->block->view = SITEMGR_VIEWABLE_EVERBODY;
+ $page->block->status = SITEMGR_STATE_PUBLISH;
+ $page->cat_id =
$GLOBALS['Common_BO']->current_site['site_id'];
+ return true;
+ }
+
+ function getIndex($showhidden=true, $rootonly=false)
+ {
+ $cats = $this->getCatLinks(0,!$rootonly);
+ $index = array();
+
+ if (count($cats)>0)
+ {
+ reset($cats);
+ $content = "\n".'<ul>';
+ while(list($cat_id,$cat) = each($cats))
+ {
+ $pages =
$this->getPageLinks($cat_id,$showhidden);
+ if (count($pages)>0)
+ {
+ foreach($pages as $link)
+ {
+ $index[] = array(
+
'catname'=>$cat['name'],
+
'catdepth'=>$cat['depth'],
+
'catlink'=>$cat['link'],
+
'catdescrip'=>$cat['description'],
+
'pagename'=>$link['name'],
+
'pagelink'=>$link['link'],
+
'pagetitle'=>$link['title'],
+
'pagesubtitle'=>$link['subtitle']
+ );
+ }
+ }
+ else
+ {
+ $index[] = array(
+ 'catname'=>$cat['name'],
+
'catdepth'=>$cat['depth'],
+
'catdescrip'=>$cat['description'],
+ 'catlink'=>$cat['link'],
+ 'pagelink'=>lang('No
pages available')
+ );
+ }
+ }
+ }
+ return $index;
+ }
+
+ function loadTOC($category_id=false)
+ {
+ global $page;
+
+ $page->title = lang('Table of Contents');
+ $page->subtitle = '';
+ $page->toc = True;
+ $page->cat_id = $category_id ? $category_id :
CURRENT_SITE_ID;
+ $page->block = CreateObject('sitemgr.Block_SO',True);
+ $page->block->module_name = 'toc';
+ $page->block->arguments = array('category_id' =>
$category_id);
+ $page->block->module_id =
$GLOBALS['Common_BO']->modules->getmoduleid('toc');
+ $page->block->view = SITEMGR_VIEWABLE_EVERBODY;
+ $page->block->state = SITEMGR_STATE_PUBLISH;
+ return true;
+ }
+
+ function getPageLinks($category_id, $showhidden=true)
+ {
+ $pages=$this->pages_bo->getPageIDList($category_id);
+ foreach($pages as $page_id)
+ {
+ $page=$this->getpagewrapper($page_id);
+ if ($showhidden || !$page->hidden)
+ {
+ $pglinks[$page_id] = array(
+ 'name'=>$page->name,
+ 'link'=>'<a
href="'.sitemgr_link('page_name='.$page->name).'">'.$page->title.'</a>',
+ 'title'=>$page->title,
+ 'subtitle'=>$page->subtitle
+ );
+ }
+ }
+ return $pglinks;
+ }
+
+ function getCatLinks($cat_id=0,$recurse=true)
+ {
+ $catlinks = array();
+ $cat_list =
$this->catbo->getpermittedcatsRead($cat_id,$recurse);
+ foreach($cat_list as $cat_id)
+ {
+ $category = $this->getcatwrapper($cat_id);
+ $catlinks[$cat_id] = array(
+ 'name'=>$category->name,
+ 'link'=>'<a
href="'.sitemgr_link('category_id='.$cat_id).'">'.$category->name.'</a>',
+ 'description'=>$category->description,
+ 'depth'=>$category->depth
+ );
+ }
+ return $catlinks;
+ }
+
+ //like $GLOBALS['phpgw']->common->getPreferredLanguage,
+ //but compares languages accepted by the user
+ //to the languages the website is configured for
+ //instead of the languages installed in phpgroupware
+ function setsitemgrPreferredLanguage()
+ {
+ //since there are lang calls in the API, and the first
lang call builds $GLOBAL['lang'], wet have to unset it, if
+ //the change of
$GLOBALS['phpgw_info']['user']['preferences']['common']['lang'] should have any
effect.
+ //is there a more efficient way to do the same thing?
+ unset($GLOBALS['lang']);
+ $supportedLanguages =
$GLOBALS['sitemgr_info']['sitelanguages'] ?
$GLOBALS['sitemgr_info']['sitelanguages'] : array('en');
+ $postlang = trim($_GET['lang']);
+ if ($postlang &&
in_array($postlang,$supportedLanguages))
+ {
+
$GLOBALS['phpgw_info']['user']['preferences']['common']['lang'] = $postlang;
+ $GLOBALS['sitemgr_info']['userlang'] =
$postlang;
+
$GLOBALS['phpgw']->session->appsession('language','sitemgr-site',$postlang);
+ return;
+ }
+
+ $sessionlang =
$GLOBALS['phpgw']->session->appsession('language','sitemgr-site');
+ if ($sessionlang)
+ {
+
$GLOBALS['phpgw_info']['user']['preferences']['common']['lang'] = $sessionlang;
+ $GLOBALS['sitemgr_info']['userlang'] =
$sessionlang;
+ return;
+ }
+
+ $client_langs = split('[,;]',
$_SERVER['HTTP_ACCEPT_LANGUAGE']);
+ if(is_array($client_langs))
+ {
+ foreach($client_langs as $lang)
+ {
+ if(strlen($lang) != 2)
+ {
+ list($lang) = explode('-',
$lang);
+ }
+ if(in_array($lang, $supportedLanguages))
+ {
+
$GLOBALS['phpgw_info']['user']['preferences']['common']['lang'] = $lang;
+
$GLOBALS['sitemgr_info']['userlang'] = $lang;
+
$GLOBALS['phpgw']->session->appsession('language','sitemgr-site',$lang);
+ return;
+ }
+ }
+ }
+
+ if ($this->isuser)
+ {
+ $userlang =
$GLOBALS['phpgw_info']['user']['preferences']['common']['lang'];
+ if (in_array($userlang,$supportedLanguages))
+ {
+ //we do not touch
$GLOBALS['phpgw_info']['user']['preferences']['common']['lang'] if
+ //the user is registered and his lang
preference is supported by the website,
+ //but save it to the appsession for quicker
retrieval
+
$GLOBALS['phpgw']->session->appsession('language','sitemgr-site',$userlang);
+ $GLOBALS['sitemgr_info']['userlang'] =
$userlang;
+ return;
+ }
+ }
+
+ // create a array of languages the user is accepting
+ $userLanguages =
explode(',',$GLOBALS['HTTP_ACCEPT_LANGUAGE']);
+
+ // find usersupported language
+ while (list($key,$value) = each($userLanguages))
+ {
+ // remove everything behind '-' example: de-de
+ $value = trim($value);
+ $pieces = explode('-', $value);
+ $value = $pieces[0];
+ //print "current lang $value<br>";
+ if (in_array($value,$supportedLanguages))
+ {
+ $browserlang = $value;
+ break;
+ }
+ }
+
+ // no usersupported language found -> return the first
entry of sitelanguages
+ if (empty($browserlang))
+ {
+ $browserlang = $supportedLanguages[0];
+ }
+
+
$GLOBALS['phpgw_info']['user']['preferences']['common']['lang'] = $browserlang;
+ $GLOBALS['sitemgr_info']['userlang'] = $browserlang;
+
$GLOBALS['phpgw']->session->appsession('language','sitemgr-site',$browserlang);
+ }
+
+ function getmode()
+ {
+ if ($this->isuser)
+ {
+ $postmode = $_GET['administration']['mode'];
+ if ($postmode)
+ {
+
$GLOBALS['phpgw']->session->appsession('mode','sitemgr-site',$postmode);
+ return $postmode;
+ }
+ $sessionmode =
$GLOBALS['phpgw']->session->appsession('mode','sitemgr-site');
+ if($sessionmode)
+ {
+ return $sessionmode;
+ }
+ }
+ return 'Production';
+ }
+ }
+?>
Index: sitemgr/sitemgr-site/index.php
diff -u sitemgr/sitemgr-site/index.php:1.7.2.2.4.1
sitemgr/sitemgr-site/index.php:1.7.2.2.4.2
--- sitemgr/sitemgr-site/index.php:1.7.2.2.4.1 Sat Nov 12 13:15:38 2005
+++ sitemgr/sitemgr-site/index.php Mon Mar 27 13:13:24 2006
@@ -8,7 +8,7 @@
* Free Software Foundation; either version 2 of the License, or (at
your *
* option) any later version.
*
\**************************************************************************/
- /* $Id: index.php,v 1.7.2.2.4.1 2005/11/12 13:15:38 skwashd Exp $ */
+ /* $Id: index.php,v 1.7.2.2.4.2 2006/03/27 13:13:24 skwashd Exp $ */
$GLOBALS['phpgw_info']['flags'] = array
(
@@ -43,6 +43,7 @@
$sitemgr_info =
array_merge($sitemgr_info,$Common_BO->sites->current_site);
$sitemgr_info['sitelanguages'] =
explode(',',$sitemgr_info['site_languages']);
$objbo->setsitemgrPreferredLanguage();
+ $sitemgr_info['themesel'] = $objbo->get_themesel();
$objui = new ui;
$page = CreateObject('sitemgr.Page_SO');
@@ -52,7 +53,7 @@
$objui->displayPageByName($_GET['page_name']);
}
elseif ( isset($_GET['category_id']) && $_GET['category_id'] )
- {
+ {
$cat = $Common_BO->cats->getCategory($_GET['category_id']);
if ( isset($cat->def_page) && $cat->def_page )
{
@@ -89,6 +90,7 @@
$objui->displayIndex();
}
}
+
if (DEBUG_TIMER)
{
$GLOBALS['debug_timer_stop'] = perfgetmicrotime();
Index: sitemgr/templates/default/edit_category.tpl
diff -u sitemgr/templates/default/edit_category.tpl:1.6.2.2.4.1
sitemgr/templates/default/edit_category.tpl:1.6.2.2.4.2
--- sitemgr/templates/default/edit_category.tpl:1.6.2.2.4.1 Sat Nov 12
13:15:38 2005
+++ sitemgr/templates/default/edit_category.tpl Mon Mar 27 13:13:24 2006
@@ -1,98 +1,158 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
-<head></head>
-<body>
-<form method="post">
-<input type="hidden" name="inputcatid" value="{cat_id}" />
-<input type="hidden" name="inputparentold" value="{old_parent}" />
-<table align="center" border ="0" width="80%" cellpadding="5" cellspacing="0">
- <tr>
- <td align="center" colspan="2"><u><b>{add_edit}</b></u></td>
- </tr>
- <tr>
- <td align="center" colspan="2"><font size="2"
color="#FF0000"><b> {message}</b></font></td>
- </tr>
- <tr>
- <td colspan="2"><b><u>{lang_basic}:</u></b></td>
- </tr>
- <tr>
- <td>{lang_catname}:</td>
- <td><input type="text" name="inputcatname"
value="{catname}"></td>
- </tr>
- <tr>
- <td>{lang_catsort}:</td>
- <td><input type="text" name="inputsortorder"
value="{sort_order}"></td>
- </tr>
- <tr>
- <td>{lang_catparent}:</td>
- <td>{parent_dropdown}</td>
- </tr>
- <tr>
- <td>{lang_catdesc}:</td>
- <td><textarea ROWS="3" COLS="50"
name="inputcatdesc">{catdesc}</textarea></td>
- </tr>
- <tr>
- <td>{lang_state}:</td>
- <td><select name="inputstate">{stateselect}</select></td>
- </tr>
- <tr>
- <td>{lang_default_page}:</td>
- <td><select name="def_page">{def_page}</select></td>
- </tr>
- <tr>
- <td colspan="2"><input name="inputgetparentpermissions"
type="checkbox">{lang_getparentpermissions}</td>
- </tr>
- <tr>
- <td colspan="2"><input name="inputapplypermissionstosubs"
type="checkbox">{lang_applypermissionstosubs}</td>
- </tr>
- <tr>
- <td colspan="2"><b><u>{lang_groupaccess}</u></b></td>
- </tr>
- <tr>
- <td colspan="2">
- <table align="center" border="0" width="80%"
cellpadding="2" cellspacing="2">
- <tr>
- <td align="center"
width="33%"><u>{lang_groupname}</u></td>
- <td align="center"
width="33%"><u>{lang_readperm}</u></td>
- <td align="center"
width="33%"><u>{lang_writeperm}</u><br>({lang_implies})</td>
- </tr>
- <!-- BEGIN GroupBlock -->
- <tr>
- <td align="center" bgcolor="dddddd"
width="33%">{groupname}</td>
- <td align="center" bgcolor="dddddd"
width="33%"><input type="checkbox" {checkedgroupread}
name="inputgroupaccessread[i{group_id}][read]" value="checked"></td>
- <td align="center" bgcolor="dddddd"
width="33%"><input type="checkbox" {checkedgroupwrite}
name="inputgroupaccesswrite[i{group_id}][write]" value="checked"></td>
- </tr>
- <!-- END GroupBlock -->
- </table>
- </td>
- </tr>
- <tr>
- <td colspan="2"><b><u>{lang_useraccess}</u></b></td>
- </tr>
- <td colspan="2">
- <table align="center" border="0" width="80%"
cellpadding="2" cellspacing="2">
- <tr>
- <td align="center"
width="33%"><u>{lang_username}</u></td>
- <td align="center"
width="33%"><u>{lang_readperm}</u></td>
- <td align="center"
width="33%"><u>{lang_writeperm}</u><br>({lang_implies})</td>
- </tr>
- <!-- BEGIN UserBlock -->
- <tr>
- <td bgcolor="dddddd"
align="center">{username}</td>
- <td bgcolor="dddddd"
align="center"><input type="checkbox" {checkeduserread}
name="inputindividualaccessread[i{user_id}][read]" value="checked"></td>
- <td bgcolor="dddddd"
align="center"><input type="checkbox" {checkeduserwrite}
name="inputindividualaccesswrite[i{user_id}][write]" value="checked"></td>
- </tr>
- <!-- END UserBlock -->
- </table>
- </td>
- </tr>
- <tr>
- <td colspan="2" align="center">
- <input type="reset" name="reset" value="{lang_reset}">
- <input type="submit" name="btnSave"
value="{lang_save}"> {savelang}
- <input type="reset"
onclick="opener.location.reload();self.close()" value="{lang_done}" />
- </td>
- </tr>
-</table>
-</form>
-</body>
+ <head>
+ <title>{add_edit}</title>
+ <link type="text/css" rel="stylesheet"
href="sitemgr/js/columnlist/columnlist.css" />
+ <script type="text/javascript"
src="sitemgr/js/columnlist/sortabletable.js"></script>
+ <script type="text/javascript"
src="sitemgr/js/columnlist/columnlist.js"></script>
+ <script type="text/javascript">
+
+ var groupList, groupTbl, userList, userTbl;
+ window.onload = function(e)
+ {
+ groupList = new WebFXColumnList();
+ groupTbl =
groupList.bind(document.getElementById('groupcontainer'),
document.getElementById('grouphead'), document.getElementById('groupbody'));
+
+ userList = new WebFXColumnList();
+ userTbl =
userList.bind(document.getElementById('usercontainer'),
document.getElementById('userhead'), document.getElementById('userbody'));
+ }
+ </script>
+ <style type="text/css">
+ body, div, input, p, select, td, textarea
+ {
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ }
+
+ br
+ {
+ clear: left;
+ }
+
+ fieldset input, fieldset label, fieldset select,
fieldset textarea
+ {
+ display: block;
+ float: left;
+ margin-bottom: 10px;
+ width: 250px;
+ }
+
+ fieldset label
+ {
+ display: block;
+ font-weight: bold;
+ width: 150px;
+ }
+ </style>
+ </head>
+ <body>
+ <h1>{add_edit}</h1>
+ <p class="msg">{message}</p>
+ <form method="post">
+
+ <fieldset>
+ <legend>{lang_basic}</legend>
+ <label
for="inputcatname">{lang_catname}:</label>
+ <input type="text" id="inputcatname"
name="inputcatname" value="{catname}" /><br />
+
+ <label
for="inputsortorder">{lang_catsort}:</label>
+ <input type="text" id="inputsortorder"
name="inputsortorder" value="{sort_order}" /><br />
+
+ <label
for="inputparent">{lang_catparent}:</label>
+ {parent_dropdown}<br />
+
+ <label
for="inputcatdesc">{lang_catdesc}:</label>
+ <textarea rows="3" cols="50"
id="inputcatdesc" name="inputcatdesc">{catdesc}</textarea><br />
+
+ <label
for="inputstate">{lang_state}:</label>
+ <select id="inputstate"
name="inputstate">{stateselect}</select><br />
+
+ <label
for="cat_tpl">{lang_cat_tpl}:</label>
+ <select id="cat_tpl"
name="cat_tpl">{cat_tpl}</select><br />
+
+ <label
for="def_page">{lang_default_page}:</label>
+ <select name="def_page"
id="def_page">{def_page}</select><br />
+ </fieldset>
+
+ <h2>{lang_permissions}</h2>
+ <div id="permission_options">
+ <span>{{lang_set_perms}</span>
+ <input name="permissions"
id="permissionsparent" value="parent" type="radio" />
+ <label
for="permissionsparent">{lang_getparentpermissions}</label>
+
+ <input name="permissions"
id="setpermissions" value="set" type="radio" />
+ <label
for="setpermissions">{lang_applypermissionstosubs}</label><br />
+ </div>
+
+ <h3>{lang_groupaccess}</h3>
+ <div id="groupcontainer"
class="webfx-columnlist">
+ <div id="grouphead"
class="webfx-columnlist-head">
+ <table>
+ <tr>
+
<td>{lang_groupname}<img src="sitemgr/templates/default/images/asc.png"/></td>
+ <td
class="permscol">{lang_readperm}<img
src="sitemgr/templates/default/images/asc.png"/></td>
+ <td
class="permscol">{lang_writeperm} [<span title="{lang_implies}">?</span>]<img
src="sitemgr/templates/default/images/asc.png"/></td>
+ </tr>
+ </table>
+ </div>
+ <div id="groupbody"
class="webfx-columnlist-body">
+ <table>
+ <colgroup span="3">
+ <col/>
+ <col/>
+ <col/>
+ </colgroup>
+ <!-- BEGIN GroupBlock
-->
+ <tr class="row_class">
+
<td>{groupname}</td>
+ <td
class="permscol"><input type="checkbox" {checkedgroupread}
name="inputgroupaccessread[i{group_id}][read]" value="checked" /></td>
+ <td
class="permscol"><input type="checkbox" {checkedgroupwrite}
name="inputgroupaccesswrite[i{group_id}][write]" value="checked" /></td>
+ </tr>
+ <!-- END GroupBlock -->
+ </table>
+ </div>
+ </div>
+
+ <h3>{lang_useraccess}</h3>
+ <div id="usercontainer"
class="webfx-columnlist">
+ <div id="userhead"
class="webfx-columnlist-head">
+ <table>
+ <tr>
+
<td>{lang_username}<img src="sitemgr/templates/default/images/asc.png"/></td>
+ <td
class="permscol">{lang_readperm}<img
src="sitemgr/templates/default/images/asc.png"/></td>
+ <td
class="permscol">{lang_writeperm} [<span title="{lang_implies}">?</span>]<img
src="sitemgr/templates/default/images/asc.png"/></td>
+ </tr>
+ </table>
+ </div>
+ <div id="userbody"
class="webfx-columnlist-body">
+ <table>
+ <colgroup span="3">
+ <col/>
+ <col
class="permscol" />
+ <col
class="permscol" />
+ </colgroup>
+ <!-- BEGIN UserBlock -->
+ <tr>
+
<td>{username}</td>
+ <td
class="permscol"><input type="checkbox" {checkeduserread}
name="inputindividualaccessread[i{user_id}][read]" value="checked" /></td>
+ <td
class="permscol"><input type="checkbox" {checkeduserwrite}
name="inputindividualaccesswrite[i{user_id}][write]" value="checked" /></td>
+ </tr>
+ <!-- END UserBlock -->
+ </table>
+ </div>
+ </div>
+ <div>
+ <input type="checkbox"
name="permissionstosubs" id="permissionstosubs" value="1" />
+ <label
for="permissionstosubs">{lang_applypermissionstosubs}</label><br />
+
+ <input type="hidden" name="inputcatid"
value="{cat_id}" />
+ <input type="hidden"
name="inputparentold" value="{old_parent}" />
+
+ <input type="reset" name="reset"
value="{lang_reset}" />
+ <input type="submit" name="btnSave"
value="{lang_save}" /> {savelang}
+ <input type="reset"
onclick="opener.location.reload();self.close()" value="{lang_done}" />
+ </div>
+ </form>
+ </body>
</html>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Phpgroupware-cvs] sitemgr inc/class.Categories_BO.inc.php inc/cla... [skwashd-16-compat],
Dave Hall <=