First step of column management in document tag list. Little debug on js for move up down.
authorcavaliet
Wed, 07 Dec 2011 15:06:35 +0100
changeset 53 22377c9e2eae
parent 52 e804ae133f27
child 54 ec51b9f4695f
First step of column management in document tag list. Little debug on js for move up down.
Controller/WikiTagController.php
Resources/public/css/clickmenu.css
Resources/public/css/wikiTag.css
Resources/public/images/arrow_redir.png
Resources/public/images/cross.png
Resources/public/images/myshadow.png
Resources/public/images/tick.png
Resources/public/js/jquery.clickmenu.js
Resources/public/js/jquery.columnmanager.js
Resources/public/js/jquery.cookie.js
Resources/public/js/wikiTag.js
Resources/views/WikiTag/css.html.twig
Resources/views/WikiTag/documentTags.html.twig
Resources/views/WikiTag/javascript.html.twig
Resources/views/WikiTag/tagTable.html.twig
--- a/Controller/WikiTagController.php	Fri Dec 02 11:31:51 2011 +0100
+++ b/Controller/WikiTagController.php	Wed Dec 07 15:06:35 2011 +0100
@@ -49,7 +49,7 @@
      * @param unknown_type $tags_list
      * @return \Symfony\Bundle\FrameworkBundle\Controller\Response
      */
-    public function addJavascriptAction($tags_list=false)
+    public function addJavascriptAction($tags_list=false, $profile_name=null)
     {
         $cats = $this->getDoctrine()->getRepository('WikiTagBundle:Category')->findOrderedCategories();
         // $cats is {"Label":"Créateur"},{"Label":"Datation"},...
@@ -61,7 +61,13 @@
         }
         // ... so we create is json like {"":""},{"Créateur":"Créateur"},{"Datation":"Datation"},...
         $categories = json_encode($ar);
-        return $this->render('WikiTagBundle:WikiTag:javascript.html.twig', array('categories' => $categories, 'tags_list' => $tags_list));
+        // Management of profiles for the list of displayed columns and reorder tag button
+        $profile_array = $this->container->getParameter("wiki_tag.document_list_profile");
+        $columns_array = null;
+        if($profile_array!=null && $profile_name!=null && $profile_name!=""){
+            $columns_array = $profile_array[$profile_name];
+        }
+        return $this->render('WikiTagBundle:WikiTag:javascript.html.twig', array('categories' => $categories, 'tags_list' => $tags_list, 'columns' => $columns_array));
     }
 
     /**
@@ -100,7 +106,7 @@
         }
         
         $ordered_tags = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->findOrderedTagsForDoc($id_doc);
-        return $this->render('WikiTagBundle:WikiTag:documentTags.html.twig', array('ordered_tags' => $ordered_tags, 'doc_id' => $id_doc, 'profile_name' => $profile_name, 'columns' => $columns_array));
+        return $this->render('WikiTagBundle:WikiTag:documentTags.html.twig', array('ordered_tags' => $ordered_tags, 'doc_id' => $id_doc, 'columns' => $columns_array));
     }
 
     /**
@@ -412,17 +418,11 @@
      * Generic render partial template
      * @param unknown_type $id_doc
      */
-    public function renderDocTags($id_doc, $profile_name)
+    public function renderDocTags($id_doc)
     {
-        // Management of profiles for the list of displayed columns and reorder tag button
-        $profile_array = $this->container->getParameter("wiki_tag.document_list_profile");
-        $columns_array = null;
-        if($profile_array!=null && $profile_name!=null && $profile_name!=""){
-            $columns_array = $profile_array[$profile_name];
-        }
         // Get tags and render the table
         $ordered_tags = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->findOrderedTagsForDoc($id_doc);
-        return $this->render('WikiTagBundle:WikiTag:tagTable.html.twig', array('ordered_tags' => $ordered_tags, 'doc_id' => $id_doc, 'columns' => $columns_array));
+        return $this->render('WikiTagBundle:WikiTag:tagTable.html.twig', array('ordered_tags' => $ordered_tags, 'doc_id' => $id_doc));
     }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/public/css/clickmenu.css	Wed Dec 07 15:06:35 2011 +0100
@@ -0,0 +1,115 @@
+div.cmDiv
+{
+	border: 1px solid black;
+	background-color: #eee;
+}
+.clickMenu
+{
+	margin: 0;
+	padding: 0;
+	cursor: default;
+}
+.clickMenu, .clickMenu ul
+{
+	list-style: none;
+}
+.clickMenu ul
+{
+	margin: 0;
+	padding: 2px;
+	border: 1px solid black;
+	background-color: #eee;
+	min-width: 100px; /* ie doesnt know this :/ */
+	//float: left;/*ie again*/
+	//width: 100%;/*and again*/
+}
+.clickMenu div.outerbox
+{
+	display: none;
+	min-width: 106px; /* firefox produces animation-flickering when the box is bigger than this :/ */
+}
+.clickMenu div.inner
+{
+	//top: 20px; /* for ie */
+	left: 0;
+	margin: 0;
+}
+.clickMenu div.inner div.outerbox
+{
+	margin: 0;
+	left: 98px;
+	//left: 90px; /* for ie */
+	top: -3px;
+}
+.clickMenu li
+{
+	position: relative;
+	padding: 0 20px 0 2px;
+	/*white-space: nowrap; does not really work in ie */
+}
+.clickMenu li.main
+{
+	float: left;
+	padding: 0 10px;
+	background-color: #eee;
+	//height: 20px; /* for ie */
+}
+.clickMenu li.main li
+{
+	z-index: 2;
+	min-width: 78px;
+}
+.clickMenu li.hover
+{
+	z-index: 1 !important; /* the hover z-index has to be below the normal one the hovering items may be drawn over a submenu */
+	background-color: #aaa;
+}
+.clickMenu img.liArrow
+{
+	position: absolute;
+	right: 5px;
+	top: 0.41em;
+}
+.clickMenu a
+{
+	text-decoration: none;
+	color: black;
+	cursor: default;
+}
+/* thats for the shadowbox */
+html>body div.outerbox
+{
+	padding: 0 5px 5px 0;
+}
+html>body div.shadowbox1
+{
+	position: absolute;
+	right: 0;
+	bottom: 5px;
+	width: 5px;
+	height: 100%;
+	background: url(../images/myshadow.png) no-repeat right top;
+}
+html>body div.shadowbox2
+{
+	position: absolute;
+	bottom: 0;
+	right: 5px;
+	height: 5px;
+	width: 100%;
+	background: url(../images/myshadow.png) left bottom;
+}
+html>body div.shadowbox3
+{
+	position: absolute;
+	bottom: 0;
+	right: 0;
+	height: 5px;
+	width: 5px;
+	background: url(../images/myshadow.png) no-repeat right bottom;
+}
+html>body .innerbox
+{
+	margin: 0;
+	display: inherit;
+}
\ No newline at end of file
--- a/Resources/public/css/wikiTag.css	Fri Dec 02 11:31:51 2011 +0100
+++ b/Resources/public/css/wikiTag.css	Wed Dec 07 15:06:35 2011 +0100
@@ -35,6 +35,9 @@
     color: yellow;
     background-color: black;
 }
