2 * (c) 2005-2007 Richard Cowin (http://openrico.org)
4 * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this
5 * file except in compliance with the License. You may obtain a copy of the License at
6 * http://www.apache.org/licenses/LICENSE-2.0
10 Rico.selectionSet = function(set, options){
11 new Rico.SelectionSet(set, options);
14 Rico.SelectionSet = Class.create(
15 /** @lends Rico.SelectionSet# */
20 * @param selectionSet collection of DOM elements (or a CSS selection string)
21 * @param options object may contain any of the following:<dl>
22 * <dt>selectedClass</dt><dd>class name to add when element is selected, default is "selected"</dd>
23 * <dt>selectNode </dt><dd>optional function that returns the element to be selected</dd>
24 * <dt>onSelect </dt><dd>optional function that gets called when element is selected</dd>
25 * <dt>onFirstSelect</dt><dd>optional function that gets called the first time element is selected</dd>
26 * <dt>noDefault </dt><dd>when true, no element in the set is initially selected, default is false</dd>
27 * <dt>selectedIndex</dt><dd>index of the element that should be initially selected, default is 0</dd>
28 * <dt>cookieName </dt><dd>optional name of cookie to use to remember selected element. If specified, and the cookie exists, then the cookie value overrides selectedIndex.</dd>
29 * <dt>cookieDays </dt><dd>specifies how long cookie should persist (in days). If unspecified, then the cookie persists for the current session.</dd>
30 * <dt>cookiePath </dt><dd>optional cookie path</dd>
31 * <dt>cookieDomain </dt><dd>optional cookie domain</dd>
34 initialize: function(selectionSet, options){
35 this.options = options || {};
36 if (typeof selectionSet == 'string')
37 selectionSet = $$(selectionSet);
38 this.previouslySelected = [];
39 this.selectionSet = selectionSet;
40 this.selectedClassName = this.options.selectedClass || "selected";
41 this.selectNode = this.options.selectNode || function(e){return e;};
42 this.onSelect = this.options.onSelect;
43 this.onFirstSelect = this.options.onFirstSelect;
44 this.clickHandler = this.click.bind(this);
45 selectionSet.each(function(e) {Event.observe(e, "click", new Rico.EventWrapper(this.clickHandler,e).wrapper);}.bind(this));
46 if (!this.options.noDefault) {
47 var cookieIndex=this.options.cookieName ? this.getCookie() : 0;
48 this.selectIndex(cookieIndex || this.options.selectedIndex || 0);
51 getCookie: function() {
52 var cookie = RicoUtil.getCookie(this.options.cookieName);
53 if (!cookie) return 0;
54 var index = parseInt(cookie);
55 return index < this.selectionSet.length ? index : 0;
58 this.previouslySelected = [];
59 this.notifySelected(this.selected);
61 select: function(element){
62 if (this.selected == element)
66 Element.removeClassName(this.selectNode(this.selected), this.selectedClassName);
68 this.notifySelected(element);
70 this.selected = element;
71 Element.addClassName(this.selectNode(this.selected), this.selectedClassName);
73 notifySelected: function(element){
74 var index = this.selectionSet.indexOf(element);
75 if (this.options.cookieName)
76 RicoUtil.setCookie(this.options.cookieName, index, this.options.cookieDays, this.options.cookiePath, this.options.cookieDomain);
77 if (this.onFirstSelect && !this.previouslySelected[index]){
78 this.onFirstSelect(element, index);
79 this.previouslySelected[index] = true;
83 this.onSelect(element, index);
86 selectIndex: function(index){
87 this.select(this.selectionSet[index]);
89 nextSelectItem: function(){
90 var index = this.selectionSet.indexOf(this.selected);
91 if (index + 1 >= this.selectionSet.length)
92 return this.selectionSet[index - 1];
94 return this.selectionSet[index + 1];
96 selectNext: function(){
97 var index = this.selectionSet.indexOf(this.selected);
98 if (index >= this.selectionSet.length)
99 this.selectIndex(index - 1);
101 this.selectIndex(index + 1);
103 click: function(event,target) {
107 // this.selectionSet.push(item)
108 if (item.constructur == Array) {
109 item.each(function(e){
110 Event.observe(e, "click", new Rico.EventWrapper(this.clickHandler,item).wrapper);
113 Event.observe(item, "click", new Rico.EventWrapper(this.clickHandler,item).wrapper);
116 remove: function(item){
117 this.selectionSet = this.selectionSet.without(item);
118 //Todo: need to cleanup all events on item - need to keep track of eventwrappers
120 removeAll: function(){
124 Rico.HoverSet = Class.create(
125 /** @lends Rico.HoverSet# */
130 * @param hoverSet collection of DOM elements
131 * @param options object may contain any of the following:<dl>
132 * <dt>hoverClass</dt><dd> class name to add when mouse is over element, default is "hover"</dd>
133 * <dt>hoverNodes</dt><dd> optional function to select/filter which nodes are in the set</dd>
136 initialize: function(hoverSet, options){
137 options = options || [];
138 this.hoverSet = hoverSet;
139 this.hoverClassName = options.hoverClass || "hover";
140 this.hoverNodes = options.hoverNodes || function(e){return [e];};
141 this.listenerHover = this._onHover.bind(this);
142 this.listenerEndHover = this._onUnHover.bind(this);
143 for (var i=0; i<this.hoverSet.length; i++) this.add(this.hoverSet[i]);
145 _onHover: function(event,target) {
148 _onUnHover: function(event,target) {
149 this.unHover(target);
151 hover: function(target) {
152 this.hoverNodes(target).each((function(t){Element.addClassName(t,this.hoverClassName);}).bind(this));
154 unHover: function(target) {
155 this.hoverNodes(target).each((function(t){Element.removeClassName(t,this.hoverClassName);}).bind(this));
158 Event.observe(item, "mousemove", new Rico.EventWrapper(this.listenerHover,item).wrapper);
159 Event.observe(item, "mouseout", new Rico.EventWrapper(this.listenerEndHover,item).wrapper);
169 clearCurrent: function(group) {
170 var last_hover = Rico.Hover.groups[group];
171 if(!last_hover) return;
172 clearTimeout(last_hover[0]);
174 Rico.Hover.groups[group] = null;
176 end: function(group) {
177 Rico.Hover.groups[group][1].end();
179 endWith: function(hover, group) {
180 var timer = setTimeout('Rico.Hover.end("'+ group + '")', hover.exitDelay);
181 Rico.Hover.groups[group] = [timer, hover];
185 Rico.HoverDisplay = Class.create(
186 /** @lends Rico.HoverDisplay# */
192 * @param options object may contain any of the following:<dl>
193 * <dt>group</dt><dd> </dd>
194 * <dt>delay</dt><dd> </dd>
197 initialize: function(element, options) {
198 this.element = element;
199 this.options = options || {};
200 this.group = this.options.group;
201 this.exitDelay = this.options.delay || 1000;
204 Rico.Hover.clearCurrent(this.group);
205 Element.show(this.element);
207 end: function(delay) {
209 Rico.Hover.endWith(this, this.group);
211 Element.hide(this.element);
216 Rico.EventWrapper = Class.create(
217 /** @lends Rico.EventWrapper# */
225 initialize: function(handler, target){
226 this.handler = handler;
227 this.target = target;
228 this.wrapper = this.wrapperCall.bindAsEventListener(this);
230 wrapperCall: function(event){
231 this.handler(event, this.target);
235 Rico.includeLoaded('ricoBehaviors.js');