1
YUI.add('listbox', function(Y) {
3
Y.ListBox = Y.Base.create("listbox", Y.Widget, [Y.WidgetParent, Y.WidgetChild], {
5
CONTENT_TEMPLATE : "<ul></ul>",
10
this.get("boundingBox").plug(Y.Plugin.NodeFocusManager, {
11
descendants: ".yui3-option",
13
next: "down:40", // Down arrow
14
previous: "down:38" // Up arrow
20
this.get("boundingBox").on("contextmenu", function (event) {
21
event.preventDefault();
24
// Setup listener to control keyboard based single/multiple item selection
25
this.on("option:keydown", function (event) {
27
var item = event.target,
28
domEvent = event.domEvent,
29
keyCode = domEvent.keyCode,
30
direction = (keyCode == 40);
32
if (this.get("multiple")) {
33
if (keyCode == 40 || keyCode == 38) {
34
if (domEvent.shiftKey) {
35
this._selectNextSibling(item, direction);
38
this._selectNextSibling(item, direction);
42
if (keyCode == 13 || keyCode == 32) {
43
domEvent.preventDefault();
44
item.set("selected", 1);
49
// Setup listener to control mouse based single/multiple item selection
50
this.on("option:mousedown", function (event) {
52
var item = event.target,
53
domEvent = event.domEvent,
56
if (this.get("multiple")) {
57
if (domEvent.metaKey) {
58
item.set("selected", 1);
61
item.set("selected", 1);
64
item.set("selected", 1);
70
// Helper Method, to find the correct next sibling, taking into account nested ListBoxes
71
_selectNextSibling : function(item, direction) {
73
var parent = item.get("parent"),
74
method = (direction) ? "next" : "previous",
76
// Only go circular for the root listbox
77
circular = (parent === this),
78
sibling = item[method](circular);
81
// If we found a sibling, it's either an Option or a ListBox
82
if (sibling instanceof Y.ListBox) {
83
// If it's a ListBox, select it's first child (in the direction we're headed)
84
sibling.selectChild((direction) ? 0 : sibling.size() - 1);
86
// If it's an Option, select it
87
sibling.set("selected", 1);
90
// If we didn't find a sibling, we're at the last leaf in a nested ListBox
91
parent[method](true).set("selected", 1);
95
NESTED_TEMPLATE : '<li class="{nestedOptionClassName}"><em class="{labelClassName}">{label}</em></li>',
97
renderUI: function () {
99
if (this.get("depth") > -1) {
102
labelClassName : this.getClassName("label"),
103
nestedOptionClassName : this.getClassName("option"),
104
label : this.get("label")
106
liHtml = Y.substitute(this.NESTED_TEMPLATE, tokens),
107
li = Y.Node.create(liHtml),
109
boundingBox = this.get("boundingBox"),
110
parent = boundingBox.get("parentNode");
112
li.appendChild(boundingBox);
113
parent.appendChild(li);
123
validator: Y.Lang.isString
128
Y.Option = Y.Base.create("option", Y.Widget, [Y.WidgetChild], {
130
CONTENT_TEMPLATE : "<em></em>",
131
BOUNDING_TEMPLATE : "<li></li>",
133
renderUI: function () {
134
this.get("contentBox").setContent(this.get("label"));
141
validator: Y.Lang.isString
149
}, '3.1.0' ,{requires:['substitute', 'widget', 'widget-parent', 'widget-child', 'node-focusmanager']});