+.wikitag_hidden {
+    display: none;
+}
 
 /* Styles for images in tables */
 .wikitag_a_icon {
@@ -55,6 +58,9 @@
 .wikitag_wp_dbplink {
     background-image: url('../images/arrow_green_right.png');
 }
+.wikitag_wp_redirlink {
+    background-image: url('../images/arrow_redir.png');
+}
 .wikitag_td_icon {
     width: 16px;
     height: 16px;
@@ -66,6 +72,9 @@
     cursor: n-resize;
     background-image: url('../images/arrow_up_down.png');
 }
+.wikitag_updown_td span {
+    display: none;
+}
 .wikitag_remove_wp_link {
 	cursor: pointer;
     background-image: url('../images/red_cross.png');
@@ -75,6 +84,56 @@
     background-image: url('../images/tag_remove.png');
 }
 
+/* Styles for the list of columns in document tag list*/
+#wikitag_ul_target
+{
+    list-style: none;
+    background-color: #eee;
+}
+#wikitag_ul_target li
+{
+    background-repeat: no-repeat;
+    padding-left: 20px;
+}
+#wikitag_thSelectColumn div.cmDiv
+{
+    display: inline;
+    background: none;
+    border: 0;
+}
+#wikitag_thSelectColumn li.main
+{
+    padding: 0;
+    background: none;
+    width: 100%;
+    text-align: right;
+}
+#wikitag_thSelectColumn li.main li
+{
+    text-align: left;
+    padding-right: 2px;
+}
+#wikitag_thSelectColumn
+{
+    padding-right: 2px;
+    width: 10px;
+}
+#wikitag_ulSelectColumn
+{
+    vertical-align: middle;
+}
+li.wikitag_advon
+{
+    background: url(../images/tick.png) 0 50%;
+}
+li.wikitag_advoff
+{
+    background: url(../images/cross.png) 0 50%;
+}
+.clickMenu div.inner {
+    left: -140px !important;
+}
+
 
 /* styles for the 4 types of STATUS */ 
 .wikitag_null_result {
Binary file Resources/public/images/arrow_redir.png has changed
Binary file Resources/public/images/cross.png has changed
Binary file Resources/public/images/myshadow.png has changed
Binary file Resources/public/images/tick.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/public/js/jquery.clickmenu.js	Wed Dec 07 15:06:35 2011 +0100
@@ -0,0 +1,515 @@
+/* clickMenu - v0.1.6
+ * Copyright (c) 2007 Roman Weich
+ * http://p.sohei.org
+ *
+ * Changelog: 
+ * v 0.1.6 - 2007-09-06
+ *	-fix: having a link in the top-level menu would not open the menu but call the link instead
+ * v 0.1.5 - 2007-07-07
+ *	-change/fix: menu opening/closing now through simple show() and hide() calls - before fadeIn and fadeOut were used for which extra functions to stop a already running animation were created -> they were 
+ *			buggy (not working with the interface plugin in jquery1.1.2 and not working with jquery1.1.3 at all) and now removed
+ *	-change: removed option: fadeTime
+ *	-change: now using the bgiframe plugin for adding iframes in ie6 when available
+ * v 0.1.4 - 2007-03-20
+ *	-fix: the default options were overwritten by the context related options
+ *	-fix: hiding a submenu all hover- and click-events were unbound, even the ones not defined in this plugin - unbinding should work now
+ * v 0.1.3 - 2007-03-13
+ *	-fix: some display problems ie had when no width was set on the submenu, so on ie the width for each submenu will be explicitely set
+ *	-fix: the fix to the ie-width-problem is a fix to the "ie does not support css min-width stuff" problem too which displayed some submenus too narrow (it looked just not right)
+ *	-fix: some bugs, when user the was too fast with the mouse
+ * v 0.1.2 - 2007-03-11
+ *	-change: made a lot changes in the traversing routines to speed things up (having better memory usage now as well)
+ *	-change: added $.fn.clickMenu.setDefaults() for setting global defaults
+ *	-fix: hoverbug when a main menu item had no submenu
+ *	-fix: some bugs i found while rewriting most of the stuff
+ * v 0.1.1 - 2007-03-04
+ *	-change: the width of the submenus is no longer fixed, its set in the plugin now
+ *	-change: the submenu-arrow is now an img, not the background-img of the list element - that allows better positioning, and background-changes on hover (you have to set the image through the arrowSrc option)
+ *	-fix: clicking on a clickMenu while another was already open, didn't close the open one
+ *	-change: clicking on the open main menu item will close it
+ *	-fix: on an open menu moving the mouse to a main menu item and moving it fastly elsewere hid the whole menu
+ * v 0.1.0 - 2007-03-03
+ */
+
+(function($)
+{
+	var defaults = {
+		onClick: function(){
+			$(this).find('>a').each(function(){
+				if ( this.href )
+				{
+					window.location = this.href;
+				}
+			});
+		},
+		arrowSrc: '',
+		subDelay: 300,
+		mainDelay: 10
+	};
+
+	$.fn.clickMenu = function(options) 
+	{
+		var shown = false;
+		var liOffset = ( ($.browser.msie) ? 4 : 2 );
+
+		var settings = $.extend({}, defaults, options);
+
+		var hideDIV = function(div, delay)
+		{
+			//a timer running to show the div?
+			if ( div.timer && !div.isVisible )
+			{
+				clearTimeout(div.timer);
+			}
+			else if (div.timer)
+			{
+				return; //hide-timer already running
+			}
+			if ( div.isVisible )
+			{
+				div.timer = setTimeout(function()
+				{
+					//remove events
+					$(getAllChilds(getOneChild(div, 'UL'), 'LI')).unbind('mouseover', liHoverIn).unbind('mouseout', liHoverOut).unbind('click', settings.onClick);
+					//hide it
+					$(div).hide();
+					div.isVisible = false;
+					div.timer = null;
+				}, delay);
+			}
+		};
+
+		var showDIV = function(div, delay)
+		{
+			if ( div.timer )
+			{
+				clearTimeout(div.timer);
+			}
+			if ( !div.isVisible )
+			{
+				div.timer = setTimeout(function()
+				{
+					//check if the mouse is still over the parent item - if not dont show the submenu
+					if ( !checkClass(div.parentNode, 'hover') )
+					{
+						return;
+					}
+					//assign events to all div>ul>li-elements
+					$(getAllChilds(getOneChild(div, 'UL'), 'LI')).mouseover(liHoverIn).mouseout(liHoverOut).click(settings.onClick);
+					//positioning
+					if ( !checkClass(div.parentNode, 'main') )
+					{
+						$(div).css('left', div.parentNode.offsetWidth - liOffset);
+					}
+					//show it
+					div.isVisible = true; //we use this over :visible to speed up traversing
+					$(div).show();
+					if ( $.browser.msie ) //fixing a display-bug in ie6 and adding min-width
+					{
+						var cW = $(getOneChild(div, 'UL')).width();
+						if ( cW < 100 )
+						{
+							cW = 100;
+						}
+						$(div).css('width', cW);
+					}
+					div.timer = null;
+				}, delay);
+			}
+		};
+
+		//same as hover.handlehover in jquery - just can't use hover() directly - need the ability to unbind only the one hover event
+		var testHandleHover = function(e)
+		{
+			// Check if mouse(over|out) are still within the same parent element
+			var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
+			// Traverse up the tree
+			while ( p && p != this )
+			{
+				try
+				{ 
+					p = p.parentNode;
+				}
+				catch(e)
+				{ 
+					p = this;
+				}
+			}
+			// If we actually just moused on to a sub-element, ignore it
+			if ( p == this )
+			{
+				return false;
+			}
+			return true;
+		};
+		
+		var mainHoverIn = function(e)
+		{
+			//no need to test e.target==this, as no child has the same event binded
+			//its possible, that a main menu item still has hover (if it has no submenu) - thus remove it
+			var lis = getAllChilds(this.parentNode, 'LI');
+			var pattern = new RegExp("(^|\\s)hover(\\s|$)");
+			for (var i = 0; i < lis.length; i++)
+			{
+				if ( pattern.test(lis[i].className) )
+				{
+					$(lis[i]).removeClass('hover');
+				}
+			}
+			$(this).addClass('hover');
+			if ( shown )
+			{
+				hoverIn(this, settings.mainDelay);
+			}
+		};
+
+		var liHoverIn = function(e)
+		{
+			if ( !testHandleHover(e) )
+			{
+				return false;
+			}
+			if ( e.target != this )
+			{
+				//look whether the target is a direct child of this (maybe an image)
+				if ( !isChild(this, e.target) )
+				{
+					return;
+				}
+			}
+			hoverIn(this, settings.subDelay);
+		};
+
+		var hoverIn = function(li, delay)
+		{
+			var innerDiv = getOneChild(li, 'DIV');
+			//stop running timers from the other menus on the same level - a little faster than $('>*>div', li.parentNode)
+			var n = li.parentNode.firstChild;
+			for ( ; n; n = n.nextSibling ) 
+			{
+				if ( n.nodeType == 1 && n.nodeName.toUpperCase() == 'LI' )
+				{
+					var div = getOneChild(n, 'DIV');
+					if ( div && div.timer && !div.isVisible ) //clear show-div timer
+					{
+						clearTimeout(div.timer);
+						div.timer = null;
+					}
+				}
+			}
+			//is there a timer running to hide one of the parent divs? stop it
+			var pNode = li.parentNode;
+			for ( ; pNode; pNode = pNode.parentNode ) 
+			{
+				if ( pNode.nodeType == 1 && pNode.nodeName.toUpperCase() == 'DIV' )
+				{
+					if (pNode.timer)
+					{
+						clearTimeout(pNode.timer);
+						pNode.timer = null;
+						$(pNode.parentNode).addClass('hover');
+					}
+				}
+			}
+			//highlight the current element
+			$(li).addClass('hover');
+			//is the submenu already visible?
+			if ( innerDiv && innerDiv.isVisible )
+			{
+				//hide-timer running?
+				if ( innerDiv.timer )
+				{
+					clearTimeout(innerDiv.timer);
+					innerDiv.timer = null;
+				}
+				else
+				{
+					return;
+				}
+			}
+			//hide all open menus on the same level and below and unhighlight the li item (but not the current submenu!)
+			$(li.parentNode.getElementsByTagName('DIV')).each(function(){
+				if ( this != innerDiv && this.isVisible )
+				{
+					hideDIV(this, delay);
+					$(this.parentNode).removeClass('hover');
+				}
+			});
+			//show the submenu, if there is one
+			if ( innerDiv )
+			{
+				showDIV(innerDiv, delay);
+			}
+		};
+
+		var liHoverOut = function(e)
+		{
+			if ( !testHandleHover(e) )
+			{
+				return false;
+			}
+			if ( e.target != this )
+			{
+				if ( !isChild(this, e.target) ) //return only if the target is no direct child of this
+				{
+					return;
+				}
+			}
+			//remove the hover from the submenu item, if the mouse is hovering out of the menu (this is only for the last open (levelwise) (sub-)menu)
+			var div = getOneChild(this, 'DIV');
+			if ( !div )
+			{
+				$(this).removeClass('hover');
+			}
+			else 
+			{
+				if ( !div.isVisible )
+				{
+					$(this).removeClass('hover');
+				}
+			}
+		};
+
+		var mainHoverOut = function(e)
+		{
+			//no need to test e.target==this, as no child has the same event binded
+			//remove hover
+			var div = getOneChild(this, 'DIV');
+			var relTarget = e.relatedTarget || e.toElement; //this is undefined sometimes (e.g. when the mouse moves out of the window), so dont remove hover then
+			var p;
+			if ( !shown )
+			{
+				$(this).removeClass('hover');
+			}
+			else if ( !div && relTarget ) //menuitem has no submenu, so dont remove the hover if the mouse goes outside the menu
+			{
+				p = findParentWithClass(e.target, 'UL', 'clickMenu');
+				if ( p.contains(relTarget))
+				{
+					$(this).removeClass('hover');
+				}
+			}
+			else if ( relTarget )
+			{
+				//remove hover only when moving to anywhere inside the clickmenu
+				p = findParentWithClass(e.target, 'UL', 'clickMenu');
+				if ( !div.isVisible && (p.contains(relTarget)) )
+				{
+					$(this).removeClass('hover');
+				}
+			}
+		};
+
+		var mainClick = function()
+		{
+			var div = getOneChild(this, 'DIV');
+			if ( div && div.isVisible ) //clicked on an open main-menu-item
+			{
+				clean();
+				$(this).addClass('hover');
+			}
+			else
+			{
+				hoverIn(this, settings.mainDelay);
+				shown = true;
+				$(document).bind('mousedown', checkMouse);
+			}
+			return false;
+		};
+
+		var checkMouse = function(e)
+		{
+			//is the mouse inside a clickmenu? if yes, is it an open (the current) one?
+			var vis = false;
+			var cm = findParentWithClass(e.target, 'UL', 'clickMenu');
+			if ( cm )
+			{
+				$(cm.getElementsByTagName('DIV')).each(function(){
+					if ( this.isVisible )
+					{
+						vis = true;
+					}
+				});
+			}
+			if ( !vis )
+			{
+				clean();
+			}
+		};
+
+		var clean = function()
+		{
+			//remove timeout and hide the divs
+			$('ul.clickMenu div.outerbox').each(function(){
+				if ( this.timer )
+				{
+					clearTimeout(this.timer);
+					this.timer = null;
+				}
+				if ( this.isVisible )
+				{
+					$(this).hide();
+					this.isVisible = false;
+				}
+			});
+			$('ul.clickMenu li').removeClass('hover');
+			//remove events
+			$('ul.clickMenu>li li').unbind('mouseover', liHoverIn).unbind('mouseout', liHoverOut).unbind('click', settings.onClick);
+			$(document).unbind('mousedown', checkMouse);
+			shown = false;
+		};
+
+		var getOneChild = function(elem, name)
+		{
+			if ( !elem )
+			{
+				return null;
+			}
+			var n = elem.firstChild;
+			for ( ; n; n = n.nextSibling ) 
+			{
+				if ( n.nodeType == 1 && n.nodeName.toUpperCase() == name )
+				{
+					return n;
+				}
+			}
+			return null;
+		};
+
+		var getAllChilds = function(elem, name)
+		{
+			if ( !elem )
+			{
+				return [];
+			}
+			var r = [];
+			var n = elem.firstChild;
+			for ( ; n; n = n.nextSibling ) 
+			{
+				if ( n.nodeType == 1 && n.nodeName.toUpperCase() == name )
+				{
+					r[r.length] = n;
+				}
+			}
+			return r;
+		};
+
+		var findParentWithClass = function(elem, searchTag, searchClass)
+		{
+			var pNode = elem.parentNode;
+			var pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
+			for ( ; pNode; pNode = pNode.parentNode )
+			{
+				if ( pNode.nodeType == 1 && pNode.nodeName.toUpperCase() == searchTag && pattern.test(pNode.className) )
+				{
+					return pNode;
+				}
+			}
+			return null;
+		};
+		
+		var checkClass = function(elem, searchClass)
+		{
+			var pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
+			if ( pattern.test(elem.className) )
+			{
+				return true;
+			}
+			return false;
+		};
+		
+		var isChild = function(elem, childElem)
+		{
+			var n = elem.firstChild;
+			for ( ; n; n = n.nextSibling ) 
+			{
+				if ( n == childElem )
+				{
+					return true;
+				}
+			}
+			return false;
+		};
+
+	    return this.each(function()
+		{
+			//add .contains() to mozilla - http://www.quirksmode.org/blog/archives/2006/01/contains_for_mo.html
+			if (window.Node && Node.prototype && !Node.prototype.contains)
+			{
+				Node.prototype.contains = function(arg) 
+				{
+					return !!(this.compareDocumentPosition(arg) & 16);
+				};
+			}
+			//add class
+			if ( !checkClass(this, 'clickMenu') )
+			{
+				$(this).addClass('clickMenu');
+			}
+			//add shadows
+			$('ul', this).shadowBox();
+			//ie6? - add iframes
+			if ( $.browser.msie && (!$.browser.version || parseInt($.browser.version) <= 6) )
+			{
+				if ( $.fn.bgiframe )
+				{
+					$('div.outerbox', this).bgiframe();
+				}
+				else
+				{
+					/* thanks to Mark Gibson - http://www.nabble.com/forum/ViewPost.jtp?post=6504414&framed=y */
+					$('div.outerbox', this).append('<iframe style="display:block;position:absolute;top:0;left:0;z-index:-1;filter:mask();' + 
+									'width:expression(this.parentNode.offsetWidth);height:expression(this.parentNode.offsetHeight)"/>');
+				}
+			}
+			//assign events
+			$(this).bind('closemenu', function(){clean();}); //assign closemenu-event, through wich the menu can be closed from outside the plugin
+			//add click event handling, if there are any elements inside the main menu
+			var liElems = getAllChilds(this, 'LI');
+			for ( var j = 0; j < liElems.length; j++ )
+			{
+				if ( getOneChild(getOneChild(getOneChild(liElems[j], 'DIV'), 'UL'), 'LI') ) // >div>ul>li
+				{
+					$(liElems[j]).click(mainClick);
+				}
+			}
+			//add hover event handling and assign classes
+			$(liElems).hover(mainHoverIn, mainHoverOut).addClass('main').find('>div').addClass('inner');
+			//add the little arrow before each submenu
+			if ( settings.arrowSrc )
+			{
+				$('div.inner div.outerbox', this).before('<img src="' + settings.arrowSrc + '" class="liArrow" />');
+			}
+
+			//the floating list elements are destroying the layout..so make it nice again..
+			$(this).wrap('<div class="cmDiv"></div>').after('<div style="clear: both; visibility: hidden;"></div>');
+	    });
+	};
+	$.fn.clickMenu.setDefaults = function(o)
+	{
+		$.extend(defaults, o);
+	};
+})(jQuery);
+
+(function($)
+{
+	$.fn.shadowBox = function() {
+	    return this.each(function()
+		{
+			var outer = $('<div class="outerbox"></div>').get(0);
+			if ( $(this).css('position') == 'absolute' )
+			{
+				//if the child(this) is positioned abolute, we have to use relative positioning and shrink the outerbox accordingly to the innerbox
+				$(outer).css({position:'relative', width:this.offsetWidth, height:this.offsetHeight});
+			}
+			else
+			{
+				//shrink the outerbox
+				$(outer).css('position', 'absolute');
+			}
+			//add the boxes
+			$(this).addClass('innerBox').wrap(outer).
+					before('<div class="shadowbox1"></div><div class="shadowbox2"></div><div class="shadowbox3"></div>');
+	    });
+	};
+})(jQuery);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/public/js/jquery.columnmanager.js	Wed Dec 07 15:06:35 2011 +0100
@@ -0,0 +1,690 @@
+/*
+ * jQuery columnManager plugin
+ * Version: 0.2.5
+ *
+ * Copyright (c) 2007 Roman Weich
+ * http://p.sohei.org
+ *
+ * Dual licensed under the MIT and GPL licenses 
+ * (This means that you can choose the license that best suits your project, and use it accordingly):
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ *
+ * Changelog: 
+ * v 0.2.5 - 2008-01-17
+ *	-change: added options "show" and "hide". with these functions the user can control the way to show or hide the cells
+ *	-change: added $.fn.showColumns() and $.fn.hideColumns which allows to explicitely show or hide any given number of columns
+ * v 0.2.4 - 2007-12-02
+ *	-fix: a problem with the on/off css classes when manually toggling columns which were not in the column header list
+ *	-fix: an error in the createColumnHeaderList function incorectly resetting the visibility state of the columns
+ *	-change: restructured some of the code
+ * v 0.2.3 - 2007-12-02
+ *	-change: when a column header has no text but some html markup as content, the markup is used in the column header list instead of "undefined"
+ * v 0.2.2 - 2007-11-27
+ *	-change: added the ablity to change the on and off CSS classes in the column header list through $().toggleColumns()
+ *	-change: to avoid conflicts with other plugins, the table-referencing data in the column header list is now stored as an expando and not in the class name as before
+ * v 0.2.1 - 2007-08-14
+ *	-fix: handling of colspans didn't work properly for the very first spanning column
+ *	-change: altered the cookie handling routines for easier management
+ * v 0.2.0 - 2007-04-14
+ *	-change: supports tables with colspanned and rowspanned cells now
+ * v 0.1.4 - 2007-04-11
+ *	-change: added onToggle option to specify a custom callback function for the toggling over the column header list
+ * v 0.1.3 - 2007-04-05
+ *	-fix: bug when saving the value in a cookie
+ *	-change: toggleColumns takes a number or an array of numbers as argument now
+ * v 0.1.2 - 2007-04-02
+ * 	-change: added jsDoc style documentation and examples
+ * 	-change: the column index passed to toggleColumns() starts at 1 now (conforming to the values passed in the hideInList and colsHidden options)
+ * v 0.1.1 - 2007-03-30
+ * 	-change: changed hideInList and colsHidden options to hold integer values for the column indexes to be affected
+ *	-change: made the toggleColumns function accessible through the jquery object, to toggle the state without the need for the column header list
+ *	-fix: error when not finding the passed listTargetID in the dom
+ * v 0.1.0 - 2007-03-27
+ */
+
+(function($) 
+{
+	var defaults = {
+		listTargetID : null,
+		onClass : '',
+		offClass : '',
+		hideInList: [],
+		colsHidden: [],
+		saveState: false,
+		onToggle: null,
+		show: function(cell){
+			showCell(cell);
+		},
+		hide: function(cell){
+			hideCell(cell);
+		}
+	};
+	
+	var idCount = 0;
+	var cookieName = 'columnManagerC';
+
+	/**
+	 * Saves the current state for the table in a cookie.
+	 * @param {element} table	The table for which to save the current state.
+	 */
+	var saveCurrentValue = function(table)
+	{
+		var val = '', i = 0, colsVisible = table.cMColsVisible;
+		if ( table.cMSaveState && table.id && colsVisible && $.cookie )
+		{
+			for ( ; i < colsVisible.length; i++ )
+			{
+				val += ( colsVisible[i] == false ) ? 0 : 1;
+			}
+			$.cookie(cookieName + table.id, val, {expires: 9999});
+		}
+	};
+	
+	/**
+	 * Hides a cell.
+	 * It rewrites itself after the browsercheck!
+	 * @param {element} cell	The cell to hide.
+	 */
+	var hideCell = function(cell)
+	{
+		if ( jQuery.browser.msie )
+		{
+			(hideCell = function(c)
+			{
+				c.style.setAttribute('display', 'none');
+			})(cell);
+		}
+		else
+		{
+			(hideCell = function(c)
+			{
+				c.style.display = 'none';
+			})(cell);
+		}
+	};
+
+	/**
+	 * Makes a cell visible again.
+	 * It rewrites itself after the browsercheck!
+	 * @param {element} cell	The cell to show.
+	 */
+	var showCell = function(cell)
+	{
+		if ( jQuery.browser.msie )
+		{
+			(showCell = function(c)
+			{
+				c.style.setAttribute('display', 'block');
+			})(cell);
+		}
+		else
+		{
+			(showCell = function(c)
+			{
+				c.style.display = 'table-cell';
+			})(cell);
+		}
+	};
+
+	/**
+	 * Returns the visible state of a cell.
+	 * It rewrites itself after the browsercheck!
+	 * @param {element} cell	The cell to test.
+	 */
+	var cellVisible = function(cell)
+	{
+		if ( jQuery.browser.msie )
+		{
+			return (cellVisible = function(c)
+			{
+				return c.style.getAttribute('display') != 'none';
+			})(cell);
+		}
+		else
+		{
+			return (cellVisible = function(c)
+			{
+				return c.style.display != 'none';
+			})(cell);
+		}
+	};
+
+	/**
+	 * Returns the cell element which has the passed column index value.
+	 * @param {element} table	The table element.
+	 * @param {array} cells		The cells to loop through.
+	 * @param {integer} col	The column index to look for.
+	 */
+	var getCell = function(table, cells, col)
+	{
+		for ( var i = 0; i < cells.length; i++ )
+		{
+			if ( cells[i].realIndex === undefined ) //the test is here, because rows/cells could get added after the first run
+			{
+				fixCellIndexes(table);
+			}
+			if ( cells[i].realIndex == col )
+			{
+				return cells[i];
+			}
+		}
+		return null;
+	};
+
+	/**
+	 * Calculates the actual cellIndex value of all cells in the table and stores it in the realCell property of each cell.
+	 * Thats done because the cellIndex value isn't correct when colspans or rowspans are used.
+	 * Originally created by Matt Kruse for his table library - Big Thanks! (see http://www.javascripttoolbox.com/)
+	 * @param {element} table	The table element.
+	 */
+	var fixCellIndexes = function(table) 
+	{
+		var rows = table.rows;
+		var len = rows.length;
+		var matrix = [];
+		for ( var i = 0; i < len; i++ )
+		{
+			var cells = rows[i].cells;
+			var clen = cells.length;
+			for ( var j = 0; j < clen; j++ )
+			{
+				var c = cells[j];
+				var rowSpan = c.rowSpan || 1;
+				var colSpan = c.colSpan || 1;
+				var firstAvailCol = -1;
+				if ( !matrix[i] )
+				{ 
+					matrix[i] = []; 
+				}
+				var m = matrix[i];
+				// Find first available column in the first row
+				while ( m[++firstAvailCol] ) {}
+				c.realIndex = firstAvailCol;
+				for ( var k = i; k < i + rowSpan; k++ )
+				{
+					if ( !matrix[k] )
+					{ 
+						matrix[k] = []; 
+					}
+					var matrixrow = matrix[k];
+					for ( var l = firstAvailCol; l < firstAvailCol + colSpan; l++ )
+					{
+						matrixrow[l] = 1;
+					}
+				}
+			}
+		}
+	};
+	
+	/**
+	 * Manages the column display state for a table.
+	 *
+	 * Features:
+	 * Saves the state and recreates it on the next visit of the site (requires cookie-plugin).
+	 * Extracts all headers and builds an unordered(<UL>) list out of them, where clicking an list element will show/hide the matching column.
+	 *
+	 * @param {map} options		An object for optional settings (options described below).
+	 *
+	 * @option {string} listTargetID	The ID attribute of the element the column header list will be added to.
+	 *						Default value: null
+	 * @option {string} onClass		A CSS class that is used on the items in the column header list, for which the column state is visible 
+	 *						Works only with listTargetID set!
+	 *						Default value: ''
+	 * @option {string} offClass		A CSS class that is used on the items in the column header list, for which the column state is hidden.
+	 *						Works only with listTargetID set!
+	 *						Default value: ''
+	 * @option {array} hideInList	An array of numbers. Each column with the matching column index won't be displayed in the column header list.
+	 *						Index starting at 1!
+	 *						Default value: [] (all columns will be included in the list)
+	 * @option {array} colsHidden	An array of numbers. Each column with the matching column index will get hidden by default.
+	 *						The value is overwritten when saveState is true and a cookie is set for this table.
+	 *						Index starting at 1!
+	 *						Default value: []
+	 * @option {boolean} saveState	Save a cookie with the sate information of each column.
+	 *						Requires jQuery cookie plugin.
+	 *						Default value: false
+	 * @option {function} onToggle	Callback function which is triggered when the visibility state of a column was toggled through the column header list.
+	 *						The passed parameters are: the column index(integer) and the visibility state(boolean).
+	 *						Default value: null
+	 *
+	 * @option {function} show		Function which is called to show a table cell.
+	 *						The passed parameters are: the table cell (DOM-element).
+	 *						Default value: a functions which simply sets the display-style to block (visible)
+	 *
+	 * @option {function} hide		Function which is called to hide a table cell.
+	 *						The passed parameters are: the table cell (DOM-element).
+	 *						Default value: a functions which simply sets the display-style to none (invisible)
+	 *
+	 * @example $('#table').columnManager([listTargetID: "target", onClass: "on", offClass: "off"]);
+	 * @desc Creates the column header list in the element with the ID attribute "target" and sets the CSS classes for the visible("on") and hidden("off") states.
+	 *
+	 * @example $('#table').columnManager([listTargetID: "target", hideInList: [1, 4]]);
+	 * @desc Creates the column header list in the element with the ID attribute "target" but without the first and fourth column.
+	 *
+	 * @example $('#table').columnManager([listTargetID: "target", colsHidden: [1, 4]]);
+	 * @desc Creates the column header list in the element with the ID attribute "target" and hides the first and fourth column by default.
+	 *
+	 * @example $('#table').columnManager([saveState: true]);
+	 * @desc Enables the saving of visibility informations for the columns. Does not create a column header list! Toggle the columns visiblity through $('selector').toggleColumns().
+	 *
+	 * @type jQuery
+	 *
+	 * @name columnManager
+	 * @cat Plugins/columnManager
+	 * @author Roman Weich (http://p.sohei.org)
+	 */
+	$.fn.columnManager = function(options)
+	{
+		var settings = $.extend({}, defaults, options);
+
+		/**
+		 * Creates the column header list.
+		 * @param {element} table	The table element for which to create the list.
+		 */
+		var createColumnHeaderList = function(table)
+		{
+			if ( !settings.listTargetID )
+			{
+				return;
+			}
+			var $target = $('#' + settings.listTargetID);
+			if ( !$target.length )
+			{
+				return;
+			}
+			//select headrow - when there is no thead-element, use the first row in the table
+			var headRow = null;
+			if ( table.tHead && table.tHead.length )
+			{
+				headRow = table.tHead.rows[0];
+			}
+			else if ( table.rows.length )
+			{
+				headRow = table.rows[0];
+			}
+			else
+			{
+				return; //no header - nothing to do
+			}
+			var cells = headRow.cells;
+			if ( !cells.length )
+			{
+				return; //no header - nothing to do
+			}
+			//create list in target element
+			var $list = null;
+			if ( $target.get(0).nodeName.toUpperCase() == 'UL' )
+			{
+				$list = $target;
+			}
+			else
+			{
+				$list = $('<ul></ul>');
+				$target.append($list);
+			}
+			var colsVisible = table.cMColsVisible;
+			//create list elements from headers
+			for ( var i = 0; i < cells.length; i++ )
+			{
+				if ( $.inArray(i + 1, settings.hideInList) >= 0 )
+				{
+					continue;
+				}
+				colsVisible[i] = ( colsVisible[i] !== undefined ) ? colsVisible[i] : true;
+				var text = $(cells[i]).text(), 
+					addClass;
+				if ( !text.length )
+				{
+					text = $(cells[i]).html();
+					if ( !text.length ) //still nothing?
+					{
+						text = 'undefined';
+					}
+				}
+				if ( colsVisible[i] && settings.onClass )
+				{
+					addClass = settings.onClass;
+				}
+				else if ( !colsVisible[i] && settings.offClass )
+				{
+					addClass = settings.offClass;
+				}
+				var $li = $('<li class="' + addClass + '">' + text + '</li>').click(toggleClick);
+				$li[0].cmData = {id: table.id, col: i};
+				$list.append($li);
+			}
+			table.cMColsVisible = colsVisible;
+		};
+
+		/**
+		 * called when an item in the column header list is clicked
+		 */
+		var toggleClick = function()
+		{
+			//get table id and column name
+			var data = this.cmData;
+			if ( data && data.id && data.col >= 0 )
+			{
+				var colNum = data.col, 
+					$table = $('#' + data.id);
+				if ( $table.length )
+				{
+					$table.toggleColumns([colNum + 1], settings);
+					//set the appropriate classes to the column header list
+					var colsVisible = $table.get(0).cMColsVisible;
+					if ( settings.onToggle )
+					{
+						settings.onToggle.apply($table.get(0), [colNum + 1, colsVisible[colNum]]);
+					}
+				}
+			}
+		};
+
+		/**
+		 * Reads the saved state from the cookie.
+		 * @param {string} tableID	The ID attribute from the table.
+		 */
+		var getSavedValue = function(tableID)
+		{
+			var val = $.cookie(cookieName + tableID);
+			if ( val )
+			{
+				var ar = val.split('');
+				for ( var i = 0; i < ar.length; i++ )
+				{
+					ar[i] &= 1;
+				}
+				return ar;
+			}
+			return false;
+		};
+
+        return this.each(function()
+        {
+			this.id = this.id || 'jQcM0O' + idCount++; //we need an id for the column header list stuff
+			var i, 
+				colsHide = [], 
+				colsVisible = [];
+			//fix cellIndex values
+			fixCellIndexes(this);
+			//some columns hidden by default?
+			if ( settings.colsHidden.length )
+			{
+				for ( i = 0; i < settings.colsHidden.length; i++ )
+				{
+					colsVisible[settings.colsHidden[i] - 1] = true;
+					colsHide[settings.colsHidden[i] - 1] = true;
+				}
+			}
+			//get saved state - and overwrite defaults
+			if ( settings.saveState )
+			{
+				var colsSaved = getSavedValue(this.id);
+				if ( colsSaved && colsSaved.length )
+				{
+					for ( i = 0; i < colsSaved.length; i++ )
+					{
+						colsVisible[i] = true;
+						colsHide[i] = !colsSaved[i];
+					}
+				}
+				this.cMSaveState = true;
+			}
+			//assign initial colsVisible var to the table (needed for toggling and saving the state)
+			this.cMColsVisible = colsVisible;
+			//something to hide already?
+			if ( colsHide.length )
+			{
+				var a = [];
+				for ( i = 0; i < colsHide.length; i++ )
+				{
+					if ( colsHide[i] )
+					{
+						a[a.length] = i + 1;
+					}
+				}
+				if ( a.length )
+				{
+					$(this).toggleColumns(a);
+				}
+			}
+			//create column header list
+			createColumnHeaderList(this);
+        }); 
+	};
+
+	/**
+	 * Shows or hides table columns.
+	 *
+	 * @param {integer|array} columns		A number or an array of numbers. The display state(visible/hidden) for each column with the matching column index will get toggled.
+	 *							Column index starts at 1! (see the example)
+	 *
+	 * @param {map} options		An object for optional settings to handle the on and off CSS classes in the column header list (options described below).
+	 * @option {string} listTargetID	The ID attribute of the element with the column header.
+	 * @option {string} onClass		A CSS class that is used on the items in the column header list, for which the column state is visible 
+	 * @option {string} offClass		A CSS class that is used on the items in the column header list, for which the column state is hidden.
+	 * @option {function} show		Function which is called to show a table cell.
+	 * @option {function} hide		Function which is called to hide a table cell.
+	 *
+	 * @example $('#table').toggleColumns([2, 4], {hide: function(cell) { $(cell).fadeOut("slow"); }});
+	 * @before <table id="table">
+	 *   			<thead>
+	 *   				<th>one</th
+	 *   				<th>two</th
+	 *   				<th>three</th
+	 *   				<th>four</th
+	 *   			</thead>
+	 * 		   </table>
+	 * @desc Toggles the visible state for the columns "two" and "four". Use custom function to fade the cell out when hiding it.
+	 *
+	 * @example $('#table').toggleColumns(3, {listTargetID: 'theID', onClass: 'vis'});
+	 * @before <table id="table">
+	 *   			<thead>
+	 *   				<th>one</th
+	 *   				<th>two</th
+	 *   				<th>three</th
+	 *   				<th>four</th
+	 *   			</thead>
+	 * 		   </table>
+	 * @desc Toggles the visible state for column "three" and sets or removes the CSS class 'vis' to the appropriate column header according to the visibility of the column.
+	 *
+	 * @type jQuery
+	 *
+	 * @name toggleColumns
+	 * @cat Plugins/columnManager
+	 * @author Roman Weich (http://p.sohei.org)
+	 */
+	$.fn.toggleColumns = function(columns, cmo)
+	{
+        return this.each(function() 
+        {
+			var i, toggle, di, 
+				rows = this.rows, 
+				colsVisible = this.cMColsVisible;
+
+			if ( !columns )
+				return;
+
+			if ( columns.constructor == Number )
+				columns = [columns];
+
+			if ( !colsVisible )
+				colsVisible = this.cMColsVisible = [];
+
+			//go through all rows in the table and hide the cells
+			for ( i = 0; i < rows.length; i++ )
+			{
+				var cells = rows[i].cells;
+				for ( var k = 0; k < columns.length; k++ )
+				{
+					var col = columns[k] - 1;
+					if ( col >= 0 )
+					{
+						//find the cell with the correct index
+						var c = getCell(this, cells, col);
+						//cell not found - maybe a previous one has a colspan? - search it!
+						if ( !c )
+						{
+							var cco = col;
+							while ( cco > 0 && !(c = getCell(this, cells, --cco)) ) {} //find the previous cell
+							if ( !c )
+							{
+								continue;
+							}
+						}
+						//set toggle direction
+						if ( colsVisible[col] == undefined )//not initialized yet
+						{
+							colsVisible[col] = true;
+						}
+						if ( colsVisible[col] )
+						{
+							toggle = cmo && cmo.hide ? cmo.hide : hideCell;
+							di = -1;
+						}
+						else
+						{
+							toggle = cmo && cmo.show ? cmo.show : showCell;
+							di = 1;
+						}
+						if ( !c.chSpan )
+						{
+							c.chSpan = 0;
+						}
+						//the cell has a colspan - so dont show/hide - just change the colspan
+						if ( c.colSpan > 1 || (di == 1 && c.chSpan && cellVisible(c)) )
+						{
+							//is the colspan even reaching this cell? if not we have a rowspan -> nothing to do
+							if ( c.realIndex + c.colSpan + c.chSpan - 1 < col )
+							{
+								continue;
+							}
+							c.colSpan += di;
+							c.chSpan += di * -1;
+						}
+						else if ( c.realIndex + c.chSpan < col )//a previous cell was found, but doesn't affect this one (rowspan)
+						{
+							continue;
+						}
+						else //toggle cell
+						{
+							toggle(c);
+						}
+					}
+				}
+			}
+			//set the colsVisible var
+			for ( i = 0; i < columns.length; i++ )
+			{
+				this.cMColsVisible[columns[i] - 1] = !colsVisible[columns[i] - 1];
+				//set the appropriate classes to the column header list, if the options have been passed
+				if ( cmo && cmo.listTargetID && ( cmo.onClass || cmo.offClass ) )
+				{
+					var onC = cmo.onClass, offC = cmo.offClass, $li;
+					if ( colsVisible[columns[i] - 1] )
+					{
+						onC = offC;
+						offC = cmo.onClass;
+					}
+					$li = $("#" + cmo.listTargetID + " li").filter(function(){return this.cmData && this.cmData.col == columns[i] - 1;});
+					if ( onC )
+					{
+						$li.removeClass(onC);
+					}
+					if ( offC )
+					{
+						$li.addClass(offC);
+					}
+				}
+			}
+			saveCurrentValue(this);
+		});
+	};
+
+	/**
+	 * Shows all table columns.
+	 * When columns are passed through the parameter only the passed ones become visible.
+	 *
+	 * @param {integer|array} columns		A number or an array of numbers. Each column with the matching column index will become visible.
+	 *							Column index starts at 1!
+	 *
+	 * @param {map} options		An object for optional settings which will get passed to $().toggleColumns().
+	 *
+	 * @example $('#table').showColumns();
+	 * @desc Sets the visibility state of all hidden columns to visible.
+	 *
+	 * @example $('#table').showColumns(3);
+	 * @desc Show column number three.
+	 *
+	 * @type jQuery
+	 *
+	 * @name showColumns
+	 * @cat Plugins/columnManager
+	 * @author Roman Weich (http://p.sohei.org)
+	 */
+	$.fn.showColumns = function(columns, cmo)
+	{
+        return this.each(function() 
+        {
+			var i,
+				cols = [],
+				cV = this.cMColsVisible;
+			if ( cV )
+			{
+				if ( columns && columns.constructor == Number ) 
+					columns = [columns];
+
+				for ( i = 0; i < cV.length; i++ )
+				{
+					//if there were no columns passed, show all - or else show only the columns the user wants to see
+					if ( !cV[i] && (!columns || $.inArray(i + 1, columns) > -1) )
+						cols.push(i + 1);
+				}
+				
+				$(this).toggleColumns(cols, cmo);
+			}
+		});
+	};
+
+	/**
+	 * Hides table columns.
+	 *
+	 * @param {integer|array} columns		A number or an array of numbers. Each column with the matching column index will get hidden.
+	 *							Column index starts at 1!
+	 *
+	 * @param {map} options		An object for optional settings which will get passed to $().toggleColumns().
+	 *
+	 * @example $('#table').hideColumns(3);
+	 * @desc Hide column number three.
+	 *
+	 * @type jQuery
+	 *
+	 * @name hideColumns
+	 * @cat Plugins/columnManager
+	 * @author Roman Weich (http://p.sohei.org)
+	 */
+	$.fn.hideColumns = function(columns, cmo)
+	{
+        return this.each(function() 
+        {
+			var i,
+				cols = columns,
+				cV = this.cMColsVisible;
+			if ( cV )
+			{
+				if ( columns.constructor == Number ) 
+					columns = [columns];
+				cols = [];
+
+				for ( i = 0; i < columns.length; i++ )
+				{
+					if ( cV[columns[i] - 1] || cV[columns[i] - 1] == undefined )
+						cols.push(columns[i]);
+				}
+				
+			}
+			$(this).toggleColumns(cols, cmo);
+		});
+	};
+})(jQuery);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/public/js/jquery.cookie.js	Wed Dec 07 15:06:35 2011 +0100
@@ -0,0 +1,88 @@
+/**
+ * Cookie plugin
+ *
+ * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+
+/**
+ * Create a cookie with the given name and value and other optional parameters.
+ *
+ * @example $.cookie('the_cookie', 'the_value');
+ * @desc Set the value of a cookie.
+ * @example $.cookie('the_cookie', 'the_value', {expires: 7, path: '/', domain: 'jquery.com', secure: true});
+ * @desc Create a cookie with all available options.
+ * @example $.cookie('the_cookie', 'the_value');
+ * @desc Create a session cookie.
+ * @example $.cookie('the_cookie', '', {expires: -1});
+ * @desc Delete a cookie by setting a date in the past.
+ *
+ * @param String name The name of the cookie.
+ * @param String value The value of the cookie.
+ * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
+ * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
+ *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
+ *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
+ *                             when the the browser exits.
+ * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
+ * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
+ * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
+ *                        require a secure protocol (like HTTPS).
+ * @type undefined
+ *
+ * @name $.cookie
+ * @cat Plugins/Cookie
+ * @author Klaus Hartl/klaus.hartl@stilbuero.de
+ */
+
+/**
+ * Get the value of a cookie with the given name.
+ *
+ * @example $.cookie('the_cookie');
+ * @desc Get the value of a cookie.
+ *
+ * @param String name The name of the cookie.
+ * @return The value of the cookie.
+ * @type String
+ *
+ * @name $.cookie
+ * @cat Plugins/Cookie
+ * @author Klaus Hartl/klaus.hartl@stilbuero.de
+ */
+jQuery.cookie = function(name, value, options) {
+    if (typeof value != 'undefined') { // name and value given, set cookie
+        options = options || {};
+        var expires = '';
+        if (options.expires && (typeof options.expires == 'number' || options.expires.toGMTString)) {
+            var date;
+            if (typeof options.expires == 'number') {
+                date = new Date();
+                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
+            } else {
+                date = options.expires;
+            }
+            expires = '; expires=' + date.toGMTString(); // use expires attribute, max-age is not supported by IE
+        }
+        var path = options.path ? '; path=' + options.path : '';
+        var domain = options.domain ? '; domain=' + options.domain : '';
+        var secure = options.secure ? '; secure' : '';
+        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
+    } else { // only name given, get cookie
+        var cookieValue = null;
+        if (document.cookie && document.cookie != '') {
+            var cookies = document.cookie.split(';');
+            for (var i = 0; i < cookies.length; i++) {
+                var cookie = jQuery.trim(cookies[i]);
+                // Does this cookie string begin with the name we want?
+                if (cookie.substring(0, name.length + 1) == (name + '=')) {
+                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+                    break;
+                }
+            }
+        }
+        return cookieValue;
+    }
+};
\ No newline at end of file
--- a/Resources/public/js/wikiTag.js	Fri Dec 02 11:31:51 2011 +0100
+++ b/Resources/public/js/wikiTag.js	Wed Dec 07 15:06:35 2011 +0100
@@ -133,9 +133,9 @@
             $($(row).children()[1]).html("<img src='"+static_url+"/images/indicator.gif'/>");
             rows = table.tBodies[0].rows;
             nb_rows = rows.length;
-            for(var i=1; i<nb_rows; i++){
+            for(var i=0; i<nb_rows; i++){
                 if(rows[i].id==old_order){
-                    new_order = i; // No need to +1 because rows[0] are headers
+                    new_order = i+1;
                     $.ajax({
                         url: tag_up_down_url,
                         type: 'POST',
@@ -157,6 +157,10 @@
         },
         dragHandle: "wikitag_updown_td"
     });
+    // Hide/show column management. We disable the possibility to hide menu (column 14).
+    $('#wikitag_table').columnManager({listTargetID:'wikitag_ul_target', onClass: 'wikitag_advon', offClass: 'wikitag_advoff', hideInList: [14], saveState: true, colsHidden: columsToHide});
+    //create the clickmenu from the target
+    $('#wikitag_ulSelectColumn').clickMenu({onClick: function(){}});
 }
 
 function wikitag_init_datasheet_events()
--- a/Resources/views/WikiTag/css.html.twig	Fri Dec 02 11:31:51 2011 +0100
+++ b/Resources/views/WikiTag/css.html.twig	Wed Dec 07 15:06:35 2011 +0100
@@ -1,3 +1,4 @@
 {# partial display to add the needed CSS #}
+<link rel="stylesheet" href="{{ asset('bundles/wikitag/css/clickmenu.css') }}" type="text/css"/>
 <link rel="stylesheet" href="{{ asset('bundles/wikitag/css/wikiTag.css') }}" type="text/css"/>
 <link rel="stylesheet" href="{{ asset('bundles/wikitag/css/smoothness/jquery-ui-1.8.13.custom.css') }}" type="text/css"/>
--- a/Resources/views/WikiTag/documentTags.html.twig	Fri Dec 02 11:31:51 2011 +0100
+++ b/Resources/views/WikiTag/documentTags.html.twig	Wed Dec 07 15:06:35 2011 +0100
@@ -8,7 +8,7 @@
       <span>Ajouter un tag : <input type="text" name="wikitag_wp_search" id="wikitag_wp_search" size="35" /> <span id="wikitag_ok_search" class="wikitag_hand_cursor"><b>OK</b></span></span>
     </div>
     <input type="hidden" name="wikitag_document_id" value="{{ doc_id }}" id="wikitag_document_id" />
-    <input type="hidden" name="wikitag_document_profile" value="{{ profile_name }}" id="wikitag_document_profile" />
+    <!--input type="hidden" name="wikitag_document_profile" value="profile_name" id="wikitag_document_profile" /-->
 </div>
 <div id="wikitag_table_container" style="float:left; width: 100%">
   {% include 'WikiTagBundle:WikiTag:tagTable.html.twig' %}
--- a/Resources/views/WikiTag/javascript.html.twig	Fri Dec 02 11:31:51 2011 +0100
+++ b/Resources/views/WikiTag/javascript.html.twig	Wed Dec 07 15:06:35 2011 +0100
@@ -6,6 +6,9 @@
 <script type="text/javascript" src="{{ asset('bundles/wikitag/js/jquery.tablednd_0_5.js') }}"></script>
 <script type="text/javascript" src="{{ asset('bundles/wikitag/js/jquery-ui.min.js') }}"></script>
 <script type="text/javascript" src="{{ asset('bundles/wikitag/js/jquery.jeditable.js') }}"></script>
+<script type="text/javascript" src="{{ asset('bundles/wikitag/js/jquery.clickmenu.js') }}"></script>
+<script type="text/javascript" src="{{ asset('bundles/wikitag/js/jquery.cookie.js') }}"></script>
+<script type="text/javascript" src="{{ asset('bundles/wikitag/js/jquery.columnmanager.js') }}"></script>
 <script type="text/javascript" src="{{ asset('bundles/wikitag/js/wikiTag.js') }}" ></script>
 <script type="text/javascript">
 
@@ -25,6 +28,21 @@
     var update_tag_alias_url = "{{ url('wikitag_update_tag_alias') }}";
     var update_tag_category_url = "{{ url('wikitag_update_tag_category') }}";
     var categories_list = '{{ categories|raw }}';
+    // We prepare the list of the columns to hide
+    var columsToHide = [];
+    {% if columns is not null and 'order' not in columns %}columsToHide.push(1);{% endif %}
+    {% if columns is not null and 'id' not in columns %}columsToHide.push(2);{% endif %}
+    {% if columns is not null and 'move_up_down' not in columns %}columsToHide.push(3);{% endif %}
+    {% if columns is not null and 'label' not in columns %}columsToHide.push(4);{% endif %}
+    {% if columns is not null and 'wikipedia_link' not in columns %}columsToHide.push(5);{% endif %}
+    {% if columns is not null and 'wikipedia_permalink' not in columns %}columsToHide.push(6);{% endif %}
+    {% if columns is not null and 'dbpedia_link' not in columns %}columsToHide.push(7);{% endif %}
+    {% if columns is not null and 'category' not in columns %}columsToHide.push(8);{% endif %}
+    {% if columns is not null and 'remove_wikipedia_link' not in columns %}columsToHide.push(9);{% endif %}
+    {% if columns is not null and 'alias' not in columns %}columsToHide.push(10);{% endif %}
+    {% if columns is not null and 'remove_tag_from_list' not in columns %}columsToHide.push(11);{% endif %}
+    {% if columns is not null and 'alternative_label' not in columns %}columsToHide.push(12);{% endif %}
+    {% if columns is not null and 'alternative_wikipedia_url' not in columns %}columsToHide.push(13);{% endif %}
     
     $(document).ready(function(){
         wikitag_init_tags_events();
--- a/Resources/views/WikiTag/tagTable.html.twig	Fri Dec 02 11:31:51 2011 +0100
+++ b/Resources/views/WikiTag/tagTable.html.twig	Wed Dec 07 15:06:35 2011 +0100
@@ -1,92 +1,67 @@
 {# partial display document's tags (table only) #}
   <table id="wikitag_table">
-    <tr class="nodrop nodrag">
-  {% if columns is null or "order" in columns %}
+   <thead>
+   <tr class="nodrop nodrag">
     <th>#</th>
-  {% endif %}
-  {% if columns is null or "move_up_down" in columns %}
-    <th><img src="{{ asset('bundles/wikitag/images/arrow_up_down.png') }}"/></th>
-  {% endif %}
-  {% if columns is null or "id" in columns %}
+    <th class="wikitag_updown_td wikitag_td_icon"><span>Haut Bas</span></th>
     <th>id</th>
-  {% endif %}
-  {% if columns is null or "label" in columns %}
     <th>label</th>
-  {% endif %}
-  {% if columns is null or "wikipedia_link" in columns %}
     <th class="wikitag_text_centered">Lien W</th>
-  {% endif %}
-  {% if columns is null or "wikipedia_permalink" in columns %}
     <th class="wikitag_text_centered">pLien W</th>
-  {% endif %}
-  {% if columns is null or "dbpedia_link" in columns %}
     <th class="wikitag_text_centered">Lien D</th>
-  {% endif %}
-  {% if columns is null or "category" in columns %}
     <th>Catégorie</th>
-  {% endif %}
-  {% if columns is null or "remove_wikipedia_link" in columns %}
-    <th class="wikitag_large_25 wikitag_text_centered">Supprimer<br/>le lien W</th>
-  {% endif %}
-  {% if columns is null or "alias" in columns %}
+    <th class="wikitag_large_25 wikitag_text_centered">Supprimer<br/> le lien W</th>
     <th>Alias</th>
-  {% endif %}
-  {% if columns is null or "remove_tag_from_list" in columns %}
-    <th class="wikitag_large_25 wikitag_text_centered">Retirer le tag</th></tr>
-  {% endif %}
-    {% for t in ordered_tags %}
-        <tr class="imageline {{ cycle(['wikitag_oddline', 'wikitag_evenline'], loop.index) }}" id="{{loop.index}}">
-      {% if columns is null or "order" in columns %}
-        <td>{{loop.index}}</td>
-      {% endif %}
-      {% if columns is null or "move_up_down" in columns %}
-        <td class="wikitag_updown_td wikitag_td_icon wikitag_text_centered"></td>
-      {% endif %}
-      {% if columns is null or "id" in columns %}
-        <td>{{t.tag.id}}</td>
-      {% endif %}
-      {% if columns is null or "label" in columns %}
-        <td class="wikitag_{{t.tag.urlstatustext}} wikipediatag" id="{{t.tag.id}}" >{{t.tag.label}}</td>
-      {% endif %}
-      {% if columns is null or "wikipedia_link" in columns %}
-        <td class="wikitag_text_centered">
-        {% if t.tag.wikipediaurl and t.tag.wikipediaurl != ""  %}
-          <a class="wikitag_a_icon wikitag_wp_link" href="{{t.tag.wikipediaurl}}" target="_blank" />
-        {% else %}
-          <a class="wikitag_a_icon wikitag_wp_nolink" href="http://fr.wikipedia.org/w/index.php?search={{t.tag.label}}" target="_blank"></a>
-        {% endif %}
-        </td>
-      {% endif %}
-      {% if columns is null or "wikipedia_permalink" in columns %}
-        <td class="wikitag_text_centered">
-            {% if t.wikipediarevisionid  %}
-            <a class="wikitag_a_icon wikitag_wp_permalink" href="{{t.wikipediaversionpermalink}}" target="_blank"></a>
-            {% else %}
-            &nbsp;
-            {% endif %}
-        </td>
-      {% endif %}
-      {% if columns is null or "dbpedia_link" in columns %}
-        <td class="wikitag_text_centered">
-            {% if t.tag.dbpediauri and t.tag.dbpediauri != ""  %}
-            <a class="wikitag_a_icon wikitag_wp_dbplink" href="{{t.tag.dbpediauri}}" target="_blank"></a>
-            {% else %}
-            &nbsp;
-            {% endif %}
-        </td>
-      {% endif %}
-      {% if columns is null or "category" in columns %}
-        <td class="wikitag_category" id="{{t.tag.id}}">{% if t.tag.category %}{{ t.tag.category.label }}{% endif %}</td>
-      {% endif %}
-      {% if columns is null or "remove_wikipedia_link" in columns %}
-        <td class="wikitag_text_centered wikitag_td_icon wikitag_remove_wp_link" id="{{t.tag.id}}" alt="{{t.tag.label}}" ></td>
-      {% endif %}
-      {% if columns is null or "alias" in columns %}
-        <td>{% if t.tag.alias %}{{t.tag.alias}}{% endif %}</td>
-      {% endif %}
-      {% if columns is null or "remove_tag_from_list" in columns %}
-        <!--td class="wikitag_text_centered"><img src="{{ asset('bundles/wikitag/images/tag_remove.png') }}" class="wikitag_remove_tag_from_list" id="{{t.tag.id}}" alt="{{t.tag.label}}" /></td-->
-        <td class="wikitag_text_centered wikitag_td_icon wikitag_remove_tag_from_list" id="{{t.tag.id}}" alt="{{t.tag.label}}" ></td></tr>
-      {% endif %}
-    {% endfor %}
+    <th class="wikitag_large_25 wikitag_text_centered">Retirer le tag</th>
+    <th>Label redirigé</th>
+    <th class="wikitag_text_centered">Lien<br/> redirigé</th>
+    <th id="wikitag_thSelectColumn"><ul id="wikitag_ulSelectColumn"><li><img src="{{ asset('bundles/wikitag/images/sort-desc.png') }}" alt="select columns" title="select columns" />
+      <ul id="wikitag_ul_target"></ul></li></ul>
+    </th>
+  </tr>
+  </thead>
+  
+  <tbody>
+  {% for t in ordered_tags %}
+    <tr class="imageline {{ cycle(['wikitag_oddline', 'wikitag_evenline'], loop.index) }}" id="{{loop.index}}">
+      <td>{{loop.index}}</td>
+      <td class="wikitag_updown_td wikitag_td_icon wikitag_text_centered"></td>
+      <td>{{t.tag.id}}</td>
+      <td class="wikitag_{{t.tag.urlstatustext}} wikipediatag" id="{{t.tag.id}}" >{{t.tag.label}}</td>
+      <td class="wikitag_text_centered">
+       {% if t.tag.wikipediaurl and t.tag.wikipediaurl != ""  %}
+        <a class="wikitag_a_icon wikitag_wp_link" href="{{t.tag.wikipediaurl}}" target="_blank" />
+       {% else %}
+        <a class="wikitag_a_icon wikitag_wp_nolink" href="http://fr.wikipedia.org/w/index.php?search={{t.tag.label}}" target="_blank"></a>
+       {% endif %}
+      </td>
+      <td class="wikitag_text_centered">
+       {% if t.wikipediarevisionid  %}
+        <a class="wikitag_a_icon wikitag_wp_permalink" href="{{t.wikipediaversionpermalink}}" target="_blank"></a>
+       {% else %}
+        &nbsp;
+       {% endif %}
+      </td>
+      <td class="wikitag_text_centered">
+       {% if t.tag.dbpediauri and t.tag.dbpediauri != ""  %}
+        <a class="wikitag_a_icon wikitag_wp_dbplink" href="{{t.tag.dbpediauri}}" target="_blank"></a>
+       {% else %}
+        &nbsp;
+       {% endif %}
+      </td>
+      <td class="wikitag_category" id="{{t.tag.id}}">{% if t.tag.category %}{{ t.tag.category.label }}{% endif %}</td>
+      <td class="wikitag_text_centered wikitag_td_icon wikitag_remove_wp_link" id="{{t.tag.id}}" alt="{{t.tag.label}}" ></td>
+      <td>{% if t.tag.alias %}{{t.tag.alias}}{% endif %}</td>
+      <td class="wikitag_text_centered wikitag_td_icon wikitag_remove_tag_from_list" id="{{t.tag.id}}" alt="{{t.tag.label}}" ></td>
+      <td>{% if t.tag.alternativelabel %}{{t.tag.alternativelabel}}{% endif %}</td>
+      <td class="wikitag_text_centered">
+       {% if t.tag.alternativewikipediaurl and t.tag.alternativewikipediaurl != ""  %}
+        <a class="wikitag_a_icon wikitag_wp_redirlink" href="{{t.tag.alternativewikipediaurl}}" target="_blank" />
+       {% endif %}
+      </td>
+      <td>&nbsp;</td>
+    </tr>
+  {% endfor %}
+  </tbody>
   </table>
+