// vim: et:ts=4:sw=4:sts=4:ft=javascript 'use strict'; /*@ Ox.Select Select Object () -> Select Object (options) -> Select Object (options, self) -> Select Object options Options object id element id items items label Label labelWidth Label width max minimum number of selected items min maximum number of selected items overlap can be none, left or right selectable is selectable size size, can be small, medium, large title select title type can be 'text' or 'image' width can be auto or width in pixels self 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, maxWidth: 0, min: 1, overlap: 'none', // can be none, left or right selectable: true, size: 'medium', style: 'rounded', title: '', type: 'text', // can be 'text' or 'image' value: '', width: 'auto' }) // fixme: make default selection restorable // or allow for extra action items below options // fixme: passing value has no effect .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' : '') ) .css(self.options.width == 'auto' ? {} : { width: self.options.width - 2 + 'px' }) .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; } }); */ 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 = $('
') .addClass('OxTitle') .css({ width: getTitleWidth() + 'px' }) .html( 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], maxWidth: self.options.maxWidth, 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.Log('Form', 'clickMenu: ', self.options.id, data) if (self.options.selectable) { self.checked = self.optionGroup.checked(); self.options.value = data.checked.length ? data.checked[0].id : ''; self.$title && self.$title.html( self.options.title ? self.options.title : data.checked[0].title ); that.triggerEvent('change', { selected: data.checked, value: self.options.value }); } else { that.triggerEvent('click', data); } } function getTitleWidth() { // fixme: used to be 22. obscure return self.options.width - 24 - ( self.options.label ? self.options.labelWidth : 0 ); } function hideMenu() { //Ox.Log('Form', '%% hideMenu that', that, 'self', self) that.removeClass('OxSelected'); // self.$button.removeClass('OxSelected'); //Ox.Log('Form', '%% 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 == 'labelWidth') { self.$label.options({width: value}); self.$title.css({width: getTitleWidth() + 'px'}); } else if (key == 'title') { self.$title.html(value); } else if (key == 'width') { Ox.Log('Form', 'SETTING WIDTH OPTION', value) self.$title.css({width: getTitleWidth() + 'px'}); that.css({width: value - 2 + 'px'}); } else if (key == 'value') { Ox.Log('Form', 'SETTING VALUE OPTION', value) that.selectItem(value); } }; 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() ??? /*@ selected gets selected item () -> 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 select item in group (id) -> select item by id id item id @*/ that.selectItem = function(id) { Ox.Log('Form', '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() { var selected; if (arguments.length == 0) { selected = that.selected(); return selected.length ? that.selected()[0].id : ''; } else { that.selectItem(arguments[0]); return that; /* Ox.Log('Form', 'ELSE'); that.selectItem(arguments[0]); return that; */ } }; return that; };