3. Implementing the script
The script is configured using two object constructors.
The first is a control function called
which looks after cookie persistence
and controls the API;
the second is a group constructor called
which defines behaviors and properties for each group of docking boxes.
For a given page or application you would have a single instance of the manager,
controlling any number of groups.
The preferred technique is to put the configuration file at the very
end of the
<body> section. This avoids the need to use any kind of
load wrapper, and consequently also avoids the
possibility of a
flash of unsorted content, that might otherwise occur in
some browsers (the momentary appearance of the boxes in their
original order, before any cookie state is applied).
However, if you do want or need to have the
configuration file in the
section, then you must use a load wrapper around the constructors.
For this you can a regular
window.onload, or, better,
you could use a scaleable solution such as my
domFunction helper or
generic onload script.
dbxManager constructor takes four arguments:
//initialise the docking boxes manager var manager = new dbxManager( 'main', // session ID [/-_a-zA-Z0-9/] 'yes', // enable box-ID based dynamic groups ['yes'|'no'] 'yes', // hide source box while dragging ['yes'|'no'] 'button' // toggle button element type ['link'|'button'] );
- session ID [string]
The session ID is used to differentiate groups of docking boxes from each other; the value is used as part of the cookie name, and is so that you can use the script in multiple places within the same site, for completely different things, without those instances interfering with each other.
This value can only contain letters, numbers, dash or underscore.
- enable box-ID based dynamic groups ["yes" or "no"]
This setting controls whether the script should use the
IDattributes of boxes to refer to them internally, or whether it should create and assign a
If you have this set to
"yes"then you don't have to assign
IDattributes to the boxes — the script will still create
IDattributes are not found.
If you want to be able to add or remove boxes mid-session (for example, by loading new data using Ajax) then you will need to assign
IDsto those boxes, and therefore you must have this value set to
"yes". (Have a look at the Ajax-controlled group demo to see this in action.) Therefore, given that a value of
"yes"still works even if
IDattributes are not used, you may as well leave it set to
"yes"all the time.
The only reason this setting exists at all is that, when enabled, it will validate
IDattributes and throw an exception for invalid values. Since this setting was not present in version 2, setting it to
"no"will ensure backward compatibility with previous installations that may have had
IDattributes used for your own purposes that the script would consider invalid.
- hide source box while dragging ["yes" or "no"]
When you move a box, what you're holding with the mouse, and what you see animated when movement occurs, is a clone of the original box, not the original box itself. The original box never leaves its position in the group, and is merely hidden whenever the clone is created. If this value is set to
"no"then the original box will remain visible all the time.
- toggle button element type ["link" or "button"]
The toggle button is the element that allows you to open and close a box, revealing and hiding its content area, and is dynamically generated by the script. This value allows you to control whether this should be a
<a>element) or a
I would recommend using a button element, because doing so makes for cleaner output (no need to have a junk
hrefvalue) and better semantics — since the toggle element is, conceptually, a button, not a hyperlink. Better semantics in turn means better usability to assistive devices.
dbxGroup constructor takes
sixteen arguments in total —
seven for controlling the layout and behaviors, and nine
which define the language for informational tooltips:
//create new docking boxes group var purple = new dbxGroup( 'purple', // container ID [/-_a-zA-Z0-9/] 'vertical', // orientation ['vertical'|'horizontal'|'freeform'|'freeform-insert'|'confirm'] '7', // drag threshold ['n' pixels] 'no', // restrict drag movement to container/axis ['yes'|'no'] '10', // animate re-ordering [frames per transition, or '0' for no effect] 'yes', // include open/close toggle buttons ['yes'|'no'] 'open', // default state ['open'|'closed'] 'open', // word for "open", as in "open this box" 'close', // word for "close", as in "close this box" 'click-down and drag to move this box', // sentence for "move this box" by mouse 'click to %toggle% this box', // pattern-match sentence for "(open|close) this box" by mouse 'use the arrow keys to move this box. ', // sentence for "move this box" by keyboard 'press the enter key to %toggle% this box. ', // pattern-match sentence-fragment for "(open|close) this box" by keyboard '%mytitle% [%dbxtitle%]', // pattern-match syntax for title-attribute conflicts 'hit the enter key to select this target', // confirm dialog sentence for "selection okay" 'sorry, this target cannot be selected' // confirm dialog sentence for "selection not okay" );
Layout and behaviors
- container ID [string]
IDof the main group container element (the
"dbx-group"). This value can only contain letters, numbers, dash or underscore.
- orientation ["vertical", "horizontal", "freeform", "freeform-insert", "confirm", or "confirm-insert"]
For linear (one-dimensional) orientations, specify either a
"vertical"column or a
For grid-based (two-dimensional) orientations, specify
"freeform"for movement in which boxes are swapped over when moved, or
"freeform-insert"for movement in which one box is inserted before another when moved. Freeform orientation works best with boxes which are roughly square. They don't have to be exactly square, but the more rectangular they are (ie. the greater the difference in length between their horizontal and vertical sides) the more difficult it will be for the script to find a swap or insertion target. You may find for boxes which have a very high difference ratio, approaching 1 in 10 or more, that target finding does not work at all.
Freeform orientation create immediate sorting movement, in which repositioning happens continually as you move a box. But if you want delayed sorting movement, in which repositioning only occurs when you let go of the mouse (or press Enter with the keyboard), you can specify
"confirm-insert"(for the same two sorting options). The notes regarding box shape apply equally to confirm-based orientation as they do to freeform.
When you use a confirm-based orientation, dragging the box will create so-called
dialogelements in place of immediate movement — a second box will be created directly above the target box that would otherwise be the swap or insert-before target. The dialog is an empty clone of the underlying box (a copy of the box with no content) and can be styled to suit your preference, for example, as a solid or dotted border. For more about styling, please see Writing the CSS framework. For keyboard users, the dialog will also have title text that indicates its purpose and tells the user what to do, for example
hit the enter key to select this target.
The dialog element will also have a further class name (and modified title text) when used in association with the rules engine, to indicate whether the target movement is allowed. Apart from the title text, which only appears for keyboard users, the
classname is the only way in which allowed movement is indicated, so it's up to you to ensure that it appropriately indicates this. Again, see Writing the CSS framework for more about this, and see the rules engine demo for an example.
The following demos show each of the main orientations in action, and you may like to use them as the basis for your implementation:
- drag threshold [number]
The drag threshold is the amount by which you have to move your mouse after clicking down, before a drag action is initiated. This is so that handle elements can also be links without a conflict — nobody keeps the mouse perfectly still when clicking a link, and without this discrimination it would not be possible to combine both functions in a single element.
The drag threshold also manifests as a
stickinessaround the origin of each box.
- restrict drag movement to container axis ["yes" or "no"]
For linear (vertical or horizontal) orientations, if this is set to
"yes"then the draggable element's position will only be updated in the direction of its container orientation: horizontal boxes only go left and right, vertical boxes only up and down — giving the impression that movement is restricted to that direction. If set to
"no"then draggable elements can move freely.
For grid (freeform or confirm) orientations, setting this value to
"yes"means that the center-point of the box you're moving cannot go outside the group container. If you attempt to do so, the box will be dropped back to its previous position.
- animate re-ordering [number]
This value defines how many frames of movement occur with each box animation.
An animation is either a re-ordering of the boxes from mouse dragging, or a re-positioning of the boxes from keyboard navigation; a frame is a
setTimeoutloop. So for each animation the timeout will loop n times, moving the object by its own dimension over n each time.
Lower values give a faster but jerkier effect; higher values look smoother but are more CPU intensive, therefore slower. As with all such things, there's a good balance to be found somewhere between the two.
If you specify a value of
"0"there will be no animation, just snap movement.
- include open/close toggle buttons ["yes" or "no"]
If this is set to
"yes"then each handle will have a toggle element appended to it (a link or button, depending on the value of toggle button element type), and these will be used as open/close toggles, and as the focus-anchors for keyboard navigation. They can be styled to create the appearance of buttons, as described in the chapter Writing the CSS framework.
If this is set to
"no"then toggles are not included, and therefore the content area will not be controllable; the
"no"setting is intended for applications like the buttons demo, where the handle is the entire box and there is no content area.
In that situation the script will attempt to bind
focusfunctions to the handle elements themselves, and use those as the anchors for keyboard navigation. Therefore if you're not including toggles, the handles should be focusable elements (such as links or form controls), otherwise the interface will not be accessible to the keyboard.
You can also create the toggle buttons manually, and have the script bind its handlers to those. If you do this, this setting must still have the value
"yes", or the event handlers will not be added.
- default state ["open" or "closed"]
Specify whether the boxes in the group should be
"closed"by default. A value of
"closed"will only be honoured if you've included toggle buttons.
Language for informational tooltips
The script creates informational tooltips for both mouse and keyboard users, with summary instructions for using the interface. These tooltips are particularly important for keyboard users, because de-facto conventions do not exist already.
The tooltips are created from the language and grammar you define in these arguments:
- word for "open", as in "open this box" [string]
Define a word that means to open the box, used in conjunction with the pattern-match sentences below.
- word for "close", as in "close this box" [string]
Define a word that means to close the box, used in conjunction with the pattern-match sentences below.
- sentence for "move this box" by mouse [string]
Specify a plain sentence for the text of mouseover tooltips on handle elements, which describe how the drag action works.
- pattern-match sentence for "(open|close) this box" by mouse [string]
Specify a pattern-match sentence for the text of mouseover tooltips on toggle buttons, describing how the open/close action works.
%toggle%token refers to the word for "open" or "close", so you can move that token around within the sentence to acheive the appropriate grammar.
- sentence for "move this box" by keyboard [string]
Specify a plain sentence for the text of focus-activated tooltips on keyboard anchors, describing how the move action works.
If toggle buttons are not in use, this sentence will be the whole tooltip.
- pattern-match sentence-fragment for "(open|close) this box" by keyboard [string]
When toggle buttons are in use, define a sentence-fragment used to supplement the text of focus-activated tooltips, describing how the open/close action works. This text will be added immediately after the "move this box" text, so that the two fragments can be structured together to form a single sentence.
%toggle%token refers to the word for "open" or "close", so you can move that token around within the sentence-fragment to acheive the appropriate grammar.
This and the previous sentence may appear individually, or they may appear one after the other (this one second), depending on whether the box has toggle buttons.
- pattern-match syntax for title-attribute conflicts [string]
If an element which requires an informational tooltips already contains
titleattribute text, this pattern-match determines how the conflict is handled.
%mytitle%refers to the existing
titleattribute; the token
%dbxtitle%refers to the informational text generated by the script; the other formatting determines the overall construct.
So you could, for example, set a value of
"%mytitle%"to specify that the original title should be preserved unchanged; or conversely you could specify
"%dbxtitle%"to overwrite existing titles completely. But the best solution is probably a formatted mixture of both, as I've done in the demos.
- confirm dialog sentence for
When you use a confirm-based orientation, the dialog elements will have title text for keyboard users that indicate whether or not the target is allowed. Targets are always allowed unless you're using the rules engine, therefore this value will be used most often, and your phrasing should not imply differently.
- confirm dialog sentence for
selection not okay[string]
If you're using the rules engine and a target is not allowed, this sentence will be used instead.