Ox.TreeList = function(options, self) { var self = self || {}, that = new Ox.Element('div', 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(self.options.data, function(value, key) { self.options.items.push(parseData(key, value)); }); //Ox.print('d', self.options.data, 'i', self.options.items) } that.$element = new 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.hasClass('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.getImagePath( 'symbol' + (data.expanded ? 'Down' : 'Right') + '.svg' ) }) .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 items = items || self.options.items, level = level || 0, ret = null; 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: key, title: key.toString().split('.').pop() }, type = Ox.typeOf(value); if (type == 'array' || type == 'object') { ret.title += ': ' + Ox.toTitleCase(Ox.typeOf(value)); ret.items = Ox.map(Ox.sort(Ox.keys(value)), function(k) { return parseData(key + '.' + k, value[k]); }); } else { ret.title += ': ' + ( type == 'function' ? value.toString().split('{')[0] : JSON.stringify(value) ) } return ret; } function parseItems(items, level) { var items = items || self.options.items, level = level || 0, ret = []; 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, $item, pos; item.expanded = expanded; $.each(that.$element.find('.OxItem'), function(i, v) { var $item = $(v); if ($item.data('id') == item.id) { $img = $item.find('img'); pos = $item.data('position'); return false; } }); Ox.print('i.e', item.expanded) $img.attr({ src: Ox.UI.getImagePath( 'symbol' + (item.expanded ? 'Down' : 'Right') + '.svg' ) }); item.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.onChange = function(key, value) { if (key == 'data') { } }; return that; };