236 lines
6.9 KiB
JavaScript
236 lines
6.9 KiB
JavaScript
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
|
|
|
/*@
|
|
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
|
|
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
|
|
@*/
|
|
|
|
Ox.Select = function(options, self) {
|
|
|
|
// fixme: make selected a separate option
|
|
// fixme: selected item needs attribute "checked", not "selected" ... that's strange
|
|
self = self || {};
|
|
var that = Ox.Element({
|
|
tooltip: options.tooltip || ''
|
|
}, self)
|
|
.defaults({
|
|
id: '',
|
|
items: [],
|
|
label: '',
|
|
labelWidth: 64,
|
|
max: 1,
|
|
min: 1,
|
|
overlap: 'none', // can be none, left or right
|
|
selectable: true,
|
|
size: 'medium',
|
|
title: '',
|
|
type: 'text', // can be 'text' or 'image'
|
|
value: [],
|
|
width: 'auto'
|
|
})
|
|
// fixme: make default selection restorable
|
|
// or allow for extra action items below options
|
|
.options(options)
|
|
.addClass(
|
|
'OxSelect Ox' + Ox.toTitleCase(self.options.size) + (
|
|
self.options.overlap == 'none'
|
|
? '' : ' OxOverlap' + Ox.toTitleCase(self.options.overlap)
|
|
) + (self.options.label ? ' OxLabelSelect' : '')
|
|
)
|
|
.css(self.options.width == 'auto' ? {} : {
|
|
width: self.options.width - 2 + 'px'
|
|
})
|
|
.bindEvent({
|
|
key_escape: loseFocus,
|
|
key_down: showMenu
|
|
});
|
|
|
|
//Ox.print('Ox.Select', self.options);
|
|
|
|
Ox.extend(self, {
|
|
buttonId: self.options.id + 'Button',
|
|
groupId: self.options.id + 'Group',
|
|
menuId: self.options.id + 'Menu'
|
|
});
|
|
|
|
if (self.options.selectable) {
|
|
self.optionGroup = new Ox.OptionGroup(
|
|
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);
|
|
}
|
|
|
|
if (self.options.type == 'text') {
|
|
self.$title = $('<div>')
|
|
.addClass('OxTitle')
|
|
.css({
|
|
// fixme: used to be 22. obscure
|
|
width: (self.options.width - 24 - (
|
|
self.options.label ? self.options.labelWidth : 0
|
|
)) + 'px'
|
|
})
|
|
.html(
|
|
self.options.title ? self.options.title
|
|
: self.options.items[self.checked[0]].title
|
|
)
|
|
.click(showMenu)
|
|
.appendTo(that.$element);
|
|
}
|
|
|
|
self.$button = Ox.Button({
|
|
id: self.buttonId,
|
|
style: 'symbol',
|
|
title: 'select',
|
|
type: 'image'
|
|
})
|
|
.bindEvent('click', showMenu)
|
|
.appendTo(that);
|
|
|
|
self.$menu = Ox.Menu({
|
|
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],
|
|
side: 'bottom',
|
|
size: self.options.size
|
|
})
|
|
.bindEvent({
|
|
change: changeMenu,
|
|
click: clickMenu,
|
|
hide: hideMenu
|
|
});
|
|
|
|
self.options.type == 'image' && self.$menu.addClass('OxRight');
|
|
|
|
function clickMenu(data) {
|
|
that.triggerEvent('click', data);
|
|
}
|
|
|
|
function changeMenu(data) {
|
|
//Ox.print('clickMenu: ', self.options.id, data)
|
|
self.checked = self.optionGroup.checked();
|
|
self.$title && self.$title.html(
|
|
self.options.title ? self.options.title :
|
|
data.checked[0].title
|
|
);
|
|
that.triggerEvent('change', {
|
|
selected: data.checked
|
|
});
|
|
}
|
|
|
|
function hideMenu() {
|
|
//Ox.print('%% hideMenu that', that, 'self', self)
|
|
that.removeClass('OxSelected');
|
|
// self.$button.removeClass('OxSelected');
|
|
//Ox.print('%% hideMenu end')
|
|
}
|
|
|
|
function loseFocus() {
|
|
that.loseFocus();
|
|
}
|
|
|
|
function showMenu() {
|
|
that.gainFocus();
|
|
that.addClass('OxSelected');
|
|
self.options.tooltip && that.$tooltip.hide();
|
|
self.$menu.showMenu();
|
|
}
|
|
|
|
self.setOption = function(key, value) {
|
|
if (key == 'value') {
|
|
that.selectItem(value);
|
|
}
|
|
};
|
|
|
|
/*@
|
|
selected <f> gets selected item
|
|
() -> <o> returns object of selected items with id, title
|
|
@*/
|
|
that.selected = function() {
|
|
return /*self.checked*/self.optionGroup.checked().map(function(v) {
|
|
return {
|
|
id: self.options.items[v].id,
|
|
title: self.options.items[v].title
|
|
};
|
|
});
|
|
};
|
|
|
|
/*@
|
|
selectItem <f> select item in group
|
|
(id) -> <u> select item by id
|
|
id <s> item id
|
|
@*/
|
|
that.selectItem = function(id) {
|
|
Ox.print('selectItem', id, self.options.items, self.options.items.length, Ox.getObjectById(self.options.items, id))
|
|
self.options.type == 'text' && self.$title.html(
|
|
Ox.getObjectById(self.options.items, id).title
|
|
);
|
|
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() {
|
|
if (arguments.length == 0) {
|
|
//Ox.print('selected::', that.selected())
|
|
return that.selected()[0].id;
|
|
} else {
|
|
/*
|
|
Ox.print('ELSE');
|
|
that.selectItem(arguments[0]);
|
|
return that;
|
|
*/
|
|
}
|
|
};
|
|
|
|
return that;
|
|
|
|
};
|