1. Introduction
2. Object Hierarchy
3. How To Create Menu
4. AT JsMenu Programming Interfaces
4. 1. ClassAtJsMenuElement
4. 2. ClassAtJsMenuContainer
4. 3. ClassAtJsMenuBar
4. 4. ClassAtJsMenuPopup
4. 5. ClassAtJsMenuAbstractButton
4. 6. ClassAtJsMenuItem
4. 7. ClassAtJsMenu
4. 8. ClassAtJsMenuCheckedItemAbstract
4. 9. ClassAtJsMenuCheckBoxItem
4.10. ClassAtJsMenuRadioButtonItem
4.11. ClassAtJsMenuButtonGroup
4.12. ClassAtJsMenuRequestParam
4.13. ClassAtJsMenuRequestParamHolder
4.14. Global Functions
5. Persistent State
6. Stylesheets (Theme)
6.1. Menu Bar
6.2. Popup Menu (Menu List)
6.3. How To Use Different Icon Image When Menu Item Is Highlighted
6.4. Check Sign, Radio Sign, Sub Sign and Separator Line
6.5. Conversion of CSS Selectors From The Older Version
7. Script Embedding Issues
8. Keyboard Handling
9. XML/HTML Dataset To Create Menu Components
9.1. XML Dataset
9.2. HTML Dataset
9.3. Remote XML Dataset
10.AtJsMenuLoader
Bugs Report
Future Features
AT JsMenu is designed to simulate the mechanism of Java Swing JMenu to create its menu component objects. But there must be an extension to it, due to the lack of the condition of web environment which is stateless. A menu item whose checkbox or radiobutton, will not be able to remember its state (whether the checkbox or radiobutton has been checked or not) on previous page when the new page is loaded. Of course, the extra effort can be done to remember their state. AT JsMenu is provided with a feature that can save all state that must be remembered for the next page. These states are primarily stored in a cookie variable. See section 5. Persistent State. Beside persistent state, the other differences and extensions also exist. But the main steps in creating menu will look similar with Java Swing Menu.
AT JsMenu supports the following browsers:
These three browser families represent the most (if not all) platforms. May be, AT JsMenu will fail on some specific version, even if the version is included in the range of version mentioned above. Noticed, sometimes the behavior of a browser within handling a DHTML feature will differ gradually from a version to the next version.
Even if AT JsMenu is designed to simulate Java Swing JMenu, but the object hierarchy of AT JsMenu is designed differently. It's for eficiency (remember, some objects involved in object hierarchy of Java Swing menu component objects are not for the menu components themselves, but also for the other widgets in Java Swing). (Actually, I had never used Java Swing menu components when designing this DHTML widget. I only read the Java SDK Documentation)
Each object in the picture above will be outlined briefly here. To know more detail how to use these objects, see section 4. AT JsMenu Programming Interfaces. The objects in AT JsMenu have evolved since the first release. Furthermore, the definition of object, for what the object is created and also when and where it is used, has changed. But we try to make your code will not differ from the older version. Of course, the new feature in the new version will need additional code.
AtJsMenuElement
, AtJsMenuSeparator
,
AtJsMenuContainer
, AtJsMenuAbstractButton
,
AtJsMenuCheckedItemAbstract
AtJsMenuElement
is AtJsMenuBaseClass
. It's
renamed to match the similar object in Java Swing.
AtJsMenuItem
AtJsMenu
AtJsMenuBar
AtJsMenuBarIcon
AtJsMenuPopup
AtJsMenu
)
will have an associated popup menu that contains its all child menus. A popup menu can be
created independently (not associated with a menu), that is to create the popup menu in general
speaking.
AtJsMenuCheckBoxItem
AtJsMenuRadioButtonItem
AtJsMenuButtonGroup
AtJsMenuBar.Separator
addSeparator
or insertSeparator
instead.
AtJsMenuPopup.Separator
AtJsMenuBar.Separator
, except it's used on the popup.
AtJsMenuSelectionManager
AtJsMenuSelectionManager
object is to store
the path of the highlighted menu item. When the path changes, this object will manage
which menu objects are to be closed/unhighlighted and which to be open/highlighted.
It's supposed that you won't use this object, it's created automatically, so it will not
be explained furtherly in this manual.
AtJsMenuRequestParam
AtJsMenuRequestParamHolder
AtJsMenuCheckBoxItem
and AtJsMenuButtonGroup
.
It is used to remember the state of the checkbox and radio button.
This section will describe the main steps in creating the menu. Firstly, you should create the menu bar. The piece of code below shows how to do it.
oMenuBar = new AtJsMenuBar('menuBar','../At.ico');
There are two parameters passed to constructor. The first parameter is the id of an HTML element where the menu bar will be put in. Note, it gives you a flexibility that you can put the menu bar anywhere on your web page. So, you don't have to put the menu bar in the certain palce, such as on the top of the web page. The second parameter is optional. It's the icon for menu bar. The icon will be displayed on the left side of menu bar. The example above shows the file path of the icon image. It's the relative path. You may pass an absolute path too.
The next step is to add a top menu. The top menu become the direct child of menu bar. The top menu's name will be displayed on the menu bar. The code for creating a menu will be as below.
oMenu = new AtJsMenu('A Menu'); oMenuBar.add(oMenu);
The parameter passed to the constructor is the name of menu. This text will be
displayed on the menu bar. Its child menu will appear if its name on the menu bar
is clicked. Then you must invoke method add
of the menu bar object to
make the menu become available on the menu bar.
Of course, you may add the menu as many as you want (But, I don't kwow how your
web page will look like if too many menus you add). The order of menus on the menu
bar is the same as the order when they are added. You may also to insert a menu to
a certain position by using method insert
. For example:
oMenu = new AtJsMenu('A Menu'); oMenuBar.insert(oMenu,3);
The code above is to insert the menu on the fourth order because we pass 3 for the second parameter (0 is the first).
The next step is to add some menu items that become the child menus of the previous top menu. These menu items that will be selected by the user to tell what the user wants the system does. As explained in the previous section, there are some kind of menu items: the ordinary menu item, the menu item whose checkbox and the menu item whose radio button. Ok, below the example of code to add the menu items.
oMenuItem = new AtJsMenuItem('A Menu Item', 'icons/item.gif'); oMenuItem.onclick = function(e) { //Some javascript statements that will be executed when this item is chosen }; oMenu.add(oMenuItem); oMenuChecBoxItem = new AtJsMenuCheckBoxItem('A Menu Item Whose Checkbox', 'icons/icon-opt.gif', true); oMenu.add(oMenuChecBoxItem); oMenu.addSeparator(); oButtonGroup = new AtJsMenuButtonGroup(); oMenuRadioButtonItem = new AtJsMenuRadioButtonItem('Japanese', 'icons/flgjapan.ico',true,'jpn'); oButtonGroup.add(oMenuRadioButtonItem); oMenu.add(oMenuRadioButtonItem); oMenuRadioButtonItem = new AtJsMenuRadioButtonItem('German', 'icons/flggerm.ico',false,'ger'); oButtonGroup.add(oMenuRadioButtonItem); oMenu.add(oMenuRadioButtonItem);
As the top menu object before, the first parameter passed to the constructor is the name
of menu item which is the text will be displayed on the menu list. The second parameter
is optional, it is the icon for the menu item. The icon will be displayed on the
left side of menu item. Then you must invoke method add
of the menu object.
You should specify an onclick
event handler that will executed when
the menu item is chosen. Note, AT JsMenu doesn't follow Java Swing JMenu on how
to handle the event. Only onclick
event handler provided. It is for
efficiency.
For the menu item whose checkbox or radio button, there is the third parameter
to determine the initial state of the checkbox/radio button whether it's checked or not.
This parameter is optional too, the default value is false
. When checkbox/radio
button is checked, the icon, if any, will disappear and the checkbox/radio button appears.
Otherwise, the icon appears and the checkbox/radio button disappear. It's because they
occupy the same place.
The menu item whose radio button has the fourth parameter to specify the
value of the radio button. This value is for identifying which radio button
is checked in the persitent mode (see section 5. Persistent
State). Already explained in the previous section, object
AtJsMenuButtonGroup
is needed to group some radio buttons.
Only one radio button can be checked in a group. If a radio button is
checked then the other ones in the same group, will be unchecked automatically.
Use method add
of an object AtJsMenuButtonGroup
to include a menu item into the group, as shown in the example above.
The menu item whose checkbox or radio button may have an onclick
event handler. So, beside the checkbox or radio button's state changes,
the onclick
event handler will be executed.
Notice, there is a statement oMenu.addSeparator()
. This method
is to add a separator into the menu list. The separator is a line. It is
useful for grouping visually some menu items. There is also method
insertSeparator
to insert separator on the certain position.
The same as method insert
which is complementary of method
add
.
If you need a sub menu, the code below will tell you how to create it. A sub menu is simply a menu too. Different from the top menu, the sub menu is a child of a menu, not the menu bar. Therefore, a sub menu must be added into a menu, not into a menu bar. For clarity, see the code below.
oSubMenu = new AtJsMenu('A Sub Menu','icons/folder.gif'); oMenuItem = new AtJsMenuItem('A Menu Item on Sub Menu'); oSubMenu.add(oMenuItem); oMenuItem = new AtJsMenuItem('Another Menu Item on Sub Menu'); oSubMenu.add(oMenuItem); oMenu.add(oSubMenu);
When a sub menu is added, it will be created a menu item that will appear in the menu list associated with its parent menu. The text diplayed for the menu item is the name of the sub menu. This menu item will have a sign on the right side to show that this menu item has the child menu. Different from the top menu, the sub menu may have an icon. This icon will be displayed on the left side of the sub menu.
Since version 1.3, not only AtJsMenu
(the menu whose children)
object that can be added into the menu bar, but also all objects of AtJsMenuItem
,
including AtJsMenuCheckBoxItem
and AtJsMenuRadioButtonItem
can
be added into the menu bar. The menu bar object has also method
addSeparator
and insertSeparator
to create a separator on it.
How To Create A Popup Menu
First, create an instance object of popup menu
oPopup = new AtJsMenuPopup();
Then fill the popup menu in the way like the ordinary menu
oPopup.add(new AtJsMenuItem('A Menu Item in Popup')); oPopup.addSeparator(); .... oMenu = new AtJsMenu('A Sub Menu'); oMenu.add(new AtJsMenuItem('Child Sub Menu 1')); oMenu.add(new AtJsMenuItem('Child Sub Menu 2')); oMenu.add(new AtJsMenuItem('Child Sub Menu 3')); oPopup.add(oMenu);
Then, you must decide when and where the popup menu appears. It's your own task to write the code for it. The popup menu is shown by method below
oPopup.show(iX, iY, 'south')
More detail about this method, see its explaination.
4. AT JsMenu Programming Interfaces
The public interfaces will be explained per class object. Since the inheritance rule, all descendant objects will inherit public methods and properties from their ancestor objects. Therefore, the methods and properties that have been explained for an ancestor object, will not be explained again for the descendant objects except there are some additional notes for that object.
There some terms used here must be understood what really they are. The term 'static' means the method or property can only be accessed by referring to the class and cannot be accessed by referring to an instance object of that class. The static member is not inherited. Term 'read only' for a property doesn't really mean read only. Actually, you can still alter its value but you must treat this property as read only.
AtJsMenuElement
Abstract class. This object is the top ancestor of all menu components in AT JsMenu whose visual representation.
Properties
descAttrName
getComponent
). Set this property value
before that HTML element is created. Otherwise, the changes will have no effect.
For a menu item, the HTML element is created when it is added into a parent menu.
For the menu bar and popup, this property has no meaning.
By default, this property has value 'desc'. You may set the value become
the name of a useful standard attribute, such as 'title'.
See property description
.description
descAttrName
That HTML attribute will be set after the corresponding HTML element is
created. So any change of its property value after it, will have no effect.
By default, its value is empty string that means this menu object has no
description. The description is shown when this menu object is highlighted,
usually when the mouse cursor over this object. When this event happens,
the method showDescription
will be invoked. After that event ends, the method clearDescription
is invoked.icon
IMG
. But not always, it can also be a element DIV
which its CSS has been set to show the icon image. Remember the CSS property
background-image
.parentMenu
null
(has no parent). In version 1.0, this property's
name is menuContainer
that doesn't match anymore with
the current objects definition.Methods
clearDescription(oElm)
showDescription
.
In version 1.0, it's static method.oElm
getComponent
.getDescription(oElm)
description
but from the HTML
attribute which its name mentioned by property descAttrName
.
See also method showDescription
.oElm
clearDescription
.getComponent()
getElement
. It's renamed to match similar method in
Java Swing.setInterface(fInterface)
fInterface
showDescription(oElm)
getDescription
, not
from property description
.
In version 1.0, it's static methodoElm
clearDescription
.AtJsMenuContainer
This class is to create a container for a list of menu items. Each item can be
chosen by user that tells what the user wants for the system to do. The item may be a
sub menu if it's selected, it will show another menu list containing its child menus.
Specially, this class is inherited by class AtJsMenuBar
and AtJsMenuPopup
.
See also class parent.
Properties
Property descAttrName
and description
have no meaning for this object. Property parentMenu
is always null
, it means the menu container object has no parent.
Methods
add(oMenuItem)
insert
.oMenuItem
addSeparator()
insertSeparator
.getItem(idx)
null
.idx
getMenu
of menu bar
object instead.
null
will be returned.getItemCount()
getMenuCount
of menu bar object insteadinsert(oMenuItem,idx)
oMenuItem
idx
insertSeparator(idx)
idx
remove(oMenuItem)
oMenuItem
remove(idx)
idx
AtJsMenuBar
It is to create the menu bar. See also its parent class.
Parameter(s):sId
icon
IMG
).Methods
getMenu(idx)
idx
null
.getMenuCount()
AtJsMenuPopup
This class is to create a popup menu. Each menu object whose children
(instance object of Class AtJsMenu
)
has a popup menu object associated with it. This popup menu will contain all child
menu items of the menu object. This popup menu object is created when the menu
object is created. The popup menu can also be created independently (not associated
with any menu object) that can be displayed anywhere, not only near the menu object.
See also its parent class.
Properties
Property icon
has no meaning for this object.
Methods
getHeight()
getWidth()
isVisible()
true
if this popup menu has
been visible.setLocation(iLeft,iTop)
iLeft
iTop
setVisible(bVisible)
bVisible
true
then this popup menu will be
visible. Otherwise, it will be invisible.show(iLeft,iTop,sDirection)
iLeft
iTop
sDirection
AtJsMenu.delayOpen
is higher than zero
then the popup menu won't be displayed entirely directly but will be revealed
and slidden piece by piece. This parameter is to determine the direction to
which the popup menu is slidden when it comes up. The possible values is 'south' (down),
'north' (up), 'west' (to the left) and 'east' (to the right) and also 'south-west',
'south-east', 'north-west' and 'north-east'.
The value of (iLeft
,iTop
)
from the other parameters is the coordinate after the popup menu is slidden.
If the value of AtJsMenu.delayOpen
is 0 then this parameter will be ignored.show(oInvoker,iX,iY)
oInvoker
(iX,iY)
AtJsMenuAbstractButton
Abstract class. This class is the ancestor class for all objects that can be included into a menu container (menu bar or popup), except separator. See also class parent.
Properties
text
setText
.
Methods
doClick()
onclick
event handler.getContainer()
null
if it has not been included into a menu container.getMnemonic()
setMnemonic
.isEnabled()
isTopLevelMenu()
true
if it's a top menu.isSelected()
AtJsMenuCheckBoxItem
and
AtJsMenuRadioButtonItem
object.true
if the checkbox
or radio button is checked.onclick(e)
onclick
event, so will not execute this
handler. Selecting a menu object will only reveal its child menu items. However,
this handler still has the meaning for a menu object whose children as explained hereafter.
When an item is chosen, its onclick
event handler will be invoked,
if any. After it's executed, then will be invoked the handler owned by the menu
item's parent and then after that will be invoked the handler owned by its grand
parent. This propagation will continue up to the top menu that become the ancestor
of the menu item selected. After the top menu's handler is executed then will be
executed AtJsMenu.onclick
(static
method).
Each handler can stop the propagation, that is the next handlers will not be
executed, see the parameter. Each handler should be redefined to execute the
right statements.e
src
is the reference to the chosen menu item and
cancelBubble
is to set whether the propagation
must be stopped or not (if set to true
then
the propagation will be stopped). The property cancelBubble
must be set in the handler who wants to stop the propagation.setEnabled(bEnabled)
onclick
event but only closes the menu. By default, the menu is enabled.
See also method isEnabled
.bEnabled
true
the the menu will be enabled.setMnemonic(iKeyCode)
getMnemonic
.iKeyCode
AtJsMenuKeys.DOM_VK_A
to AtJsMenuKeys.DOM_VK_Z
or AtJsMenuKeys.DOM_VK_0
to AtJsMenuKeys.DOM_VK_9
constants.setSelected(bSelected)
bSelected
true
then
the checkbox or radio button will be checked. Otherwise, they will
be unchecked.setText(sText)
text
.sText
AtJsMenuItem
This class is to create an ordinary menu item. This class is the ancestor class for all kind of menu items (menu item whose children, menu item whose checkbox, menu item whose radio button). Defines common interface for a menu item. See also class parent.
Parameter(s):sText
icon
IMG
).getIndex()
getAccelerator()
setAccelerator
.keyCode
is the main accelerator key code and modifiers
is the
modifier key(s) which are pressed together). If the keyCode
property is 0 then this menu item has no accelerator key. Use bitwise operator
&
to know which modifier key pressed (Shift/Ctrl/Alt) and masked by
the value of AtJsMenuKeys.ALT_MASK
, AtJsMenuKeys.CONTROL_MASK
or AtJsMenuKeys.SHIFT_MASK
.setAccelerator(iKeyCode,iModifiers)
getAccelerator
.iKeyCode
AtJsMenuKeys
constants, avoid to use the integer literal value
directly.iModifiers
AtJsMenuKeys.ALT_MASK
,
AtJsMenuKeys.CONTROL_MASK
, AtJsMenuKeys.SHIFT_MASK
or the sum of any of them.AtJsMenu
This class is to create a menu item that can have child menu items. See also class parent.
Properties
checkSign
setCheckSign
. You may prefer to use
the actual checkbox (element <input type='checkbox' ...>
).
By default, the sign is the element below
<div class='check'>√</div>
chunkPerSizeOpen
delayOpen
.delayOpen
chunkPerSizeOpen
). It's in miliseconds.
By default, the value is 0 that means the menu will appear immediately entirely.horizontalSeparatorSign
<div class='line' style='border-style:solid; border-width:0px 1px 1px 0px; fontSize:1px; height:2px;></div>To change the element separator, use method
setHorizontalSeparatorSign
.
radioSign
setRadioSign
. You may prefer to use
the actual radio button (element <input type='radio' ...>
).
By default, the sign is the element below
<div class='radio'>♦</div>
subSign
<div class='sub'>»</div>You, however, may alter this sub sign by a good arrow image using method
setSubSign
. Wrap the image become element
IMG
.
verticalSeparatorSign
<div class='line' style='border-style:solid; border-width:0px 1px 1px 0px; fontSize:1px; width:2px;></div>To change the element separator, use method
setVerticalSeparatorSign
.
Methods
add(oMenuItem)
insert
.oMenuItem
addSeparator()
insertSeparator
.doClick()
doClick
of AtJsMenuAbstractButton
.getItem(idx)
idx
null
will be returned.getItemCount()
getPopupMenu()
insert(oMenuItem,idx)
oMenuItem
idx
insertSeparator(idx)
idx
isPopupVisible()
true
if its child menus has been
revealed.isSelected()
isSelected
of AtJsMenuAbstractButton
.true
if it's highlighted.onchange(e)
onchange
event happens on its child menu whose checkbox or radio button because the event bubbles.
See also onchange
handler of
AtJsMenuCheckedItemAbstract
.onclick(e)
onclick
event for all menu items that has been created. It should be executed whenever a menu item
is selected, if not canceled. See event handler onclick
.remove(oMenuItem)
oMenuItem
remove(idx)
idx
setAccelerator(iKeyCode,iModifiers)
setAccelerator
of
AtJsMenuItem
. Always resets the accelerator/shortcut key
(this menu object cannot have an accelerator key).
setCheckSign(oSign)
checkSign
.oSign
setHorizontalSeparatorSign(oSign)
horizontalSeparatorSign
.oSign
setRadioSign(oSign)
radioSign
.oSign
setSubSign(oSign)
subSign
.oSign
setVerticalSeparatorSign(oSign)
verticalSeparatorSign
.oSign
setZIndexMin(iZIndex)
z-index
. By default, it's 100. As you know, property
CSS z-index
is to set priority of visibility when two
or more elements are overlapped. Whose the higher value, will be seen on top
the others. The popup of sub menu always has the higher value than its parent popup's,
so the popup of sub menu will be seen on top.iZIndex
z-index
minimal value.showCopyright(f)
f
window.alert
(that simply shows the copyright statement
on an alert box).AtJsMenuCheckedItemAbstract
Abstract class. This is the base class for menu item whose checkbox or radio button. Basically, checkbox and radio button have the same behavior, that is, they can be checked or unchecked. This class defines the common process for this behavior. See also class parent.
Parameter(s):bSelected
true
then it will be checked/selected. By default,
it's unchecked.Properties
value
AtJsMenuButtonGroup
).
Remember, only one radio button that can be selected in a group.Methods
onchange(e)
onchange
event happens. This event happens when the checkbox
or radio button's state changes from unchecked to checked or viceversa.
Beside triggering onclick
event, clicking a checkbox will trigger
onchange
event because the state of checkbox will change when it's
clicked. But radio button doesn't so. It will always be checked when it's clicked.
For radio button, onchange
event is very useful when it's unchecked
because another radio button in the same group is checked. The onclick
event only occurs on the radio button which is checked.onclick
event. See also
onchange
handler
of AtJsMenu
.AtJsMenuCheckBoxItem
This class is to create a menu item whose checkbox. See also parent classes:
AtJsMenuCheckedItemAbstract
and
AtJsMenuRequestParamHolder
.
Methods
setValue(val)
setValueFromRequestParam
.val
null
then the checkbox will be unchecked.AtJsMenuRadioButtonItem
This class is to create a menu item whose radio button. See also class parent.
Parameter(s):sValue
value
.Methods
setGroup(oButtonGroup)
oButtonGroup
AtJsMenuButtonGroup
.AtJsMenuButtonGroup
To group some menu items whose radio button. Only one radio button that can be selected in a group. If a radio button is selected the the other ones in the same group will be automatically unselected. See also class parent.
Methods
add(oRadioButtonMenuItem)
oRadioButtonMenuItem
AtJsMenuRadioButtonItem
.getButtonCount()
getButtons()
remove(oRadioButtonMenuItem)
oRadioButtonMenuItem
setSelected(oRadioButtonMenuItem,bSelected)
oRadioButtonMenuItem
bSelected
true
then the
radio button will be checked. Otherwise, the radio button will be
unchecked.setValue(val)
value
.val
AtJsMenuRequestParam
As you know, basically the web is stateless. So the state on the
previous page cannot be remembered on the next page. The extra effort
must be made to remember that. One of ways is to save all state must be
remembered in cookie. The persistent state, contrary from stateless,
is needed by a menu, particularly for remembering the state of
checkboxes and radio buttons.
This class is intended for storing the state of checkboxes and
radio buttons. Not only that, it can be used for the other state, such as
the dynamic menu as shown in the example distributed with this
AT JsMenu package. Each state, as a variable, will have the name and
the value. All states will be stored in a cookie and optionally
inserted into a form as the hidden fields (still experimental).
For more information, see section 5. Persistent State.
sParamName
Properties
isCookieEnabled
true
, that is
the use of cookie is enabled. Currently, many browsers, by default,
disallow javascript to set cookie and it will raise error.
If you don't want this happen, set this property to false
before an AtJsMenuRequestParam
object is used for saving the states.isExist
true
if there are some states has been remembered.cookieSettings
paramName
Methods
getValue()
paramName
).null
will be returned if this state has not been remembered yet.setFormId(sId)
sId
setFormName(sName)
sName
setFormObject(oForm)
oForm
setValue(val)
null
then the state will not be remembered anymore.
If the value is string then it cannot contain character ':' (colon)
and '=' (equals sign) because they are used by AT JsMenuval
removeMe()
AtJsMenuRequestParamHolder
It's inherited by class AtJsMenuCheckBoxItem
and
AtJsMenuButtonGroup
.
It's intended for remembering the state of checkbox and radio button.
It will take an instance object of class AtJsMenuRequestParam
.
For more information, see section 5. Persistent State.
Methods
getRequestParamValue()
getValue
of
class AtJsMenuRequestParam
.removeRequestParam()
removeMe
of
class AtJsMenuRequestParam
.setRequestParam(oReqParam)
AtJsMenuRequestParam
.oReqParam
AtJsMenuRequestParam
.setRequestParamValue(val)
setValue
of
class AtJsMenuRequestParam
.val
setValueFromRequestParam()
AtJsMenuRequestParam.isExist
.
It will call method setValue
of the related child class ( AtJsMenuCheckBoxItem
or
AtJsMenuButtonGroup
).
getWinLeftSide()
getWinRightSide()
getWinTopSide()
getWinBottomSide()
getElementCoordOnPage(oElm)
oElm
x
is the left coord and y
is the top coord.The web is stateless, it means the state on the previous page
will not be able to be retrieved on the current page. Yet, the extra effort
can be done to make some informations become persistent. One of
ways is to store them in cookie. This section will explain how the
persistent state is done, especially the use of class AtJsMenuRequestParamHolder
and class AtJsMenuRequestParam
.
Class AtJsMenuRequestParamHolder
is inherited by class
AtJsMenuCheckBoxItem
and class AtJsMenuButtonGroup
.
The interfaces of this class are useful to save the state of the checbox
and radio button and then to retrive it on the next page. Everytime the
state of checkbox or radio button changes then the change will be stored
automatically in cookie. It's done by providing an instance object of class
AtJsMenuRequestParam
to tell in which variable/parameter the state will be stored. The example
below will tell the clear explanation.
oJpnMenuItem = new AtJsMenuRadioButtonItem('Japanese', 'icons/flgjapan.ico',false,'jpn'); oGerMenuItem = new AtJsMenuRadioButtonItem('German', 'icons/flggerm.ico',false,'ger'); oEngMenuItem = new AtJsMenuRadioButtonItem('English','icons/flguk.ico',false,'eng'); .... oButtonGroup = new AtJsMenuButtonGroup(); oButtonGroup.add(oJpnMenuItem); oButtonGroup.add(oGerMenuItem); oButtonGroup.add(oEngMenuItem); oButtonGroup.setRequestParam(new AtJsMenuRequestParam('lang')); if (AtJsMenuRequestParam.isExist) oButtonGroup.setValueFromRequestParam(); else oButtonGroup.setValue('eng');
Three last lines in the piece of code above are the statements
how to deal with the remembered state (persistent state).
Method setRequestParam
is to set an instance object of class AtJsMenuRequestParam
to which the AtJsMenuRequestParamHolder
consults
about the remembered state. Each instance object of class
AtJsMenuRequestParam
will correspond to a variable
in which the remembered state is stored. Parameter string passed
to the constructor is the name of variable/parameter. In this case,
the name variable is 'lang'
. The property AtJsMenuRequestParam.isExist
is to check whether there is a remembered state, if not then the menu
is firstly loaded. Note, this property is not for only a state variable,
that is if there is whatever remembered state then this property will
return true
. It's useful if you want to set the default
value/state. In the example above, the default value is 'eng'
.
Method setValueFromRequestParam
is to retrieve the remembered state and then set the current object's
state become the remembered state. This process is not done automatically
(must use method setValueFromRequestParam
) because
it cannot be known when to retrieve the remembered state. It must fit your
own code.
The persitent state is not only for the button group (indirectly,
for menu item whose radio button) or the menu item whose checkbox.
Object AtJsMenuRequestParam
can be used independently
to deal with the other state that must be remembered. One of cases is
dynamic menu. That is the menu which its item can be added into or removed
from it at run time. Here the example.
var g_oDynamicMenu = new AtJsMenu('Dynamic Menu'); g_oDynamicMenu.description = 'Its menu items can be dynamically added or removed'; oMenuBar.add(g_oDynamicMenu); oMenuItem = new AtJsMenuItem('Add an item'); var g_iAddedMenuItemIdx = 1; var g_oDynMenuReqParam = new AtJsMenuRequestParam('dynmenu'); var g_sShownDynIndex = (g_oDynMenuReqParam.getValue() ? g_oDynMenuReqParam.getValue() : ''); oMenuItem.onclick = function() { var o_MenuItem = new AtJsMenuItem('Remove this item added ' + (g_iAddedMenuItemIdx++)); o_MenuItem.dynIndex = g_iAddedMenuItemIdx - 1; g_oDynamicMenu.add(o_MenuItem); g_sShownDynIndex += (o_MenuItem.dynIndex + '-'); g_oDynMenuReqParam.setValue(g_sShownDynIndex + g_iAddedMenuItemIdx); o_MenuItem.onclick = function() { g_oDynamicMenu.remove( this.getIndex() ); g_sShownDynIndex = g_sShownDynIndex.replace(new RegExp('^'+this.dynIndex+'-'), ''); g_sShownDynIndex = g_sShownDynIndex.replace(new RegExp('-'+this.dynIndex+'-'), '-'); g_oDynMenuReqParam.setValue(g_sShownDynIndex + g_iAddedMenuItemIdx); } } g_oDynamicMenu.add(oMenuItem); g_oDynamicMenu.addSeparator(); arShownDynIndex = g_sShownDynIndex.split('-'); g_sShownDynIndex = ''; for (i=0; i<arShownDynIndex.length-1; i++) if (arShownDynIndex[i]) { g_iAddedMenuItemIdx = parseInt(arShownDynIndex[i]); oMenuItem.onclick(); } i = arShownDynIndex.length-1; if (i >= 0 && arShownDynIndex[i]!='') //Last element is the last value of g_iAddedMenuItemIdx g_iAddedMenuItemIdx = parseInt(arShownDynIndex[i]);
One think that must be noticed to create the dynamic menu
is how to define the event handler for each dynamic item (can
be added or removed at run time). If the menu item has been
known before, but it only appear or disappear on the menu,
not difficult to define the exact event handler. But if
what menu item that must be created will just be known at
run time, like the example above, then defining event
handler will have more consideration. The easy way is
to define the general event handler and then what to do if a
dynamic item is chosen, is determined by checking out
the property text
of the menu item.
About Cookie
All remembered states in AT JsMenu are stored in a cookie named
'AtJsMenu'. I don't know exactly how large cookie can be handled
by a certain browser. A reference tells me that a cookie in Netscape
is limited up to 4 kilobytes, including the cookie name. Yes indeed,
it's a lot enough. Yet, the limitation must still be taken into account.
Make the state variable name and it's value as concise as possible.
It may not be likeable but don't create a lot of remembered states.
How to Read The Remembered States of AT JsMenu on Server
Sometimes, the server side script, such as PHP script, needs to read
the state of AT JsMenu, especially for checkboxes and radio buttons.
Of course, it must read the cookie named 'AtJsMenu' and then parse it.
To make it easier, AT JsMenu package includes two PHP files, they are
'AtJsMenuRequestParam.php4' and 'AtJsMenuRequestParam.php5'. Choose
one of them, depending on your PHP version. These files contain PHP class
AtJsMenuRequestParam
. This class is not more than a
translation of class AtJsMenuRequestParam
in JavaScript
version. Example of the use of this PHP class is in file 'options.php',
one of examples distributed in AT JsMenu package. Explore yourself!
The goal of this section is in order that you can customize the stylesheets or you can create your own theme. AT JsMenu distributes three CSS files you can choose one of them, those are 'AtJsMenu-default.css', 'AtJsMenu-classic.css' and 'AtJsMenu-xpsilver.css'. These three styles are not all. You always have your own taste. Ok, this section will explain the styles per menu component. The example of styles will be taken from file 'AtJsMenu-default.css' because it's the most complex, so all can be described.
AT JsMenu version 1.3 uses different CSS selector names from the older version and NO BACKWARD COMPATIBILITY. This section also will tell some guides to change your stylesheet if you have used the older version of AT JsMenu.
As explained in section 4.3. Class
AtJsMenuBar
, to create a menu bar, we must supply
the id of an HTML element to be the menu bar element (in which the
menu bar will be drawn). As a consequence, it cannot be determined
what kind of HTML element must be the menu bar. Whatever kind of
HTML element, this element's class
attribute will be
set become 'AtJsMenuBar' (remember, the attribute class
is to set the style). Inside the menu bar element, will be created
an element TABLE
with one row. Each cell in this table
will become the menu bar item element (top menu). The left-most cell is always
reserved for the place of the menu bar icon. If the icon is not
specified, this cell will be emptied (not become the first top menu).
class
set to one of values below:
Class Name | When it happens |
---|---|
AtJsMenuButton |
In normal condition |
AtJsMenuButton-hover |
When the menu item is highlighted, for example when mouse cursor is over it |
AtJsMenuButton-select |
When the menu item have been checked, specially for toggle item
such as AtJsMenuCheckBoxItem and AtJsMenuRadioButtonItem . |
AtJsMenuButton-select-hover |
When the item has been checked and it's highlighted. The menu whose children also has this style when it's highlighted and the list of its child menus has been revealed. |
AtJsMenuButton-select-hover-armed |
The same as AtJsMenuButton-select-hover |
AtJsMenuButton-disabled |
The same as AtJsMenuButton |
AtJsMenuButton-hover-disabled |
The same as AtJsMenuButton-hover |
AtJsMenuButton-select-disabled |
The same as AtJsMenuButton-select |
AtJsMenuButton-select-hover-disabled |
The same as AtJsMenuButton-select-hover |
Class Name | When it happens |
---|---|
AtJsMenuButton-icon |
In normal condition |
AtJsMenuButton-hover-icon |
When the icon is highlighted. |
AtJsMenuButton-select-hover-icon |
When the icon is pressed (pressing the mouse left button on it). |
We design these class names, actually it is intended for class attribute
selector in the way of '
The elements on menu bar will look like below (consider the menu bar element
is an element DIV
).
<div class='AtJsMenuBar'> <table> <tr> <td class='AtJsMenuButton-icon'><img src='icon.gif' /></td> <td class='AtJsMenuButton'>Item 1</td> <td class='AtJsMenuButton'>Item 2</td> .... .... </tr> </table> </div>
Based on the description of the menu bar elements above, we can define the following style.
.AtJsMenuBar { background-color: #486048; border-color: #738573 #233523 #233523 #738573; border-style: solid; border-width: 2px; cursor: default; padding: 2px; } .AtJsMenuBar table { border-spacing: 0px; border-width: 0px; margin: 0px; } .AtJsMenuBar td { border-color: #486048; border-style: solid; border-width: 1px; font-family: arial,sans-serif; font-size: 12px; line-height: 12px; padding: 2px 5px; } td.AtJsMenuButton { color: #cccccc; } td.AtJsMenuButton-hover, td.AtJsMenuButton-hover-disabled { border-color: #738573 #233523 #233523 #738573; color: #ffffff; cursor: pointer; text-decoration: underline; } td.AtJsMenuButton-select, td.AtJsMenuButton-select-hover, td.AtJsMenuButton-select-hover-armed, td.AtJsMenuButton-select-disabled, td.AtJsMenuButton-select-hover-disabled { border-color: #233523 #738573 #738573 #233523; color: #ffffff; cursor: default; text-decoration: none; } td.AtJsMenuButton-select, td.AtJsMenuButton-select-disabled { background-color: #637563; padding: 3px 4px 1px 6px; } td.AtJsMenuButton-select-hover, td.AtJsMenuButton-select-hover-disabled { background-color: #486048; padding: 3px 4px 1px 6px; } td.AtJsMenuButton-select-hover-armed { background-color: #486048; padding: 5px 3px 0px 7px; } td.AtJsMenuButton-disabled, td.AtJsMenuButton-hover-disabled, td.AtJsMenuButton-select-disabled, td.AtJsMenuButton-select-hover-disabled { color: #8da58d; } td.AtJsMenuButton-icon { padding: 1px; } td.AtJsMenuButton-hover-icon { border-color: #738573 #233523 #233523 #738573; cursor: pointer; padding: 1px; } td.AtJsMenuButton-select-hover-icon { background-color: #486048; border-color: #233523 #738573 #738573 #233523; cursor: default; padding: 2px 0px 0px 2px; }
Needs to note, the rule with selector '.AtJsMenuBar td
'
is for all menu bar item and also the icon's cell because they are
the table cell or element TD
. The styles above for higlighted
items but not selected yet, make the item element as if
it were coming out of the canvas. And it's as if it were pressed
when it has been selected. The rules above also specify that the disabled item
will have the same style as if it were not disabled, except its font color
will differ because of the tenth rule above.
A popup menu element is an element DIV
which its attribute
class
is set to 'AtJsMenuPopup'. Inside the popup menu element,
there is an element TABLE
. Each row in the table is
a menu item element. Normally, the menu item element have attribute
class
set to 'AtJsMenuItem'. A menu item element, which
is an element TR
, has three cells (element TD
).
The first cell contains an icon, checkbox or radio button if any.
The second cell shows the text of the menu item. The third cell,
if the menu item is sub menu, contains sub sign element (usually
a right arrow). The third cell can also display shorcut/accelerator
key for the menu item if any (a menu whose child menus cannot have a
shortcut key) The first cell has attribute class
set to
'icon'. The second one has attribute class
set to 'text'.
The third one has attribute class
set to 'arrow' if it
is a menu whose children or 'shortcut' if it is not.
Based on this description, all menu elements will look like
<div class='AtJsMenuPopup'> <table> <tr class='AtJsMenuItem'> <td class='icon'><img src='icon.gif' /></td> <td class='text'>Item 1</td> <td class='shortcut'> </td> </tr> <tr class='AtJsMenuItem'> <td class='icon'> </td> <td class='text'>Item 2</td> <td class='shortcut'> </td> </tr> <tr class='AtJsMenuItem'> <td class='icon'> </td> <td class='text'>A Sub Menu</td> <td class='arrow'><div class='sub'>»</div></td> </tr> ..... ..... </table> </div>
After you look at the HTML elements above, you should understand that we can defines the following styles.
.AtJsMenuPopup { background-color: #486048; border-color: #738573 #233523 #233523 #738573; border-style: solid; border-width: 2px; cursor: default; padding: 1px; } .AtJsMenuPopup table { border-spacing: 0px; } .AtJsMenuPopup tr { color: #cccccc; font-family: arial,sans-serif; font-size: 12px; } .AtJsMenuPopup td { border-color: #486048; border-style: solid; border-width: 1px; } .AtJsMenuPopup td.text { padding: 3px 2px; } .AtJsMenuPopup td.icon { padding: 1px 2px; text-align: center; width: 24px; } .AtJsMenuPopup td.shortcut { padding: 3px 10px 3px 4px; width: 24px; } .AtJsMenuPopup td.arrow { padding: 3px 2px; width: 24px; } .AtJsMenuPopup tr.AtJsMenuItem { font-weight: normal; } .AtJsMenuPopup td.icon img { background-color: #486048; border-color: #486048; border-style: solid; border-width: 1px; display: block; height: 18px; width: 18px; }
The rule with selector '.AtJsMenuPopup td.icon img' is for
the icon image, as you can guess. But not always, the icon
image must become an element IMG
. Another
possibility will be outlined later. As I said before,
class name 'AtJsMenuItem' is for normal condition. But
sometimes, an menu item element may be highlighted.
Of course in this condition, we should give the different
style for it. When it's highlighted, attribute class
of the menu item element is set to '
.AtJsMenuPopup tr.AtJsMenuItem.hover { background-color: #606000; color: #ffffff; font-weight: bold; } .AtJsMenuPopup tr.AtJsMenuItem.hover td.icon { border-color: #858525 #606000 #353500 #858525; } .AtJsMenuPopup tr.AtJsMenuItem.hover td.text { border-color: #858525 #606000 #353500 #606000; } .AtJsMenuPopup tr.AtJsMenuItem.hover td.shortcut { border-color: #858525 #353500 #353500 #606000; } .AtJsMenuPopup tr.AtJsMenuItem.hover td.arrow { border-color: #858525 #353500 #353500 #606000; } .AtJsMenuPopup tr.AtJsMenuItem.hover td.icon img { border-color: #738573 #233523 #233523 #738573; }
The styles above make the highlighted menu item element has the different background color. Beside that, it will look as if it were coming out of the canvas. The last rule in the styles above indicates that we want the icon image has the different style when its menu item is highlighted.
Beside those, the menu item may be disabled. In this condition,
it should have different style. When disabled, the class
attribute
of menu item element will be set to '
.AtJsMenuPopup tr.disabled { color: #8da58d; } .AtJsMenuPopup tr.hover.disabled { color: #8da58d; font-weight: normal; }
AT JsMenu doesn't provide the interface to set two icon image
for a menu component. The first icon is for normal condition and
the second one is used when it's highlighted. However, we can trick
it via style. The following example will show it more clearly.
The first, we use an element DIV
, not element
IMG
(it's just an example, the chosen element is
up to you). We create this element via script for more convenient.
Set its attribute class
(property className
if via script) to a value, call it '
.AtJsMenuPopup td.icon .folder-icon { background-color: #486048; background-position: center center; background-repeat: no-repeat; border-style: solid; border-width: 1px; height: 18px; width: 18px; } .AtJsMenuPopup tr.AtJsMenuItem td.icon .folder-icon { background-image: url('icons/folder-closed.gif'); border-color: #486048; } .AtJsMenuPopup tr.AtJsMenuItem.hover td.icon .folder-icon { background-image: url('icons/folder-open.gif'); border-color: #738573 #233523 #233523 #738573; }
Notice at the styles above, the second rule and the third one
make the different icon image between the normal condition and
highlighted condition (notice the CSS property
background-image
). After we define these styles, we create
the icon element via script like below.
oFolderIcon = document.createElement('DIV'); oFolderIcon.className = 'folder-icon'; oSubMenu = new AtJsMenu('Purchase',oFolderIcon); ... ... oMenu.add(oSubMenu);
These elements become the good factors to make a theme looks different from the others. Check sign is used to visualize the checkbox and placed on the left side of the menu item needing it. Radio sign is to visualize radio button and also placed on the left. Sub sign is to mark that the menu item is sub menu (has children), usually it's a right arrow. The sub sign is placed on the right side.
Separator line is used to separate some menu items from some other ones, that is to group visually some menu items. Since version 1.3, AT JsMenu supports two kinds of separator line, horizontal and vertical line. The new line is vertical which is placed on menu bar.
To break the dependency to several image file, AT JsMenu,
by default, create these elements from some HTML elements with certain style
or containing the appropriate HTML entity. Original element checkbox
(<input type='checkbox' .../>
), radio button
(<input type='radio' .../>
) and line (<hr />
)
is too ugly (may not on your taste). Has been explained, by default,
AT JsMenu uses these elements:
The check sign is
<div class='check'>√</div>
The radio sign is
<div class='radio'>♦</div>
The sub sign is
<div class='sub'>»</div>
The horizontal separator line is
<div class='line' style='border-style:solid; border-width:0px 1px 1px 0px; fontSize:1px; height:2px;></div>
The vertical separator line is
<div class='line' style='border-style:solid; border-width:0px 1px 1px 0px; fontSize:1px; width:2px;></div>
As explained before, the checkbox and radio button is placed in a cell
whose attribute class
set to 'icon'. Sub sign is placed in
a cell whose attribute class
set to 'arrow'. Horizontal separator
line occupies an entire row in the table inside the menu list
element. This row's attribute class
is set to 'AtJsMenuSeparator'.
To fit with the other menu items, this row contains one cell spanned from 3 cells.
Vertical separator line is placed inside element TD
which is its
class
attribute set to 'AtJsMenuSeparator'.
Then it's ready to define the style for these element signs.
.AtJsMenuPopup td.icon .check { border-color: #233523 #738573 #738573 #233523; border-style: solid; border-width: 1px; color: #ffffff; font-family: arial,sans-serif; font-size: 12px; font-weight: 900; line-height: 14px; text-align: center; vertical-align: middle; padding: 2px 0px 2px 0px; width: 18px; } .AtJsMenuPopup tr.AtJsMenuItem td.icon .check { background-color: #637563; } .AtJsMenuPopup tr.AtJsMenuItem.hover td.icon .check { background-color: #486048; } .AtJsMenuPopup td.icon .radio { background-color: #486048; color: #cccccc; font-family: arial,sans-serif; font-size: 14px; font-weight: 900; height: 16px; line-height: 14px; text-align: center; vertical-align: middle; width: 18px; } .AtJsMenuPopup tr.AtJsMenuItem.hover td.icon .radio { color: #ffffff; } .AtJsMenuPopup td.arrow .sub { font-size: 14px; line-height: 14px; text-align: right; width: 100%; } .AtJsMenuSeparator { visibility: inherit; } .AtJsMenuSeparator .line { background-color: #233523; border-color: #738573; } tr.AtJsMenuSeparator td { padding: 1px 3px; } td.AtJsMenuSeparator { padding: 0px 5px; } td.AtJsMenuSeparator .line { height: 16px; }
Notice the second and the third rule, they make different style for the checkbox when the menu item is highlighted. So does the fifth rule which is for the radio button. Note, 'tr.AtJsMenuSeparator' is for horizontal separator line and 'td.AtJsMenuSeparator' is for vertical one.
Now, will be answered the question: how to set the different
elements for these signs to fit the theme. AT JsMenu script, when it's
loaded, searches five global variables, if any. These five global
variables are considered to hold the reference of the element check sign,
radio sign, sub sign, horizontal separator line and vertical separator
line. They must refer to the valid HTML element object. Otherwise, will be
ignored. The name of these variables are AtJsMenuCheckSign
,
AtJsMenuRadioSign
, AtJsMenuSubSign
,
AtJsMenuHorizontalSeparatorSign
and AtJsMenuVerticalSeparatorSign
.
So, if you want the different appearance for those signs then define
the appropriate HTML element and assign its reference to the the
appropriate global variable before inserting AT JsMenu script.
Note, the element you create, needs not to have attribute class
set to 'check' for check sign, 'radio' for radio sign, 'sub' for sub sign
and 'line' for separator line. You may assign the other class
name, providing that you define the appropriate style. To make more clear, a
piece of HTML code below shows how you can set your theme.
<link href='your-theme.css' rel='stylesheet' type='text/css' /> <script language='JavaScript' type='text/javascript' src='signs.js'></script> .... .... <script language='JavaScript' type='text/javascript' src='AtJsMenu-dir/AtJsMenu.js'></script>
File 'signs.js' contains five global variables explained before. It may not only these. In this file also, can be defined the other element which fits your them but specific for your application, such as folder icon.
The table below will help you to find what have to change in your stylesheet if you use the older version and want to upgrade to new version. The table below shows which selectors are the same each other.
Older than version 1.3 | Version 1.3 |
---|---|
.AtJsMenuBarItem |
.AtJsMenuButton |
.AtJsMenuBarItem-hover |
.AtJsMenuButton-hover |
- | .AtJsMenuButton-select |
.AtJsMenuBarItem-select |
.AtJsMenuButton-select-hover |
.AtJsMenuBarItem#AtJsMenuBarIcon |
.AtJsMenuButton-icon |
.AtJsMenuBarItem-hover#AtJsMenuBarIcon |
.AtJsMenuButton-hover-icon |
.AtJsMenuBarItem-select#AtJsMenuBarIcon |
.AtJsMenuButton-select-hover-icon |
.AtJsMenuItem |
.AtJsMenuItem |
.AtJsMenuItem-select |
.AtJsMenuItem.hover |
.AtJsMenuItem-separator |
tr.AtJsMenuSeparator (horizontal) |
- | td.AtJsMenuSeparator (vertical) |
Older than version 1.4 | Version 1.4 |
- | .AtJsMenuButton-select-hover-armed |
- | .AtJsMenuButton-disabled |
- | .AtJsMenuButton-hover-disabled |
- | .AtJsMenuButton-select-disabled |
- | .AtJsMenuButton-select-hover-disabled |
- | .AtJsMenuItem.disabled |
- | .AtJsMenuItem.hover.disabled |
Close to the title of this section, firstly we look at how to embed AT JsMenu stuff. The HTML code will look like.
<link href='AtJsMenu-dir/AtJsMenu-default.css' rel='stylesheet' type='text/css' /> <script language='JavaScript' type='text/javascript' src='AtJsMenu-dir/browser.js'></script> <script language='JavaScript' type='text/javascript' src='AtJsMenu-dir/AtJsMenuKeys.js'></script> <script language='JavaScript' type='text/javascript'><!-- if (navigator.family) { document.writeln(">"+"script language='JavaScript' type='text/javascript' src='AtJsMenu-dir/compat-"+navigator.family+".js'"+"><"+"/script"+">"); } //--> </script> <script language='JavaScript' type='text/javascript' src='AtJsMenu-dir/AtJsMenu.js'></script>
The first line, we insert the css file needed by AT JsMenu or your own theme.
We also must insert script file 'browser.js'. This script is to check what browser
is being used. After this script is executed, the object navigator
will have new property, that is family
. This property hold the string
identifying the browser. Its value is one of 'Gecko' for gecko browsers (Netscape,
Firefox etc.), 'IE6' for Internet Explorer and 'Opera7' for Opera. After inserting
'browser.js' then insert file 'AtJsMenuKeys.js'. This script file is needed by the
other script files to check if the keyboard handling is supported.
Then insert file 'compat-[browser].js'. '[browser]' here is the value
of navigator.family
. This file contains script which is specific for
the current used browser. It's to make the compability between browsers. After that,
you're free to insert the main script file, that is 'AtJsMenu.js'.
Actually, the main issue will be discussed in this section, is the
possibility of crash between AT JsMenu script and the script created by
yourself or taken from the other stuff. It's too naive if considered that
your web page only uses AT JsMenu. The other widget may also be interesting
to use. The crash here means there is a global identifier (class, global
variable or function) whose the same name. AT JsMenu names its global identifiers
with prefix 'AtJsMenu'. We can think that the name of widget is unique, so if
prefixed with its name then the crash will not happen. But not all global
identifier is prefixed with 'AtJsMenu'. Especially the script inside the file
'compat-[browser].js' (see section 4.12. Global Functions).
The additional property/method attached to the standard objects that are
commonly used, may also make the crash. To make compability between browsers,
AT JsMenu emulates some features, such as method document.addEventListener
for Internet Explorer, method contains
for Gecko and some properties of
object event that is created for Gecko to emulate the same property in Internet
Explorer, etc. You should check these files ('compat-[browser].js').
This main issue must you keep in mind when you create a DHTML application that uses some widgets from several authors.
When there is no highlighted/focused menu item, we need to highlight an item on
menu bar. Usually, the Alt key is used to highlight the first menu on menu bar.
Of course, it's also used to highlight the browser menu. Because Alt key is used
by the browser, AT JsMenu uses Ctrl+Alt or Shift+Alt key to highlight the first menu
on menu bar (press Ctrl/Shift key and hold then press Alt key and then release it. After Alt key
is released, the first menu on menu bar will be highlighted). You must ensure the
HTML document gets the focus in order for the keyboard handling will run. The browser
window has focus doesn't mean the HTML document has focus. Another component on window,
such as location bar, may have the focus. Sometimes, Firefox doesn't respond Ctrl+Alt.
Use another combination. On IE, Shift+Alt will still highlight the browser's menu.
To move the highlighted menu on menu bar, press left/right arrow. To open the child
menu list of the highlighted menu on menu bar, press up/down arrow or Enter. To
navigate the menu item inside the menu list, use up/down arrow. To open the child menu
list of a sub menu, press Enter or right arrow. To close it, use left arrow. Escape
key can be used to close the last opened menu list. Independent popup menu can also
handle keyboard. When the popup menu appear, it gets the focus.
Since version 1.2, AT JsMenu supports mnemonic and accelerator/shortcut key. The mnemonic key is usually a characther taken from the menu item's text. It will be underlined to show that it is the mnemonic. The mnemonic key is an alternative way to navigate the menu hierarchy and to select a menu item. Depending the GUI environment, the way to use mnemonic key possibly differs. But usually, to select the top menu, it will need the Alt key pressed together with mnemonic key. For the other menus, it may use Alt key or not. A menu item can be selected if it is inside the last opened menu list. AT JsMenu uses somewhat different way to use mnemonic key. It's to avoid conflict with the browser menu itself. Yet, there is still the possibility the conflict with the shortcut key of browser menu. To select the top menu in AT JsMenu, press Ctrl+Alt or Shift+Alt beside the mnemonic key. For the other menus, only press the mnemonic key without Alt/Ctrl/Shift.
Shortcut key is to select a menu item without navigating the menu hierarchy. So the menu item can be selected even if it is not visible. By pressing the shortcut key, it will do the action as if the menu item is selected by clicking it. The shortcut key will be displayed on the right side of the menu item. To design the keyboard handling for AT JsMenu must consider the keys that has meaning for the browsers itself so it will not happen the conflict.
In AT JsMenu package, there is a file named AtJsMenuKeys.js. This file contains
the constants that represent the key code values. It only considers the PC keyboard.
May be in future, there will be an extension. The contants are the same as the
constants owned by Event
object in Gecko browser. These constants is
used to make the compability between browsers. Opera key codes is not compatible with
the other browsers, even between each versions of itself. And also in recent version,
Opera will return 0 for some extended keys.
It's intended for everyone who doesn't want to write the script. Using XML
dataset may be more readable. But still you must write the script for
event handler. We don't have any idea to know what you want if
you don't write the script. HTML datase is an alternative way of XML dataset.
It's contains standard HTML tags. AT JsMenu supports two ways
of how this dataset is stored. The first way is to be embedded in HTML document.
This dataset should be stored inside an HTML element that is not displayed (its
CSS property display
is set to none
). The second one is
only for XML dataset, which is stored in separate file which will be loaded then
by XMLHttpRequest
object.
For the fisrt way, even if it's embedded in HTML document but if you
use server side script like PHP, you can separate this XML dataset and share it
among several modules. For instance, 'menu-content.xml.inc' is included in
'popup.xml.php' file.
In turn, this XML/HTML dataset can be used by a menu builder.
This section describes XML dataset which is embedded in HTML document. Also it explains all elements and attributes of the dataset. Opera doesn't support XML dataset embedded in HTML document.
Things Needing to Note about This XML Dataset
- This XML dataset must be written inside xml
element.
It's needed by IE to create XML data island.
- Even if some elements is defined as empty element, such as separator
,
you may not write it to be <separator />
but must be
<separator></separator>
. Firefox will fail to parse them
in this condition.
- IE will use true xml parser. Take care about XML entity characters that may be
used in attribute values. We usually use '&
' (and), '<
' (less than) and
'>
' (greater than) operators in javascript statement for onclick
attribute. Remember always to replace them become &
, <
and >
respectively. Not all HTML entity characters is valid in XML if we don't
define them in DTD. Use their keycode if you want to use these characters, for example,
use  
to write
(non breaking space).
The other entity characters may be used in XML dataset is "
for double quote and '
for single quote.
- Don't use standard HTML elements inside this XML dataset. Firefox will fail to
parse this XML dataset.
Elements and Their Attributes for AT JsMenu XML Dataset
AtJsMenu
HTML
in HTML document. This elments
has some attributes to set global properties. Those are:
chunkpersizeopen
chunkPerSizeOpen
property.
cookiedisabled
isCookieEnabled
property become false
.
delayopen
delayOpen
property.
onclick
onclick
event handler.
Note, the value of this attribute is the function body. Variable e
has
been declared to be the parameter of event. Use it in the function body.
zindexmin
setZIndexMin
method.
The value of this attribute will be the parameter for the method.
menubar
AtJsMenu
element.
Its attributes are:
contid
sId
parameter of
AtJsMenuBar
constructor.
icon
icontype
attribute.
icontype
icon
attribute is set.
If the value is 'class' then icon
attribute
value is the class name and then the icon will be created from a DIV
element which its class
attribute is set to the value of icon
attribute. If the value is 'image
' then icon
attribute
value is the image file path and then the icon will be created from a IMG
element which its src
attribute is set to the value of icon
attribute. The default value is 'image'.
varname
popup
AtJsMenu
element.
Its attributes are:
varname
varname
.
atjsmenulink
link
element in HEAD section. It's specially to load CSS file.
Useful for customizing theme.
All attributes of this element will become the attribute of the link
element.
Valid if it becomes the child of AtJsMenu
element. It's empty element.
atjsmenuscript
script
element. Useful to add additional script.
All attributes of this element, except later
, will become the attribute
of the script
element. Valid if it becomes the child of AtJsMenu
element. If later
attribute is set, it may contain javascript statements. The
javascript statements must be covered by comment tag (<!-- -->
).
If later
attribute is not set, it's the empty element and the script
element will be inserted in HEAD section.
The attributes are:
later
subsign
x
, for example, div
becomes
xdiv
. See the example in 'menu-content.xml.inc' file.
This element is valid if it becomes the child of AtJsMenu
element.
checksign
subsign
element but
for the check sign.
radiosign
subsign
element but
for the radio sign.
horizontalseparatorsign
subsign
element but
for the horizontal separator line.
verticalseparatorsign
subsign
element but
for the vertical separator line.
menudir
AtJsMenu
object).
Valid if it becomes the child of menubar
, popup
or another menudir
element. All menuitem
,
separator
and menudir
elements which are contained
within this element will become the child menus of this element.
Its attributes are:
description
description
property.
descattrname
descAttrName
property.
icon
icon
.
icontype
icontype
.
isdisabled
isdisabled
.
mnemonic
onchange
onchange
.
onclick
onclick
.
text
or label
text
property.
varname
varname
.
separator
menubar
, popup
or menudir
element.
menuitem
menubar
, popup
or menudir
element. It's an empty element.
Its attributes are:
accelerator
AtJsMenuKeys
object without 'DOM_VK_
'. The attribute value is incase sensitive.
description
description
property.
descattrname
descAttrName
property.
icon
icon
.
icontype
icontype
.
isdisabled
true
or false
. Empty string is
false
.
isselected
or selected
selected
is for backward compability.
To set the initial state for the checkbox or radio button whether it's checked
or not. The value of this attribute will be evaluated as javascript statement
that will yield true
or false
. Empty string is
false
.
mnemonic
name
onchange
onchange
event handler.
Note, the value of this attribute is the function body. Variable e
has been declared as the event parameter. The this
keyword refers
to the current menu component object. See
onclick
.
onclick
onclick
event handler.
The value of this attribute is the function body. Variable e
has been declared as the event parameter. The this
keyword refers
to the current menu component object. It's usual that some menu items have the
same process for this event. Instead of rewriting the same javascript statements for
those menu items, it's better to make a function that will be invoked from each
menu item's event handler. But you must take care about the parameter of that
function. Here is the example will be the guide. Consider, in XML Dataset area,
defined this menu item<menuitem onclick="clickMenu(e,this)" ...>
clickMenu
function. In the
script area, we define this functionfunction clickMenu(e,oMenu) {
...
}
text
or label
text
property.
type
value
varname
varname
.
How To Parse XML Dataset
Just a little touch after you define the XML dataset, the menu
component objects will be created by calling the parser. See the
code below.
<xml id="menuContent" style="display:none"> <AtJsMenu delayopen="10"> ..... <!-- menu components --> </AtJsMenu> </xml> <script language='JavaScript' type='text/javascript' src='../AtJsMenuXmlDataset.js'></script> <script><!-- new AtJsMenuXmlDataset('menuContent'); //--> </script>
The statement new AtJsMenuXmlDataset('menuContent');
is to execute the parser.
The parameter is the id of xml
element in which the menu XML dataset is
defined. This xml
element should not be displayed.
Note, the order of menu components are the same as their order in XML dataset.
In other words, if you use the script then you'll never use insert
and insertSeparator
method.
Basically, HTML Dataset is the same as XML Dataset, all elements and attributes will be the same. But the elements are made of the standard HTML tags. So, this section will only explain what HTML tags used. For Opera, HTML dataset is supported since version 8.
This table below shows what the same elements are:
XML | HTML |
---|---|
AtJsMenu |
div whose name attribute set to 'root ' |
atjsmenulink |
div whose name attribute set to 'link ' |
atjsmenuscript |
div whose name attribute set to 'script ' |
subsign |
div whose name attribute set to 'subsign ' |
checksign |
div whose name attribute set to 'checksign ' |
radiosign |
div whose name attribute set to 'radiosign ' |
horizontalseparatorsign |
div whose name attribute set to 'horizontalseparatorsign ' |
verticalseparatorsign |
div whose name attribute set to 'verticalseparatorsign ' |
menubar |
form whose name attribute set to 'menubar ' |
popup |
form whose name attribute set to 'popup ' |
menuitem |
input |
menudir |
fieldset |
separator |
hr |
Things Needing to Note about This HTML Dataset
- Because of the way of some browsers in treating standard attributes,
use isselected
instead of selected
,
use label
instead of text
and
use the value of 'checkbox
' for type
attribute
instead of 'check
'.
- Don't use HTML entity character for script statement in event handler attribute,
such as onclick
.
- For sign elements (subsign
, checksign
, radiosign
,
horizontalseparatorsign
and verticalseparatorsign
),
the HTML elements tag inside them are not prefixed by x
.
How To Parse HTML Dataset
Parsing HTML Dataset is similar with parsing XML Dataset,
only different parser which is used.
Look at the example below.
<div id="menuContent" style="display:none"> <div name="root" delayopen="10"> ..... <!-- menu components --> </div> </div> <script language='JavaScript' type='text/javascript' src='../AtJsMenuHtmlDataset.js'></script> <script><!-- new AtJsMenuHtmlDataset('menuContent'); //--> </script>
Remote here means that the XML Dataset is stored in separate file, not embedded in HTML document. For Opera, Remote XML Dataset is supported since version 8. All elements and attributes are the same as before, need not to explain anymore. Here, will only explain how to parse Remote XML Dataset. Look at the example below.
<script language='JavaScript' type='text/javascript' src='../AtJsMenuRemoteXmlDataset.js'></script> <script language='JavaScript' type='text/javascript'><!-- var oParser = new AtJsMenuRemoteXmlDataset(sXmlUrl,fOnReadyCallBack); //--> </script>
The statement
var oParser = new AtJsMenuRemoteXmlDataset(sXmlUrl,fOnReadyCallBack);
is to parse the XML Dataset file. The first parameter is the URL of XML dataset. The second one
is the function that will be executed after all menu components are created. The parser uses
asynchronous call, so that this function very useful if there are some scripts that must be
executed after the menu objects are available. The second parameter is optional.
From the above code, oParser.onready
will be the same as fOnReadyCallBack
.
Things Needing to Note about This Remote XML Dataset
- Becuase remote, it's enough for you to refer to XML 1.0 Specification to create
a valid XML document. No additional notes like if it is embedded in HTML document.
DTD may be arranged in the next release.
- Only one instance object of the parser can be created. The next release may allow
multiple instances.
AtJsMenuLoader
Still experimental. Boring to insert many script files to create menu components,
AtJsMenuLoader
will do it at once. AtJsMenuLoader
needs
Remote XML Dataset. For Opera, it's supported since
version 9. Here is the example how to use it.
<script language='JavaScript' type='text/javascript' src='/js/AtJsMenu/AtJsMenuLoader.js'></script> <script language='JavaScript' type='text/javascript'><!-- var oLoader = new AtJsMenuLoader(); //Create the loader oLoader.AtJsMenuBasePath = '/js/AtJsMenu'; //Set the dir where AT JsMenu script files exist oLoader.sourceData = 'http://localhost/xml/menu-content.xml'; //Sets the url of Remote XML dataset oLoader.onready = function() { //Statements to execute when all menu components has been avalaible }; oLoader.load(); //Load all needed script files and parse the XML dataset //--> </script>
Only one instance object of the loader that can be created. See 'AtJsMenuLoader.htm' in the example.
Send bugs report to atmulyana@yahoo.com. Tell the exact version of your browser and on what operating system you found the bugs. Your contribution will make this library better.
In future, AT JsMenu will have the following features:
- The layout of the menu bar can be customized. The menu items on the menu bar can be
arranged vertically beside horizontally. The menu bar can also be placed on the
top, right, bottom or left side of the document area.
- The icon can be shown for the top menu (it seems the menu bar will be the tool bar).