[ Index ]
 

Code source de eZ Publish 3.9.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/design/standard/javascript/popupmenu/ -> ezpopupmenu.js (source)

   1  //
   2  // Created on: <1-Aug-2002 16:45:00 fh>
   3  //
   4  // SOFTWARE NAME: eZ publish
   5  // SOFTWARE RELEASE: 3.9.0
   6  // BUILD VERSION: 17785
   7  // COPYRIGHT NOTICE: Copyright (C) 1999-2006 eZ systems AS
   8  // SOFTWARE LICENSE: GNU General Public License v2.0
   9  // NOTICE: >
  10  //   This program is free software; you can redistribute it and/or
  11  //   modify it under the terms of version 2.0  of the GNU General
  12  //   Public License as published by the Free Software Foundation.
  13  //
  14  //   This program is distributed in the hope that it will be useful,
  15  //   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16  //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17  //   GNU General Public License for more details.
  18  //
  19  //   You should have received a copy of version 2.0 of the GNU General
  20  //   Public License along with this program; if not, write to the Free
  21  //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  22  //   MA 02110-1301, USA.
  23  //
  24  //
  25  
  26  /*! \file ezpopupmenu.js
  27  */
  28  
  29  
  30  /*!
  31    \brief
  32    This javascript provides a very cool and flexible DHTML popupmenu.
  33    In order to use this javascript you must also include ezlibdomsupport.js.
  34  
  35  
  36    Features:
  37    - Multilevel popupmenu
  38    - Supports all major browsers
  39    - All HTML code in template
  40    - Supports context sensitivity for eZ publish through:
  41       - String substitution in the href attribute of menuitems.
  42       - Form submital with string substitution.
  43  
  44    Currenty not supported but possible if requested:
  45    - Dynamic building of menus based on eZ publish content.
  46  
  47   Public interface:
  48  ezpopmenu_showTopLevel - This method opens a new top-level popupmenu.
  49  ezpopmenu_showSubLevel - This menu opens a sublevel popupmenu. It does not hide any parent menus.
  50  ezpopmenu_submitForm - This method is used to activate a form.
  51  ezpopmenu_mouseOver - This method should be called by all menuitems when a mouseover event occurs. It currently hides and submenus that should not be shown.
  52  ez_createAArray - Helper method to create associative arrays. It takes an array with an even number of elements and makes a associate element out of every two array elements.
  53  
  54  In order to use the popupmenu javascript you need to provide:
  55  1. The HTML/CSS structure for you menu(s)
  56  2. The menuArray javascript array containing the configuration of your popupmenu(s).
  57  
  58  eZ publish provides a default template for this purpose. It is located in popupmenu/popup_menu.tpl. You are encouraged to override this file in the siteacess where you want to use the menu.
  59  
  60   1. Setting up the HTML/CSS structure for your popup menu(s).
  61   Your menu should be set up completely with all elements. The following requirements apply:
  62  - The outer element should be a "div".
  63  - The css of the outer div must have the following CSS attributes set:
  64    position: absolute;
  65    z-index: +1;
  66    visibility: hidden;
  67  - The menuitems must be of type "a".
  68  - Both the menu and the menuitems must be given and "id". This id is used in the menuArray to set up that menu/item.
  69  - Each menuitem must call ezpopmenu_mouseOver or one of the methods spawning a metnu on the mouseover event. The name of the enclosing menu must be given as parameter.
  70  - The menus should be defined in the order they will be shown. In other words, the mainmenu first and then any submenus. This is to ensure the correct visible stack order.
  71  
  72  An example example with a menu and a submenu.
  73  
  74   example with a main menu and a submenu:
  75   -------------------------------------------------------------------------------
  76  <!-- The main menu -->
  77   <div class="menu" id="mainmenu">
  78    <a id="menu-main" href="http://www.ez.no" onmouseover="ezpopmenu_mouseOver( 'mainmenu' )" >ez.no</a>
  79    <a id="menu-substitute" href="#" onmouseover="ezpopmenu_mouseOver( 'mainmenu' )" >Dynamic node view</a>
  80    <a id="menu-spawn" href="#" onmouseover="ezpopmenu_showSubLevel( 'submenu', 'menu-spawn' )" >Show submenu</a>
  81   </div>
  82  <!-- The submenu -->
  83   <div class="menu" id="submenu">
  84    <a id="submenu-item" href="#" onmouseover="ezpopmenu_submitForm( 'myform' )">Form submitter</a>
  85   </div>
  86  --------------------------------------------------------------------------------
  87  
  88  
  89   2. Setting up the menuArray array containing the popupmenu configuration.
  90   The menuArray is a multilevel array describing the features of your menus. The structure of the
  91   menuArray array is flat. This means that each menu is described in the toplevel array.
  92   Each menu can have the following properties set:
  93    - "depth" [required]: The depth of the menu. Toplevel menus have depth 0. Menus appearing from a toplevel menu
  94      have depth 1 etc.
  95    - "elements": The elements property must be yet another array containing all the menuitems that require string substitution.
  96      Each item can contain the following properties:
  97        + "url": The URL that this element should point at. Put the part that should be substituted within "%" symbols.
  98  
  99  The following example configures the menu created in step 1.
 100  --------------------------------------------------------------------------------
 101  <script language="JavaScript1.2" type="text/javascript">
 102  
 103   var menuArray = new Array();
 104   <!-- main menu -->
 105   menuArray['mainmenu'] = new Array();
 106   menuArray['mainmenu']['depth'] = 0;
 107   menuArray['mainmenu']['elements'] = new Array();
 108   menuArray['mainmenu']['elements']['menu-substitute'] = new Array();
 109   menuArray['mainmenu']['elements']['menu-substitute']['url'] = {'/content/view/%nodeID%'|ezurl};
 110  
 111   <!-- submenu -->
 112   menuArray['submenu'] = new Array();
 113   menuArray['submenu']['depth'] = 1; // this is a first level submenu of ContextMenu
 114  
 115  </script>
 116  
 117   <!-- The form submitted by the submenu -->
 118   {* Remove a node. *}
 119  <form id="myform" method="post" action="someactionhere">
 120    <!-- Notice that there is autoamatic string translation for the contents of value -->
 121    <input type="hidden" name="example" value="%nodeID%" />
 122  </form>
 123  
 124  --------------------------------------------------------------------------------
 125  
 126  
 127   Finally you will need to activate the "mainmenu" menu somehow. This is achieved through a call to ezpopmenu_showToplevel. In the eaxample case links in the setup array containing the string %nodeID% will be substituted by 42.
 128  
 129   example:
 130   <a onmouseclick="ezpopmenu_showTopLevel( event, 'ContextMenu', ez_createAArray( array( %nodeID%, 42) ) ); return false;">show</a><br />
 131  
 132  
 133  #################### Developer info ##############################
 134   This script defines the following global constants/variables:
 135   EZPOPMENU_OFFSET - Added to the x,y position of the mouse when showing the menu.
 136   CurrentNodeID - Used to remember the node we are currently showing the menu for. Used by submenus.
 137   VisibleMenus - An array containing the currently visible menus.
 138   */
 139  
 140  //Global CONSTANTS
 141  var EZPOPMENU_OFFSET = 8;
 142  var EZPOPMENU_SUBTOPOFFSET = 4;
 143  
 144  // Global VARS
 145  // CurrentNodeID holds id of current node to edit for submenu's
 146  var CurrentSubstituteValues = -1;
 147  var CurrentDisableID = -1;
 148  // Which Menu should be disabled
 149  var CurrentDisableMenuID = -1;
 150  // Store ClassName
 151  var DefaultClassName = 'more';
 152  // VisibleMenus is an array that holds the names of the currently visible menus
 153  var VisibleMenus = new Array();
 154  
 155  /*!
 156    Controls the popup offsets of the menu relative to the mouse position.
 157    Default values are offsetX = 8 and offsetY = 4.
 158   */
 159  function ezpopmenu_initOffsets( offsetX, offsetY )
 160  {
 161      EZPOPMENU_OFFSET = offsetX;
 162      EZPOPMENU_SUBTOPOFFSET = offsetY;
 163  }
 164  
 165  /*!
 166   Sets an element of the substitute array.
 167   This function can be used if you want to change some substitution values dynamically,
 168   E.g based on the element you chose in the menu.
 169  */
 170  function ezpopupmenu_setSubstituteValue( key, value )
 171  {
 172    if( CurrentSubstituteValues != -1 )
 173    {
 174        CurrentSubstituteValues[key] = value;
 175    }
 176  }
 177  
 178  /*!
 179     Shows toplevel menu at the current mouseposition + EZPOPMENU_OFFSET.
 180     'event' This parameter is for the mouse event.
 181     'menuID' is the identification of the menu to use.
 182     'substituteValues' is an associative array. The string value of each item in the menu will have they keys, substituted by the value in this array.
 183     'menuHeader' If the menu has a header it is replaced with this value.
 184     'disableID' If this id is found in the list of known disabled for this menu the item is disabled.
 185   */
 186  function ezpopmenu_showTopLevel( event, menuID, substituteValues, menuHeader, disableID, disableMenuID )
 187  {
 188      if( !document.getElementById( menuID ) ) return;
 189      ezjslib_mouseHandler( event ); // register new mouse position
 190  
 191      if ( substituteValues != -1 ) // new topmenu
 192      {
 193          ezpopmenu_hideAll();
 194          CurrentSubstituteValues = substituteValues;
 195      }
 196  
 197      if( disableID != -1 )
 198      {
 199          CurrentDisableID = disableID;
 200      }
 201  
 202      if( disableMenuID != -1 )
 203      {
 204          CurrentDisableMenuID = disableMenuID;
 205      }
 206  
 207      ezpopmenu_doItemSubstitution( menuID, menuHeader );
 208  
 209      // make menu visible
 210      ezpopmenu_moveTopLevelOnScreen( menuID );
 211      ezpopmenu_makeVisible( menuID );
 212  }
 213  
 214  /*!
 215    Show sublevel menu. The current substitute values are remembered from the last call to
 216    ezpopmenu_showTopLevel().
 217    Params:
 218    event - Just pass the event causing the script to popup.
 219    menuName - The name of the menu to popup
 220    overItem - The id of the item that caused the popup. This is used to reposition the menu correctly.
 221   */
 222  function ezpopmenu_showSubLevel( event, menuID, overItem )
 223  {
 224      if( !document.getElementById( menuID ) ) return;
 225      ezjslib_mouseHandler( event ); // register new mouse position
 226      //    ezpopmenu_showTopLevel( event, menuName, -1 );
 227      ezpopmenu_doItemSubstitution( menuID );
 228  
 229      ezpopmenu_hideHigher( menuArray[menuID]['depth'] - 1 ); //hide all other submenus 
 230  
 231      // make menu visible
 232      ezpopmenu_moveSubLevelOnScreen( menuID, overItem );
 233      ezpopmenu_makeVisible( menuID );
 234  }
 235  
 236  /*!
 237    Makes a window visible for the user.
 238    This method also sets the necessary variables in order to make the menu
 239    disappear when appropriate.
 240   */
 241  function ezpopmenu_makeVisible( menuID )
 242  {
 243      var styleObject = ezjslib_getStyleObject( menuID, document );
 244      if( styleObject ) styleObject.visibility = 'visible';
 245      VisibleMenus[menuArray[menuID]['depth']] = menuID;
 246  
 247      document.getElementById( menuID ).onmouseover = function() { document.onmousedown = null; }
 248      document.getElementById( menuID ).onmouseout = function() { document.onmousedown = ezpopmenu_hideAll; }
 249      document.onmousedown = ezpopmenu_hideAll;
 250  }
 251  
 252  /*!
 253    Substitute the values of the items in the menu with the items given to the first
 254    showTopLEvel call.
 255   */
 256  function ezpopmenu_doItemSubstitution( menuID, menuHeader )
 257  {
 258      // Do URL replace for all items in that menu
 259      for ( var i in menuArray[menuID]['elements'] )
 260      {
 261          var hrefElement = document.getElementById( i );
 262  
 263          if ( !hrefElement )
 264          {
 265              continue;
 266          }
 267  
 268          // href replacement
 269          var replaceString = menuArray[menuID]['elements'][i]['url'];
 270  
 271          if ( replaceString )
 272          {
 273              // loop though substitute values and substitute for each of them
 274             for ( var substItem in CurrentSubstituteValues )
 275              {
 276                  if ( typeof CurrentSubstituteValues[substItem] != 'object' )
 277                  {
 278                      replaceString = replaceString.replace( substItem, CurrentSubstituteValues[substItem] );
 279                  }
 280              }
 281  
 282             hrefElement.setAttribute( "href", replaceString );
 283          }
 284  
 285          // dynamic generation
 286          var loopingVariable = menuArray[menuID]['elements'][i]['variable'];
 287  
 288          if ( loopingVariable )
 289          {
 290              var content = '';
 291  
 292              for ( var localVariableIndex in CurrentSubstituteValues[loopingVariable] )
 293              {
 294                  var localVariable = CurrentSubstituteValues[loopingVariable][localVariableIndex];
 295                  if ( typeof localVariable != 'object' )
 296                      continue;
 297  
 298                  var partialContent = menuArray[menuID]['elements'][i]['content'];
 299                  for ( var substItem in CurrentSubstituteValues )
 300                  {
 301                      if ( typeof CurrentSubstituteValues[substItem] != 'object' )
 302                      {
 303                          partialContent = partialContent.replace( substItem, CurrentSubstituteValues[substItem] );
 304                      }
 305                  }
 306                  for ( var localItem in localVariable )
 307                  {
 308                      partialContent = partialContent.replace( '%' + localItem + '%', localVariable[localItem] );
 309                  }
 310                  content += partialContent;
 311              }
 312  
 313              hrefElement.innerHTML = content;
 314          }
 315  
 316          // enabled/disabled
 317          if( ( typeof( menuArray[menuID]['elements'][i]['disabled_class'] ) != 'undefined' &&
 318                ( ( typeof( menuArray[menuID]['elements'][i]['disabled_for'] ) != 'undefined' &&
 319                    menuArray[menuID]['elements'][i]['disabled_for'][CurrentDisableID] == 'yes' ) ) ||
 320                ( CurrentDisableMenuID && hrefElement.id == CurrentDisableMenuID ) ) )
 321          {
 322              hrefElement.className = menuArray[menuID]['elements'][i]['disabled_class'];
 323          }
 324          else if ( typeof( menuArray[menuID]['elements'][i]['disabled_class'] ) != 'undefined' &&
 325                    hrefElement.className == menuArray[menuID]['elements'][i]['disabled_class'] )
 326          {
 327              // Restore className
 328              hrefElement.className = DefaultClassName;
 329          }
 330      }
 331  
 332      // set header
 333      if ( menuHeader && typeof( menuArray[menuID]['headerID'] ) != 'undefined' )
 334      {
 335          var header = document.getElementById( menuArray[menuID]['headerID'] );
 336          if ( header ) header.innerHTML = menuHeader;
 337      }
 338  }
 339  
 340  /*!
 341    Reposition a toplevel menu according to the mouse position.
 342    Makes sure the complete menu is visible in the viewing area.
 343    The menu is repositioned like most OS's do if it doesn't fit at the normal position: is moved
 344    to the opposite side of the mouse pointer/menu.
 345  */
 346  function ezpopmenu_moveTopLevelOnScreen( menuID )
 347  {
 348      menuElement = document.getElementById( menuID );
 349      screenData = ezjslib_getScreenProperties();
 350      var newX = 0; var newY = 0;
 351  
 352      // compensate if we are below the screen
 353      if( (screenData.ScrollY + screenData.Height) < ( MouseY + EZPOPMENU_OFFSET + menuElement.offsetHeight ) )
 354          newY = MouseY - EZPOPMENU_OFFSET - menuElement.offsetHeight;
 355      // compensate if we are above the top of the screen
 356      else if( screenData.ScrollY > EZPOPMENU_OFFSET + MouseY )
 357          newY = screenData.ScrollY;
 358      else
 359          newY = MouseY + EZPOPMENU_OFFSET;
 360  
 361      // compensate if we are to the right of the screen
 362      if( (screenData.ScrollX + screenData.Width) < ( MouseX + EZPOPMENU_OFFSET + menuElement.offsetWidth ) )
 363          newX = MouseX - EZPOPMENU_OFFSET - menuElement.offsetWidth;
 364      // compensate if we are to the left
 365      else if( screenData.ScrollX > EZPOPMENU_OFFSET + MouseX )
 366          newX = screenData.ScrollX;
 367      else
 368          newX = MouseX + EZPOPMENU_OFFSET;
 369      // reposition menu
 370      menuElement.style.left = newX + "px";
 371      menuElement.style.top = newY + "px";
 372  }
 373  
 374  
 375  /*!
 376    Reposition a toplevel menu according to parent window.
 377    Makes sure the complete menu is visible in the viewing area.
 378    The menu is repositioned like most OS's do if it doesn't fit at the normal position: is moved
 379    to the opposite side of the mouse pointer/menu.
 380    TODO: If you have several submenus we should store any side adjustment in order to
 381    always adjust to the same side
 382  */
 383  function ezpopmenu_moveSubLevelOnScreen( menuID, alignItem )
 384  {
 385      menuElement = document.getElementById( menuID );
 386      screenData = ezjslib_getScreenProperties();
 387      var newX = 0; var newY = 0;
 388  
 389      alignElement = document.getElementById( alignItem );
 390      parentElement = document.getElementById( VisibleMenus[menuArray[menuID]['depth'] - 1] );
 391  
 392      if( alignElement && parentElement )
 393      {
 394          newX = parseInt( parentElement.style.left ) + menuElement.offsetWidth - EZPOPMENU_OFFSET;
 395          newY = parseInt( parentElement.style.top ) + alignElement.offsetTop + EZPOPMENU_SUBTOPOFFSET;
 396      }
 397      // compensate if we are below the screen
 398      if( ( screenData.ScrollY + screenData.Height ) < ( newY + menuElement.offsetHeight ) )
 399          newY = screenData.ScrollY + screenData.Height - menuElement.offsetHeight;
 400      // compensate if above the screen
 401      else if( screenData.ScrollY > newY )
 402          newY = screenData.ScrollY;
 403  
 404      // compensate if we are to the right of the screen
 405      if( ( screenData.ScrollX + screenData.Width ) < ( newX + menuElement.offsetWidth ) )
 406      {
 407          newX = parseInt( parentElement.style.left ) + EZPOPMENU_OFFSET - menuElement.offsetWidth;
 408      }
 409      // to the left is impossible
 410  
 411      // reposition menu
 412      menuElement.style.left = newX + "px";
 413      menuElement.style.top = newY + "px";
 414  }
 415  
 416  /*!
 417    Submit the form with id formID. All fields of type hidden will have the texts %nodeID%
 418    and %objectID% replaced with the corresponding real values.
 419  */
 420  function ezpopmenu_submitForm( formID, customSubstitute )
 421  {
 422      var formElement = document.getElementById( formID );
 423      if( formElement )
 424      {
 425          // for all children do replacement
 426          var children = formElement.childNodes;
 427          for( var i = 0; i < children.length; i++)
 428          {
 429              if( children[i].type == 'hidden' )
 430              {
 431                  for ( var substItem in CurrentSubstituteValues )
 432                  {
 433                      children[i].value = children[i].value.replace( substItem, CurrentSubstituteValues[substItem] );
 434                      if ( customSubstitute )
 435                      {
 436                          for( var j = 0; j < customSubstitute.length; j += 2 )
 437                          {
 438                              children[i].value = children[i].value.replace( '%'+customSubstitute[j]+'%', customSubstitute[j+1] );
 439                          }
 440                      }
 441                  }
 442              }
 443          }
 444  
 445          formElement.submit();
 446      }
 447  }
 448  
 449  /*!
 450    Hide menu id and all menu's beneath it
 451   */
 452  function ezpopmenu_hide( id )
 453  {
 454      var level = menuArray[id]['depth'];
 455      ezpopmenu_hideHigher( level - 1 );
 456  }
 457  
 458  /*!
 459    Hide all menus
 460  */
 461  function ezpopmenu_hideAll()
 462  {
 463      document.onmousedown = null;
 464      ezpopmenu_hideHigher( -1 );
 465  }
 466  
 467  /*
 468   * Hide all menus above 'level'
 469   */
 470  function ezpopmenu_hideHigher( level )
 471  {
 472      for ( var i = level + 1; i < VisibleMenus.length && VisibleMenus[i] != 'none' ; i++ )
 473      {
 474          var styleObject = ezjslib_getStyleObject( VisibleMenus[i], document );
 475          if( styleObject ) styleObject.visibility = 'hidden';
 476          VisibleMenus[i] = 'none';
 477      }
 478  }
 479  
 480  /*
 481   * This method should be called by mouseover for all items in the implementation.
 482   * The method makes sure that no menus on a lower level are shown.
 483   */
 484  function ezpopmenu_mouseOver( id )
 485  {
 486      ezpopmenu_hideHigher( menuArray[id]['depth'] );
 487  }
 488  
 489  /*
 490   * Helper function to create an associative array. Every two items will be paired as a key and a value.
 491   */
 492  function ez_createAArray( flat )
 493  {
 494      var resultArray = new Array();
 495      if( flat.length % 2 != 0 ) return resultArray;
 496  
 497      var len = flat.length / 2;
 498      for ( var i = 0; i <= flat.length; i += 2 )
 499          resultArray[flat[i]] = flat[i+1];
 500  
 501     return resultArray;
 502  }
 503  
 504  /*
 505   * Perform subsitution in 'href' and redirect browser to
 506   * newly created link.
 507   */
 508  function ezpopup_SubstituteAndRedirect( href )
 509  {
 510      // loop though substitute values and substitute for each of them
 511      for ( var substItem in CurrentSubstituteValues )
 512      {
 513          href = href.replace( substItem, CurrentSubstituteValues[substItem] );
 514      }
 515      location.href = href;
 516  }
 517  


Généré le : Sat Feb 24 10:30:04 2007 par Balluche grâce à PHPXref 0.7