// vim: et:ts=4:sw=4:sts=4:ft=javascript /*@ Ox.TreeList TreeList Object () -> TreeList Object (options) -> TreeList Object (options, self) -> TreeList Object options Options object data data to be parsed to items, needs documentation items array of items max maximum number of items that can be selected, -1 unlimited min minimum number of items that have to be selected selected selected ids width list width self shared private variable @*/ Ox.TreeList = function(options, self) { // fixme: expanding the last item should cause some scroll self = self || {}; var that = Ox.Element({}, self) .defaults({ data: null, items: [], max: -1, min: 0, selected: [], width: 256 }) .options(options || {}); if (self.options.data) { self.options.items = []; //Ox.print('d', self.options.data, 'i', self.options.items) Ox.forEach(Ox.sort(Ox.keys(self.options.data)), function(key) { self.options.items.push(parseData(key, self.options.data[key])); }); //Ox.print('d', self.options.data, 'i', self.options.items) } that.$element = Ox.List({ construct: constructItem, itemHeight: 16, items: parseItems(), itemWidth: self.options.width, max: self.options.max, min: self.options.min, unique: 'id' }, $.extend({}, self)) .addClass('OxTextList OxTreeList') .css({ width: self.options.width + 'px' }) .click(clickItem) .bindEvent({ toggle: toggleItems }); function clickItem(e) { var $target = $(e.target), $item, id, item; if ($target.is('.OxToggle')) { $item = $target.parent().parent(); id = $item.data('id'); item = getItemById(id); toggleItem(item, !item.expanded); } } function constructItem(data) { var $item = $('
'), padding = (data.level + !data.items) * 16 - 8; if (data.level || !data.items) { $('
') .addClass('OxCell OxTarget') .css({ width: padding + 'px', }) .appendTo($item); } if (data.items) { $('
') .addClass('OxCell') .css({ width: '8px', }) .append( // fixme: need Ox.Icon() $('') .addClass('OxToggle') .attr({ src: Ox.UI.getImageURL( 'symbol' + (data.expanded ? 'Down' : 'Right') ) }) .css({ width: '10px', height: '10px', padding: '3px' }) ) .appendTo($item); } $('
') .addClass('OxCell OxTarget') .css({ width: (self.options.width - padding - 32 + !data.items * 16) + 'px' }) .html(data.title) .appendTo($item); return $item; } function getItemById(id, items, level) { var ret = null; items = items || self.options.items; level = level || 0; Ox.forEach(items, function(item) { if (item.id == id) { ret = $.extend(item, { level: level }); return false; } if (item.items) { ret = getItemById(id, item.items, level + 1); if (ret) { return false; } } }); return ret; } function parseData(key, value) { //Ox.print('parseData', key, value) var ret = { id: Ox.uid(), title: key.toString() + ': ' }, type = Ox.typeOf(value); if (type == 'array' || type == 'object') { ret.title += Ox.toTitleCase(type); ret.items = Ox.map(Ox.sort(Ox.keys(value)), function(k) { return parseData(k, value[k]); }); } else { ret.title += ( type == 'function' ? value.toString().split('{')[0] : JSON.stringify(value) ); } return ret; } function parseItems(items, level) { var ret = []; items = items || self.options.items; level = level || 0; items.forEach(function(item, i) { var item_ = $.extend({ level: level }, item, item.items ? { items: !!item.expanded ? parseItems(item.items, level + 1) : [] } : {}); ret.push(item_); item.items && $.merge(ret, item_.items); }); return ret; } function toggleItem(item, expanded) { var $img, pos; item.expanded = expanded; //getItemById(item.id).expanded = expanded; $.each(that.$element.find('.OxItem'), function(i, v) { var $item = $(v); if ($item.data('id') == item.id) { $img = $item.find('.OxToggle'); pos = $item.data('position'); return false; } }); $img.attr({ src: Ox.UI.getImageURL( 'symbol' + (expanded ? 'Down' : 'Right') ) }); that.$element.value(item.id, 'expanded', expanded); expanded ? that.$element.addItems(pos + 1, parseItems(item.items, item.level + 1)) : that.$element.removeItems(pos + 1, parseItems(item.items, item.level + 1).length); } function toggleItems(event, data) { data.ids.forEach(function(id, i) { var item = getItemById(id); if (item.items && data.expanded != !!item.expanded) { toggleItem(item, data.expanded); } }); } self.setOption = function(key, value) { if (key == 'data') { } else if (key == 'width') { } }; return that; };