oxjs/source/Ox.UI/js/Form/Ox.Select.js

290 lines
8.6 KiB
JavaScript
Raw Normal View History

2011-07-29 18:48:43 +00:00
// vim: et:ts=4:sw=4:sts=4:ft=javascript
2011-05-16 10:49:48 +00:00
2011-11-05 16:46:53 +00:00
'use strict';
2011-05-16 10:49:48 +00:00
/*@
Ox.Select <f:Ox.Element> Select Object
() -> <f> Select Object
(options) -> <f> Select Object
(options, self) -> <f> Select Object
options <o> Options object
id <s> element id
items <a|[]> items
label <s|''> Label
labelWidth <n|64> Label width
2011-05-16 10:49:48 +00:00
max <n|1> minimum number of selected items
min <n|1> maximum number of selected items
overlap <s|'none'> can be none, left or right
selectable <b|true> is selectable
size <s|'medium'> size, can be small, medium, large
title <s|''> select title
type <s|'text'> can be 'text' or 'image'
width <s|n|'auto'> can be auto or width in pixels
self <o> shared private variable
click <!> on click event
change <!> on change event
@*/
2011-04-22 22:03:10 +00:00
Ox.Select = function(options, self) {
2011-09-23 10:43:57 +00:00
// fixme: make selected a separate option
2011-04-22 22:03:10 +00:00
// fixme: selected item needs attribute "checked", not "selected" ... that's strange
self = self || {};
var that = Ox.Element({
2011-05-22 12:39:57 +00:00
tooltip: options.tooltip || ''
}, self)
2011-04-22 22:03:10 +00:00
.defaults({
id: '',
items: [],
label: '',
labelWidth: 64,
2011-04-22 22:03:10 +00:00
max: 1,
maxWidth: 0,
2011-04-22 22:03:10 +00:00
min: 1,
overlap: 'none', // can be none, left or right
selectable: true,
size: 'medium',
style: 'rounded',
2011-04-22 22:03:10 +00:00
title: '',
type: 'text', // can be 'text' or 'image'
value: '',
width: 'auto'
2011-04-22 22:03:10 +00:00
})
// fixme: make default selection restorable
// or allow for extra action items below options
// fixme: passing value has no effect
2011-04-22 22:03:10 +00:00
.options(options)
.addClass(
'OxSelect Ox' + Ox.toTitleCase(self.options.size)
+ ' Ox' + Ox.toTitleCase(self.options.style) + (
self.options.overlap == 'none'
? '' : ' OxOverlap' + Ox.toTitleCase(self.options.overlap)
) + (self.options.label ? ' OxLabelSelect' : '')
2011-04-22 22:03:10 +00:00
)
.css(self.options.width == 'auto' ? {} : {
width: self.options.width - 2 + 'px'
2011-04-22 22:03:10 +00:00
})
.bindEvent({
key_escape: loseFocus,
key_down: showMenu
});
Ox.Log('Form', 'Ox.Select', self.options);
/*
self.options.items.forEach(function(item, i) {
if (Ox.isUndefined(item.id)) {
self.options.items[i].id = item.title;
}
});
*/
2011-04-22 22:03:10 +00:00
Ox.extend(self, {
2011-04-22 22:03:10 +00:00
buttonId: self.options.id + 'Button',
groupId: self.options.id + 'Group',
menuId: self.options.id + 'Menu'
});
if (self.options.selectable) {
2011-06-19 18:25:37 +00:00
self.optionGroup = new Ox.OptionGroup(
2011-04-22 22:03:10 +00:00
self.options.items,
self.options.min,
self.options.max
);
self.options.items = self.optionGroup.init();
self.checked = self.optionGroup.checked();
}
if (self.options.label) {
self.$label = Ox.Label({
overlap: 'right',
textAlign: 'right',
title: self.options.label,
width: self.options.labelWidth
})
.click(function() {
// fixme: ???
// that.focus();
})
.appendTo(that);
}
2011-04-22 22:03:10 +00:00
if (self.options.type == 'text') {
self.$title = $('<div>')
.addClass('OxTitle')
.css({
width: getTitleWidth() + 'px'
2011-04-22 22:03:10 +00:00
})
.html(
self.options.title
|| self.options.items[self.checked[0]].title
2011-04-22 22:03:10 +00:00
)
.click(showMenu)
.appendTo(that.$element);
}
self.$button = Ox.Button({
2011-04-22 22:03:10 +00:00
id: self.buttonId,
style: 'symbol',
title: 'select',
type: 'image'
})
.bindEvent('click', showMenu)
.appendTo(that);
self.$menu = Ox.Menu({
2011-04-22 22:03:10 +00:00
element: self.$title || self.$button,
id: self.menuId,
items: [self.options.selectable ? {
group: self.groupId,
items: self.options.items,
max: self.options.max,
min: self.options.min
} : self.options.items],
maxWidth: self.options.maxWidth,
2011-04-22 22:03:10 +00:00
side: 'bottom',
size: self.options.size
})
.bindEvent({
change: changeMenu,
click: clickMenu,
hide: hideMenu
});
self.options.type == 'image' && self.$menu.addClass('OxRight');
function clickMenu(data) {
2011-04-22 22:03:10 +00:00
that.triggerEvent('click', data);
}
function changeMenu(data) {
2011-11-04 15:54:28 +00:00
//Ox.Log('Form', 'clickMenu: ', self.options.id, data)
2011-10-30 21:05:32 +00:00
if (self.options.selectable) {
self.checked = self.optionGroup.checked();
self.options.value = data.checked.length ? data.checked[0].id : '';
2011-10-30 21:05:32 +00:00
self.$title && self.$title.html(
self.options.title ? self.options.title : data.checked[0].title
);
that.triggerEvent('change', {
2011-11-10 13:55:33 +00:00
selected: data.checked,
value: self.options.value
2011-10-30 21:05:32 +00:00
});
} else {
that.triggerEvent('click', data);
}
2011-04-22 22:03:10 +00:00
}
function getTitleWidth() {
// fixme: used to be 22. obscure
return self.options.width - 24 - (
self.options.label ? self.options.labelWidth : 0
);
}
2011-04-22 22:03:10 +00:00
function hideMenu() {
2011-11-04 15:54:28 +00:00
//Ox.Log('Form', '%% hideMenu that', that, 'self', self)
2011-04-22 22:03:10 +00:00
that.removeClass('OxSelected');
// self.$button.removeClass('OxSelected');
2011-11-04 15:54:28 +00:00
//Ox.Log('Form', '%% hideMenu end')
2011-04-22 22:03:10 +00:00
}
function loseFocus() {
that.loseFocus();
}
function showMenu() {
that.gainFocus();
that.addClass('OxSelected');
2011-05-20 14:11:42 +00:00
self.options.tooltip && that.$tooltip.hide();
2011-04-22 22:03:10 +00:00
self.$menu.showMenu();
}
2011-04-29 12:40:51 +00:00
self.setOption = function(key, value) {
if (key == 'labelWidth') {
self.$label.options({width: value});
self.$title.css({width: getTitleWidth() + 'px'});
} else if (key == 'title') {
self.$title.html(value);
} else if (key == 'width') {
2011-12-01 10:52:23 +00:00
Ox.Log('Form', 'SETTING WIDTH OPTION', value)
self.$title.css({width: getTitleWidth() + 'px'});
2011-12-01 10:52:23 +00:00
that.css({width: value - 2 + 'px'});
} else if (key == 'value') {
2011-11-04 15:54:28 +00:00
Ox.Log('Form', 'SETTING VALUE OPTION', value)
2011-05-30 12:06:58 +00:00
that.selectItem(value);
}
2011-04-22 22:03:10 +00:00
};
that.disableItem = function(id) {
self.$menu.getItem(id).options({disabled: true});
};
that.enableItem = function(id) {
self.$menu.getItem(id).options({disabled: false});
};
self.superRemove = that.remove;
that.remove = function() {
self.$menu.remove();
self.superRemove();
};
// FIXME: selected() _and_ selectItem() _and_ value() ???
2011-05-16 10:49:48 +00:00
/*@
2011-09-23 10:43:57 +00:00
selected <f> gets selected item
2011-05-16 10:49:48 +00:00
() -> <o> returns object of selected items with id, title
@*/
2011-04-22 22:03:10 +00:00
that.selected = function() {
return /*self.checked*/self.optionGroup.checked().map(function(v) {
2011-04-22 22:03:10 +00:00
return {
id: self.options.items[v].id,
title: self.options.items[v].title
};
});
};
2011-05-16 10:49:48 +00:00
/*@
selectItem <f> select item in group
(id) -> <u> select item by id
id <s> item id
@*/
2011-04-22 22:03:10 +00:00
that.selectItem = function(id) {
2011-11-04 15:54:28 +00:00
Ox.Log('Form', 'selectItem', id, self.options.items, self.options.items.length, Ox.getObjectById(self.options.items, id))
2011-04-22 22:03:10 +00:00
self.options.type == 'text' && self.$title.html(
2011-09-20 00:11:16 +00:00
Ox.getObjectById(self.options.items, id).title
2011-04-22 22:03:10 +00:00
);
self.$menu.checkItem(id);
self.checked = self.optionGroup.checked();
};
/*
that.width = function(val) {
// fixme: silly hack, and won't work for css() ... remove!
that.$element.width(val + 16);
that.$button.width(val);
//that.$symbol.width(val);
return that;
};
*/
that.value = function() {
var selected;
if (arguments.length == 0) {
selected = that.selected();
return selected.length ? that.selected()[0].id : '';
} else {
that.selectItem(arguments[0]);
return that;
/*
2011-11-04 15:54:28 +00:00
Ox.Log('Form', 'ELSE');
that.selectItem(arguments[0]);
return that;
*/
}
};
2011-04-22 22:03:10 +00:00
return that;
};