Dijit Functional Spec

The information here was used when designing and building Dijit. It may be out of date.

Dijit Philosophy

The Dojo Widget system has shown tremendous success, to the point that to many users "Dojo" is synonymous with the dojo widget system.   In particular, it's been successful because of the widget template system and the parser, which allow developers to rapidly develop new widgets, and allow users to rapidly add widgets to their applications.    It's also successful because of the many widgets in our library, including simple widgets like ComboButton to more complex widgets that even approach applications, like the Show (aka Powerpoint) widget.


There have been a some downsides to this development though:

In order to tame the beast that is widgets,  the widgets have been split off into a project of their own.  The main emphasis on the release will be speed, code footprint, and quality.  In order to achieve this, only a subset of the existing widgets will be supported (more on this later).   And also, only a subset of the existing infrastructure will be supported.   Many seldom used features will be dropped.

Goals

Non-goals

Dijit Basics

This page lists general info about how to use dijit. The info for individual widgets is on separate pages.

Supported Features

Supported browsers

We're dropping support Konqueror because it doesn't have a big enough install base to warrant our time supporting (coding and testing) it, nor do we want to increase code size/complexity in order to support it.

Opera won't be supported either, at least not for the 0.9 release.

A11Y

For Release 1.0 all core widgets will:

Exceptions

Dijit Styling/Theming

Goals

The goals of our widget design, w.r.t styling, in order, are:
  1. A11Y usability: the widgets don't have to look pretty in screen high-contrast mode, but they need to be usable. We aren't particularly concerned with jagged edges etc. due to users increasing the browser magnification.
  2. Prepackaged tundra theme should look pretty but render quickly. Prettiness outweighs ease of customization, so that we'd consider using images even though that requires customization via image editing rather than just setting CSS rules.
  3. Support trivial customizations like fonts, colors, background images, foreground images, etc., just setting CSS rules and editing images. Note that this rule implies that all image paths (even things like arrows) occur in the CSS file, and then are transferred to <img> nodes for accessibility reasons.
  4. More complicated styling, such as making rounded borders, requires users to modify the widget templates and/or javascript code. We aren't bending over backwards to make this kind of customization easy.
  5. Dijit comes prepackaged with a theme called Tundra, which is a set of CSS rules and images to provide a standard look and feel to all the dijit widgets.
  6. Users can design their own themes, and can use multiple themes on one page (each applying to a certain section of the page, like left and right.) This is not a rule so much as a design pattern that's possible due to rule #2 above.

CSS

Styling of widgets is done completely by CSS.   You can use any CSS that you want to style the widgets.  You just define rules like

.dojoButton { ... }

There's a small dijit.css file to define essential CSS stuff, but there's no default styling CSS included into a page automatically, so the user has to define something. The user can either write their own CSS, or more typically, include and use one of the predefined "themes":

Tundra theme

Dijit comes prepacked with a theme called "tundra".   It's called a theme since it's a common look and feel for all widgets, but it's just a bunch of CSS and images:

themes/
   tundra/
       tundra.css	<-- all the CSS for all the widgets
       checkbox.gif	<--- all the checkbox and radio button images
       fader.gif	<--- background image referenced by tundra.css
A preview of tundra lives here

The foreground images are located in the theme directory (along with background images) and are referenced from the widget via CSS rules (via the background-image property of a dummy node).

The tundra.css file has rules like:

.tundra .dojoButton { ... }

You don't have to use the tundra theme, but most people probably will.  To use tundra theme for all widgets on your page, do:

<link rel=stylesheet href="dijit/themes/tundra/tundra.css" type="text/css">

(right after including dijit.js)
And then add a theme name to the <body> element, like:

<body class=tundra> 

The reason the tundra theme requires a class=tundra on the body tag (or some other tag) is because the rules all list a hierarchy like ".tundra .dojoButton".

Using multiple themes

Dijit will eventually have multiple themes in the theme directory.   You will be able to include additional CSS files into your document, like:

<link rel=stylesheet href="dijit/themes/gloss/gloss.css" type="text/css">

gloss.css will define rules like:

.gloss .dojoButton { ... }

so it won't conflict with tundra.css.

To have different sections of your document that are different themes, you just change the class of each section.   For
example, to make the main document tundra theme, but then have sections that are blackGloss and whiteGloss theme, do:

<body class=tundra>
...
	<div dojoType=dijit.layout.TabContainer>
		<div dojoType=dijit.layout.ContentPane label=Tab1 class=blackGloss>
			<input dojoType=dijit.form.TextBox>
			<button dojoType=dijit.form.Button>
			...
		</div>
		<div dojoType=dijit.layout.ContentPane label=Tab2 class=whiteGloss>
			<input dojoType=dijit.form.TextBox>
			<button dojoType=dijit.form.Button>
			...
		</div>
	</div>
...
</body>

All the widgets in the first tab will have the blackGloss theme and all the widgets in the second tab will have the whiteGloss theme.

Overriding a theme

You can also define a variation on a theme (much like Handel). Let's say that you like the tundra theme but for each tab above, just want to change the background color of the form widgets. You would define yellowForm and blueForm to just change the background color:

<style>
  .yellowForm .dojoButton, .yellowForm .dojoInputField { background-color: yellow; }
  .blueForm .dojoButton, .blueForm .dojoInputField { background-color: blue; }
</style>

Then you would reference the override class in a similar way to above:

<div dojoType=dijit.layout.TabContainer>
	<div dojoType=dijit.layout.ContentPane label=Tab1 class=yellowForm>
		<input dojoType=dijit.form.TextBox>
		<button dojoType=dijit.form.Button>
		...
	</div>
	<div dojoType=dijit.layout.ContentPane label=Tab2 class=blueForm>
		<input dojoType=dijit.form.TextBox>
		<button dojoType=dijit.form.Button>
		...
	</div>
</div>

The two tabs would then be tundra theme except for the background color on form fields

Developing your own theme

If you want to develop your own theme, like blackGloss and whiteGloss above, just make rules like

.myTheme .dojoButton { ... }

and include them into your page somehow.

Note that a widget like Checkbox displays the checkbox image using an <img> tag.   However, it grabs the image location from the CSS. 

The class names used on widgets will never change based on the theme, although they will change based on the state of the widget.  for example, an input field will have class="dojoInputField", but a disabled input field will have class= "dojoInputField dojoInputFieldDisabled"

Applying style directly to a widget

Users apply styles to plain dom nodes in various ways:

<div style= "margin: 30px;">...
<style>
   #xyz { margin: 30px; }
</style>
<div id= "xyz">

<style>
   .myClass { margin: 30px; }
</style>
<div class= myClass>

The first two techniques should work for widgets also.  However, the third technique is not likely to work, because the style rules like ".tundra .dojoButton" will take precendence.

Dijit CSS Documentation

For the ones who want to get the real insight into the CSS depths of the dijit widgeting system, following pages are a good place to start. These docs are work in progress.

Form Widgets

All the form widgets support the standard form element attributes such as disabled, tabIndex, id, name, value, in addition to enable()/disable(), and getValue()/setValue(). Of course, changing any parameter value must be done via a method call rather than by just changing the variable value.

All form widgets can be added to a webpage inside a <form> tag, and their value is submitted when the form is submitted. Form reset doesn't work (at least for 0.9).

Some form widgets have the idea of the displayed value (in localized format), and the submitted value (in a standard format). For example, a DateTextBox in America will display 5/30/2007, but you create the widget like this:

<input dojoType=dijit.DateTextBox value=2007-5-30>
and also when you submit the form it will send 2007-5-30.

Buttons

Button

A plain button, similar to standard <button>.

Parameters

Public Methods

Accessibility

Same as standard HTML button.

Dropdown Button

A Dropdown button is a button that opens a menu when activated.

Parameters

Public Methods

Accessibility

Activating the button via a mouse click or pressing enter or space with focus on the button opens a menu below the button with focus on the first menu item. Pressing up or down arrow with focus on a menu item will cycle focus around through the menu items.  Press escape to close the menu and have focus return to the Dropdown button. Pressing tab will close the menu and set focus back to the button.

Mouseover on a menuitem sets focus to that menuitem.  Setting focus is necessary so that a screen reader or screen magnifier will work correctly.  Mouseout of the menu closes the menu and set focus back to the button.

The current Dojo Tundra theme includes only button text.  For those developers using an image for the button face information, a real img element should be used with appropriate alternative text. This will insure that a button with an image is still usable in high contrast mode and with the display of images turned off in the browser.


Combo Button

