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

274 lines
8.3 KiB
JavaScript
Raw Normal View History

2011-11-05 16:46:53 +00:00
'use strict';
2011-05-16 10:49:48 +00:00
/*@
2012-05-31 10:32:54 +00:00
Ox.Select <f> Select Object
2011-05-16 10:49:48 +00:00
options <o> Options object
2011-12-20 07:07:57 +00:00
disabled <b|false> If true, select is disabled
id <s> Element id
2011-12-21 13:42:47 +00:00
items <a|[]> Items (array of {id, title} or strings)
label <s|''> Label
labelWidth <n|64> Label width
2011-12-20 07:07:57 +00:00
max <n|1> Maximum number of selected items
maxWidth <n|0> Maximum menu width
min <n|1> Minimum number of selected items
overlap <s|'none'> Can be 'none', 'left' or 'right'
2011-12-20 07:29:14 +00:00
selectable <b|true> is selectable
2011-12-20 07:07:57 +00:00
size <s|'medium'> Size, can be small, medium, large
style <s|'rounded'> Style ('rounded' or 'square')
title <s|''> Select title
tooltip <s|f|''> Tooltip title, or function that returns one
(e) -> <string> Tooltip title
e <object> Mouse event
type <s|'text'> Type ('text' or 'image')
2011-12-21 13:42:47 +00:00
value <a|s> Selected id, or array of selected ids
2011-12-20 07:07:57 +00:00
width <s|n|'auto'> Width in px, or 'auto'
self <o> Shared private variable
([options[, self]) -> <o:Ox.Element> Select Object
click <!> Click event
change <!> Change event
2011-05-16 10:49:48 +00:00
@*/
2011-04-22 22:03:10 +00:00
Ox.Select = function(options, self) {
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,
2011-12-21 13:42:47 +00:00
overlap: 'none',
2011-04-22 22:03:10 +00:00
size: 'medium',
style: 'rounded',
2011-04-22 22:03:10 +00:00
title: '',
2011-12-21 13:42:47 +00:00
type: 'text',
value: options.max != 1 ? [] : '',
width: 'auto'
2011-04-22 22:03:10 +00:00
})
// fixme: make default selection restorable
.options(options)
2012-05-28 19:35:41 +00:00
.update({
labelWidth: function() {
self.$label.options({width: self.options.labelWidth});
self.$title.css({width: getTitleWidth() + 'px'});
},
title: function() {
if (self.options.type == 'text') {
self.$title.html(self.options.title);
} else {
self.$button.options({title: self.options.title});
}
},
width: function() {
that.css({width: self.options.width- 2 + 'px'});
self.$title.css({width: getTitleWidth() + 'px'});
},
value: function() {
var value = self.options.value;
if (self.options.type == 'text' && !self.options.title) {
self.$title.html(getItem(value).title);
}
value !== '' && Ox.makeArray(value).forEach(function(value) {
self.$menu.checkItem(value);
});
self.options.value = self.optionGroup.value();
}
})
2011-04-22 22:03:10 +00:00
.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({
2011-12-20 07:29:14 +00:00
anyclick: showMenu,
2011-04-22 22:03:10 +00:00
key_escape: loseFocus,
key_down: showMenu
});
2011-12-21 13:42:47 +00:00
self.options.items = self.options.items.map(function(item) {
2012-01-13 06:57:42 +00:00
var isObject = Ox.isObject(item);
2011-12-22 15:47:46 +00:00
return Ox.isEmpty(item) ? item : {
2012-01-13 06:57:42 +00:00
id: isObject ? item.id : item,
title: isObject ? item.title : item,
checked: Ox.makeArray(self.options.value).indexOf(
2012-01-13 06:57:42 +00:00
isObject ? item.id : item
) > -1,
disabled: isObject ? item.disabled : false
2011-12-21 13:42:47 +00:00
};
});
self.optionGroup = new Ox.OptionGroup(
self.options.items,
self.options.min,
self.options.max,
'checked'
);
self.options.items = self.optionGroup.init();
self.options.value = self.optionGroup.value();
2011-04-22 22:03:10 +00:00
if (self.options.label) {
self.$label = Ox.Label({
overlap: 'right',
textAlign: 'right',
title: self.options.label,
width: self.options.labelWidth
})
.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(
2011-12-30 09:33:01 +00:00
self.options.title || getItem(self.options.value).title
2011-04-22 22:03:10 +00:00
)
2011-12-20 07:07:57 +00:00
.appendTo(that);
2011-04-22 22:03:10 +00:00
}
self.$button = Ox.Button({
2011-12-20 07:07:57 +00:00
id: self.options.id + 'Button',
selectable: true,
2011-04-22 22:03:10 +00:00
style: 'symbol',
2011-12-20 07:07:57 +00:00
title: self.options.type == 'text' || !self.options.title
? 'select' : self.options.title,
2011-04-22 22:03:10 +00:00
type: 'image'
})
.appendTo(that);
self.$menu = Ox.Menu({
2011-04-22 22:03:10 +00:00
element: self.$title || self.$button,
2011-12-20 07:07:57 +00:00
id: self.options.id + 'Menu',
2011-12-21 13:42:47 +00:00
items: [{
2011-12-20 07:07:57 +00:00
group: self.options.id + 'Group',
2011-04-22 22:03:10 +00:00
items: self.options.items,
max: self.options.max,
min: self.options.min
2011-12-21 13:42:47 +00:00
}],
maxWidth: self.options.maxWidth,
2011-12-20 07:07:57 +00:00
side: 'bottom', // FIXME: should be edge
2011-04-22 22:03:10 +00:00
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-12-21 13:42:47 +00:00
self.options.value = self.optionGroup.value();
self.$title && self.$title.html(
2011-12-30 09:33:01 +00:00
self.options.title || getItem(self.options.value).title
2011-12-21 13:42:47 +00:00
);
that.triggerEvent('change', {
2011-12-30 09:33:01 +00:00
title: Ox.isEmpty(self.options.value) ? ''
: Ox.isArray(self.options.value)
? self.options.value.map(function(value) {
return getItem(value).title;
})
: getItem(self.options.value).title,
2011-12-21 13:42:47 +00:00
value: self.options.value
});
}
function getItem(id) {
return Ox.getObjectById(self.options.items, id);
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-12-21 13:42:47 +00:00
that.loseFocus();
2011-04-22 22:03:10 +00:00
that.removeClass('OxSelected');
self.$button.options({value: false});
2011-04-22 22:03:10 +00:00
}
function loseFocus() {
that.loseFocus();
}
2011-12-21 13:42:47 +00:00
function selectItem() {
}
2011-04-22 22:03:10 +00:00
function showMenu() {
that.gainFocus();
that.addClass('OxSelected');
self.$button.options({value: true});
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();
}
2012-05-21 10:38:18 +00:00
/*@
disableItem <f> disableItem
@*/
that.disableItem = function(id) {
self.$menu.getItem(id).options({disabled: true});
};
2012-05-21 10:38:18 +00:00
/*@
enableItem <f> enableItem
@*/
that.enableItem = function(id) {
self.$menu.getItem(id).options({disabled: false});
};
2012-05-21 10:38:18 +00:00
/*@
remove <f> remove
@*/
self.superRemove = that.remove;
that.remove = function() {
self.$menu.remove();
self.superRemove();
};
2011-05-16 10:49:48 +00:00
/*@
2011-09-23 10:43:57 +00:00
selected <f> gets selected item
2011-12-21 13:42:47 +00:00
() -> <o> returns array of selected items with id and title
2011-05-16 10:49:48 +00:00
@*/
2011-04-22 22:03:10 +00:00
that.selected = function() {
return Ox.makeArray(self.optionGroup.value()).map(function(id) {
2011-04-22 22:03:10 +00:00
return {
2011-12-21 13:42:47 +00:00
id: id,
title: getItem(id).title
2011-04-22 22:03:10 +00:00
};
2011-12-21 13:42:47 +00:00
});
2011-04-22 22:03:10 +00:00
};
/*
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;
};
*/
return that;
};