A combo button is a button with two behaviors - to activate a default action or to open a drop down menu. The drop down menu functionality is implemented as an arrow or other visual indicator within the button face.  Activating the main portion of the button executes the default action.  Activating the second portion of the button opens a drop down menu of actions.

Parameters

Public Methods

Accessibility

There are two tab stops within the combo button. One tab stop for the default button action and another for the portion of the button which opens the drop down menu. This implementation is more intuitive for the screen reader user as there is no explicit role to indicate a combination button.  The optionsTitle parameter is used to label this button so the screen reader use will know the purpose of the button.

Clicking in the default portion of the button will activate the default action. With focus on the default action portion of the button, pressing the space or enter key will activate the default action.  The second portion of the button behaves the same as a Dropdown button.

The default portion of the button has the ARIA role of button.  The dropdown button portion of the combo button has the ARIA role of button and the haspopup=true property.

The current Dojo Tundra theme includes only button text.  For those developers using an image for the button face information, a real img element should be used with appropriate alternative text. This will insure that a button with an image is still usable in high contrast mode and with the display of images turned off in the browser.

Toggle Button

A toggle button is the base class for Checkbox and Radio, and has methods like setSelected(boolean)

Checkbox, Radio

Checkbox

Parameters

Public Methods

Accessibility

Radio Button

Parameters

Public Methods

Accessibility

Combobox, FilteringSelect

Combobox

Like a textbox but it suggests values for you to type in.  No key/value dichotomy.   Interfaces to server via dojo.data interface.  Can also hardcode data into the HTML file via <select> <option> <option> ...</select> format. 

Combobox subclasses the Validation textbox so that it can display error messages if user types a wrong value

FilteringSelect

Has key/value dichotomy.

Examples

See test files (test_Combobox.html, test_FilteringSelect.html) for examples with inlined data or JSON data

Invalid values

If user types in an invalid value, and tabs away, we'll just leave the text they typed in the <input> box.   We won't erase the value, nor revert to the last good value, not ignore user keystrokes that cause the text to become invalid (ie, if the user types "californib" or "acalifornia", all the characters will go into the input box).

While this doesn't match the behavior of a browser's <select> or OS drop down, my judgement is that it's the best option, since we don't lose any data the user typed in.   It also works well with the asynchronous nature of dojo.data, which prevents us from immediately determining if a given string is valid or invalid.

(bug #3268)

Down Button

The down button will show all the available choices, so that mouse only users can still use something like a state select box. This is already the current behavior; no change needed.

There will be a widget parameter to show/hide the drop down button. (bug #3269)

autocomplete=true

This option is means that if you type a partial word (like "cal") and then tab away, it will fill in "California" from the drop down list.  It automatically completes your entry.

It doesn't refer to the display of the drop down list.  The drop down list always appears; there's no option to turn it off.   (The purpose of both these widgets is to have a drop down list.)

(bug #3268)

Drop down List and Placement

The drop down list auto-sizes according to the space available; it adds a scrollbar when necessary.

Since our drop downs auto-size to the space available, let's make the drop down always go below the <input> box, unless the space below the input box is really cramped (say, less that 100px).

(bug #3272)

TODO: option to limit the # of items displayed?  <a href="">Google suggests</a> only prints 10 items at a time.

Validation Tooltips

Validation error message will print tooltip to the right of the box (bug #3267)

Select Widget

At some point we will make a select widget similar to the browser's or OS's select boxes, but not 0.9. See bug #3270 for details.

Accessibility

The browsers focus is put into the  text field and the user starts typing. When a match/matches is found, a list of choices is displayed below the textfield that match the information typed into the textfied. As the user continues typing, the list of choices is updated to match what the user has typed.

If the user arrows down into the list of choices a choice is highlighted/selected, the entry in the textfield is updated to match the selected choice and the automatically completed characters are highlighted. As the user arrows through the choices, the textfield is updated, with the automatically completed characters highlighted. The screen reader will speak each choice.

Pressing the down arrow does not change what is displayed in the drop down list.

Pressing the escape key closes the list of choices and returns the text field to the value that the user had typed before selecting from the list of choices. Likewise, pressing the up arrow to move from the list of choices back to the text field returns the textfield value to the value that the user had typed before selecting from the list of choices. The textfield has focus and the caret is at the end of the entry ready for additional input. If the user has a choice selected and types an additional letter, the list of choices is closed and the auto-completed characters are replaced by the newly entered character.  Thus, in order to continue typing a different address after having selected one from the list, the user just continues typing. If the user presses enter with a choice selected, the browser closes the list of choices and navigates to the selected choice.

InlineEditBox

(never written... see test files)

Slider

Slider docs: http://www.dojotoolkit.org/developer/dijit/spec/slider

Goal: Port slider from trunk/0.4 to the new dijit structure. Fixing bugs along the way.

Slider is 2 different 'displays'. Vertical and Horizontal.

FUNCTIONAL CHANGES FROM 0.4:

  • Box layout is dead.
  • a new precise version (with display tick marks allow % and discrete #'s).
  • make it INTEGER only?

becka11y asks: the old version of the slider had a flip attribute to change the slider behavior? Will this still be supported? I vote for no since I think it is confusing but if flip is supported the keyboard behavior will have to flip as well to support.

Keyboard Navigation:

  • Left and down arrow should move the value lower, up and right arrow should move the value higher.
  • Shift+arrow keys, should 'speed up' movement, and make it go faster. (becka11y: is SHIFT the right key for this? becka11y thinks shift is fine but will double check)
  • HOME should go to the minimin value
  • END should go to the maximum value

Mouse Navigation:

  • Mouse wheel should move the slider up/down.
  • Clicking (or dbl clicking) should move the slider to the location the mouse was clicked.
  • Dragging the slider should move the slider.

API:

  • getValue() -- gets the current slider value as a 'number'.
  • setValue() -- sets the current slider value (and updates display) (must be a number)
  • setRange(min,max) -- sets the range allowed in the slider (both must be numbers.)
  • enable() -- turns widget on (default is on)
  • disable() -- turns widget off
  • valuemin -- the current minimum value allowed in the widget. (a11y support)
  • valuemax -- the current maximum value allowed.
  • valuenow/value -- the current value.

CALLBACKS:

  • onValueChanged() -- whenever a slider value is changed.

OPTIONS:

  • snapTo: BOOL if when moving the slider, it should remain in ticks. (only valid if scalePos is valid)
  • clickSelect: BOOL can the user click to select?
  • DragSelect: BOOL can the user drag to select values?
  • showButons: BOOL does the UI show the buttons on either side?
  • scalePos: enum string 'top','left','right','bottom' Display the scale where? Orientation is derived from top/bottom == horizontal, left/right == vertical. This makes valid combinations enforced.
  • valuemin: int the minimum value of the slider (this & maxRange is for parsed widgets.. see setRange())
  • valuemax: int the maximum value of the slider
  • animate: BOOL. slide the slider over, instead of jumping to the new value(when clicked for instance) (default: false)
  • stepIncrement: int --integer of how far when an arrow key, or an arrow button is pushed.
  • pageIncrement: int -- integer of how far when shift+arrow key is pushed (how to do with mouse?)

How to deal with Tick Marks, and Labels? Do we allow just tick marks, do we allow them to specify, or draw their own, or do we just do it ourselves however we see fit? Do we allow percentages and discrete numbers?

the spinner widget will deal with adjustments as well(increment/decrement some value.. should we play well with them?)

I've looked at QT and GTK, neither seem to have a good way to deal with the tick marks and labels. I'm going to play with an implementation and see what I come up with.

A11y Requirements

The slider needs to work in high contrast mode. Any CSS background images or colors are turned off in high contrast mode. Generally to support high contrast we need to use real images to represent at least the slider. This image should have alternative text (probably a + or X to represent the slider when images are turned off. An alternative to an image slider is to use an img button - the button text could have the actual slider value.

At least one of elements in the slider needs to have tabindex="0" so it is in the tab order. This element should receive the ARIA role of slider. The role can probably be set in the slider template. This element also needs the ARIA property values valuemin, valuemax, and valuenow. Valuemin and valuemax correspond to the slider min and max values, respectively. If min and max can be programmitically updated the valuemin and valuemax properties must be updated as well. The valuenow is the current silder value and must be updated via the dijit.util.wai.setAttr() api each time the slider value is updated via the mouse, keyboard or programmatically.

References:

Textarea

textarea that automatically changes size based on the content (like the Editor)

Textbox

Textbox

This is a standard textbox with various facilities for auto-correcting the input text (capitalization, etc), and hinting w/example values to type in.

TODO: hinting wasn't implemented for 0.9. Need it for 1.0

Validating Textbox

A Textbox that can take different regular expressions for validating many different patterns. Pops up an error message (like a tooltip) if there is an error.

Integer Textbox

Displayed value will be localized; user inputs localized value. But the value sent to the server is standard format like javascript numbers.

Currency Textbox

See currency checkbox comments above.

DateTextBox

Like DropdownDatePicker but vastly simpler; no parameters to widget (other than those in FormWidget.js (value, name, id, etc). No advance by week buttons. A stand alone calendar isn't supported. Allows manual input of date by typing. Includes validation if user types wrong date. Combination of Validating textbox and drop down.

Layout Widgets

These are the widgets that take over when layout out panes via CSS or tables doesn't get you far enough.

AccordionContainer

nothing written...

ContentPane

This is a stripped down version of the original Content Pane code.
Still can load from href but remove support for CSS and script mangling.

LayoutContainer

Positions panes at left/right/top/bottom/center.

SplitContainer

Horizontal or vertical set of panes where you can adjust the relative size of each pane.

StackContainer, StackController

Holds a set of panes only one of which is shown at a time.

TabContainer

Typical tab widgets, holding panes and showing one at a time.

Other Widgets

These widgets don't fall into a category so they are in the dijit.* namespace.

ColorPalette

(nothing written)

Dialog

Looks like ModalFloatingPane. You can move the dialog box and close it with an [X]. The dialog box sizes automatically to the content, unless you specify a width and/or max-height.

Editor

Nee Editor2. Editor needs to have auto-size mode but also be able to set a fixed size via style attribute or via resizeTo() function, so that editor can be placed in a layout pane.

Menu

The context menu from dojo.widget.Menu2. Menu bar not supported.

ProgressBar

Parameters

Public Methods

Accessibility

The progress bar is made accessible by providing a solid border around the visual progress indicator. This border is implemented in an additional z-indexed layer tso it does not change the visual characteristics of the bar when not in high contrast mode.. The layer with the border will be visible in high contrast mode as well as when images are turned off.

The internalProgress div is assigned the ARIA role of progressbar  The valuenow attribute is updated as the progress is updated. No valuemin and valuemax values are provided since the valuenow attribute may be a string provided tby the Web developer.

Note: The hot key for the Window-Eyes screen reader to speak progress bar information is ctrl-ins-b. JAWS provides the hot key ins-tab for announcing progress bar name and status.JAWS also has a setting to select the frequency of progress bar announcements.  Go to the Configuration Manager, Select Set Options, then User Options and select the desired announcement frequency.

Table

 

Summary

The grid widget provides a scrollable table with sortable columns connected to a dojo.data Store object.  It downloads data as needed from the data store, which typically pulls the data from the server in a JSON format.  It leverages the store's functionality for sorting, filtering and paging.   The table's outer size can be set, so that it fits into a swing-like application with a predetermined size for each section.

Some of the decisions below are based on various email conversations including this thread.

Model

In as much as possible, the Grid is modeled after a native html <table>.
  • variable height rows
  • vertical but not horizontal scrolling (by default)
Some notable differences from a native HTML table:
  • data not inlined; it comes from a dojo.data.Store object
  • height of table can be constrained, so that a scrollbar shows up

Basic Features

  • lazy load via dojo.data interface
  • vertical scrolling (the header of the table stays stationary but the inner section moves)
  • column sorting by clicking on the column
  • column formatting / expressions
  • designer specifies width and height of outer dom node, and the relative (initial) width of each column
  • resizeTo() method : dynamically change size of table (this may trigger pulling more data from the dojo.data store)
  • cells can contain simple text strings, or complex HTML (like images)
  • fast, even for large amounts of data (especially startup time)
  • different classnames for alternate rows, to allow CSS for zebra striping; classname changes when hovering over a row

Advanced Features

These features are not required for the 0.9 release but will be added eventually (either in 0.9 or afterwards).
  • no height specified; table sizes to natural height needed to fit all the data
  • column resizing (see below)
  • editable data (edits reflected back over dojo.data)
  • delete rows - TODO: how?
  • add rows - TODO: how?
  • row selection - each row has a checkbox; clicking it selects the row. TODO: how is the info about selected rows communicated?

Non-features

These features are explicitly not supported.
  • data inlined into the HTML markup as <tr>...</tr>.   (Note though that you could inline JSON data into the web page using dojo.data.JsonItemStore. It would also be easy to write a dojo.data.HtmlTableStore that could read data from an HTML table on the page, but that's not part of this spec)
  • filtering  (if the user wants to filter they can do a new query on the data store and pass the new result set to the Grid)
  • tree-table: nested rows
  • specifying custom css class names.  standard names are used (see dijit doc for details on theming)
  • selecting a certain row and then sorting by a given column results in sorted table, put you are positioned at the same row as before
  • embedded widgets in data
  • horizontal scrolling
  • drag and drop

Column resizing

Each column label has a bar after the column label. (It might be perceived as the separator between columns but the last column has it too.) You can adjust the size of a column by dragging the bar to the left of the right. Doing so does not change the width of the other columns. The columns on the right may get pushed out of the table's viewport. Adjusting column size may have an effect on the height of each row.

Scroll Bar

Since the rows have varying sizes, scrolling is complicated. But it should work this way:

The scrollbar's position is relative to the current row #, vs. the total # of rows. If you are on row 75 out of 100 rows, the scrollbar button will be 3/4 of the way down.

The scrollbar button's size can be anything.

The scrollbar must have up/down arrows.

Implementation-wise, this means that we can't have a browser-native scrollbar isn't attached directly to the div holding the data. Probably should have a browser-native scrollbar connected to a dummy div that is hidden behind the div showing the data. Could also use a slider or other custom control for the scrollbar. If we do make a fake scrollbar, then you should use Typematic.js hooked up to the buttons (it's already hooked up for keyboard handling, see the A11Y section below).

API

Programmatic creation

var store1 = new dojox.data.RemoteJsonData({documentUrl: "customers.php"});
new dijit.Grid(
  {
	data: store1,
	filter: "date > 2007-1-1",
	columns:
		[
			{ attribute: "name", label: "Name", size: 30},
			{ attribute: "dateAdded", label: "Date Added", size: 20 }, ...
		]
   }, srcNode);

Markup creation

<table dojoType="dijit.Grid" data="store1" 
style="height: 500px; width: 300px;">
	<thead>
		<tr>
			<th attribute="Name" dataType="String">Name</th>
			<th field="DateAdded" dataType="Date" align="center">Date Added</th>
			<th field="NumAccounts" dataType="Number" sort="desc" align="center"># of accounts</th>
			<th field="Description" dataType="html">Description</th>
		</tr>
	</thead>
</table>

Parameters to widget

  • store: dojo.data.Store The underlying Store for all data represented by the widget.
  • columns: Array. see above
  • query: object
    user specified query as per dojo.data standard query format, like {abbr: "ec"}
  • sort: array
    user specified sort as per dojo.data standard sort format, like [ {attribute: "uniqueId", descending: true} ]
  • id: String The name of the attribute used as a unique key for each row
  • editable: Boolean
    If the widget rows can be edited.
  • selection: String
    If rows can be selected. "none", "single", "multiple"

Store parameter

The user will call:

var store1 = new dojo.data.JsonItemStore({url: "customers.php"});
or something similar to create the store, and then pass that argument when creating the grid widget.

The Grid is designed to be able to access remote data (hence the paging interface to dojo.data), but the data doesn't necessarily need to be remote.   In other words, the Grid accesses it's data via the dojo.data interface and doesn't care where it is.   For small datasets, sometimes people will want to embed the data locally in a web page so that there's no server dependency, and for performance reasons.

This can be done with JsonItemStore. The interface looks like this:

var itemData = {items: [{name: "Bill", hiredate: new Date("2006-8-1")}, ...]};
var store = new dojo.data.JsonItemStore({ data: itemData});

Column specification:

For each column we specify the following:

  • data source is either one of these:
    • attribute: name of the attribute in the data store
    • expression: see "computed columns" below
  • type: datatype of the column (string, number, date, currenty, html); used to pick a suitable editor for when editing the column value or inserting a new row
  • constraints: for a numeric column, there can be formatting options (like # of decimal places) and/or restrictions on input. This constraints objects is a black box to Grid, but it's passed through to formatting functions based on the type above.
  • formatUsing - function to format from raw value into displayed value (overrides type)
  • editUsing - widget to use to edit value (widget will have setValue() and getTextValue() methods (overrides type)
  • label:  html text to print for the label
  • sortKey: in the case of formatted data like "<img src= 'bag.jpg'><i>Louis Vitton</i> bag", the sort key must be different than the data itself.

Computed columns:

Given a item with the following values:

productCode: 1234
image: shoes.jpg
description: Louis Vitton bag

We might want to write

<icon> 1234 Louis Vitton bag
You can specify the column contents as a function on the item:

expression: function(store, item){
	return "<img src=" + store.getValue(item, "image") + "> "
	 + store.getValue(item, "productCode") ...
 }

Supported Methods

  • setQuery() - resets the filter on the data, then reissues the query and displays the resulting data

Look And Feel

Accessibility

  • Full keyboard access - arrow key navigation of the cells in the grid. This means adding tabindex=-1 on each cell and appropriately responding to onkey events (Bill: this means up/down/left/right arrow, right? This should use Typematic.js.)
  • Each cell receives focus as the user navigates to it (either via click or keyboard).
  • Adding the WAI grid role on the outer element (either table or div element)
  • Adding the WAI cell role on each cell.
  • Adding the WAI readonly attribute on cells which are not editable (generally header cells)
  • Adding the WAI columnheader and rowheader roles on the header cells.
  • Sortable headers need the WAI sort attribute.
  • If multiselection will be implemented this must be made keyboard accessible as well. The WAI multiselectable role will be added to the outer element. 
At least one cell in the grid needs a tabindex-0 so the user can navigate into the grid.  I think that the last cell visited should retain tabindex=0 so that if the user tabs out of the grid and then back into it, they arrive back at the last cell accessed.   Although, I can live without the dynamic tabindex and having one cell designated as the entry point into the grid via tabindex=0. 

Dojo.data <--> Grid interaction

This isn't really part of the grid spec, but it's listed here for convenience.

Grid will define functions like:

function onBegin(size){
  gets the # of rows in the table.
  setup the scrollbar etc. here.
}
function onItem(item){
  callback when each row is returned.
  for(var i=0; i < this.columns.length; i++){
    var value = store.getValue(item, this.columns[i].attribute);
    ...
}

And then it will do something like this to get the first set of rows:

var params = { query: myQuery, sort: mySort, onBegin: onBegin, onItem: onItem, start: 0, count: 1000};
store.fetch(params);

Then to get next set of rows:

params.start += 1000;
store.fetch(params);

And on destruction, or when before redoing the query with a new filter or new sort:

store.close(params);

Note that it's the store's job to do caching, sorting, and querying. The Grid widget doesn't have code for any of that.

For editing an existing row:

store.setValue(item, attr, newValue);
...
store.save();

For adding a new row:

var item = store.newItem({attr1: value1, attr2: value2, ...});
store.save();

For deleting a row:

store.deleteItem(item);
store.save();

Note: how do I get back to the 300th row, which is not #300 when you sort by date, but maybe row #100 or row #400??? It won't be supported in dojo 1.0 but maybe later

TitlePane

A container with a title bar. The visibility of the container is toggled by activating an arrow "button" on the title bar via the mouse or keyboard.

Parameters

Public Methods

Accessibility

(proposed). 

The arrow to open/close each title pane will be included in the tab order via tabindex="0". The arrow will be given a role of button with a title attribute which indicates that it opens/closes the pane.   Pressing enter or space will trigger the button to toggle the open/close of the pane.

When the pane is made visible via the keyboard, the focus remains in the title pane.  The user can press down arrow to set focus to the container of the title pane contents (containerNode).   Thus, the container Node needs a tabindex="-1" so it can receive focus. When the container is opened, the tabindex should be set to 0 so the user can tab or arrow to the container.  When the title pane is closed, the tabindex needs to be set back to 0 (it could also be removed and added as the container is opened or closed but I think it is preferable to just change the tabindex value).

The title pane container will have a labelledby property which points to the id of the titlebar (thus the title bar must have an id attribute).  The containerNode will have an ARIA role of region (under discussion since region is not yet supported by screen readers).

Toolbar

(nothing written)

Tooltip

The tooltip pops up like a voice-bubble in comics. It fades in when you mouse over or focus on an element, after a brief delay, and fades out when you mouse away or blur (for keyboard).

Since the tooltip fades out when you mouse off, it's not suitable for holding button or links; use TooltipDialog for that.

TooltipDialog

The tooltip dialog is like a voice-bubble in comics. It fades in when you click (or hit return on) an element,
and fades out when you close the dialog by hitting cancel, hit escape, or click somewhere else on the screen. It will look similar to odeo's login bubble

Tree

Nothing written.