oxjs/source/Ox.UI/js/List/Ox.TreeList.js

219 lines
6.6 KiB
JavaScript
Raw Normal View History

2011-07-29 18:48:43 +00:00
// vim: et:ts=4:sw=4:sts=4:ft=javascript
2011-05-16 08:24:46 +00:00
/*@
Ox.TreeList <f:Ox.Element> TreeList Object
() -> <f> TreeList Object
(options) -> <f> TreeList Object
(options, self) -> <f> TreeList Object
options <o> Options object
data <f|null> data to be parsed to items, needs documentation
items <a|[]> array of items
max <n|-1> maximum number of items that can be selected, -1 unlimited
min <n|0> minimum number of items that have to be selected
selected <a|[]> selected ids
width <n|256> list width
self <o> shared private variable
@*/
2011-04-22 22:03:10 +00:00
Ox.TreeList = function(options, self) {
// fixme: expanding the last item should cause some scroll
self = self || {};
var that = Ox.Element({}, self)
2011-04-22 22:03:10 +00:00
.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]));
2011-04-22 22:03:10 +00:00
});
//Ox.print('d', self.options.data, 'i', self.options.items)
}
that.$element = Ox.List({
2011-04-22 22:03:10 +00:00
construct: constructItem,
itemHeight: 16,
items: parseItems(),
itemWidth: self.options.width,
max: self.options.max,
min: self.options.min,
2011-05-12 03:29:35 +00:00
unique: 'id'
}, Ox.extend({}, self))
2011-04-22 22:03:10 +00:00
.addClass('OxTextList OxTreeList')
.css({
width: self.options.width + 'px'
})
.bindEvent({
anyclick: clickItem,
2011-04-22 22:03:10 +00:00
toggle: toggleItems
});
function clickItem(e) {
var $target = $(e.target),
$item, id, item;
if ($target.is('.OxToggle')) {
2011-04-22 22:03:10 +00:00
$item = $target.parent().parent();
id = $item.data('id');
item = getItemById(id);
toggleItem(item, !item.expanded);
2011-04-22 22:03:10 +00:00
}
}
function constructItem(data) {
var $item = $('<div>'), //.css({width: self.options.width + 'px'}),
2011-04-22 22:03:10 +00:00
padding = (data.level + !data.items) * 16 - 8;
if (data.level || !data.items) {
$('<div>')
.addClass('OxCell OxTarget')
.css({
width: padding + 'px',
})
.appendTo($item);
}
if (data.items) {
$('<div>')
.addClass('OxCell')
.css({
width: '8px',
})
.append(
// fixme: need Ox.Icon()
$('<img>')
.addClass('OxToggle')
.attr({
2011-08-09 17:00:39 +00:00
src: Ox.UI.getImageURL(
'symbol' + (data.expanded ? 'Down' : 'Right')
2011-04-22 22:03:10 +00:00
)
})
.css({
width: '10px',
height: '10px',
padding: '3px'
})
)
.appendTo($item);
}
$('<div>')
.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;
2011-04-22 22:03:10 +00:00
Ox.forEach(items, function(item) {
if (item.id == id) {
ret = Ox.extend(item, {
2011-04-22 22:03:10 +00:00
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(),
2011-07-26 14:36:31 +00:00
title: key.toString() + ': '
2011-04-22 22:03:10 +00:00
},
type = Ox.typeOf(value);
if (type == 'array' || type == 'object') {
ret.title += Ox.toTitleCase(type) + ' [' + Ox.len(value) + ']';
2011-04-22 22:03:10 +00:00
ret.items = Ox.map(Ox.sort(Ox.keys(value)), function(k) {
return parseData(k, value[k]);
2011-04-22 22:03:10 +00:00
});
} else {
2011-07-26 14:36:31 +00:00
ret.title += (
2011-04-22 22:03:10 +00:00
type == 'function' ?
2011-07-26 14:36:31 +00:00
value.toString().split('{')[0] :
JSON.stringify(value)
);
2011-04-22 22:03:10 +00:00
}
return ret;
}
function parseItems(items, level) {
var ret = [];
items = items || self.options.items;
level = level || 0;
2011-04-22 22:03:10 +00:00
items.forEach(function(item, i) {
var item_ = Ox.extend({
2011-04-22 22:03:10 +00:00
level: level
}, item, item.items ? {
items: !!item.expanded ?
parseItems(item.items, level + 1) : []
} : {});
ret.push(item_);
item.items && Ox.merge(ret, item_.items);
2011-04-22 22:03:10 +00:00
});
return ret;
}
function toggleItem(item, expanded) {
var $img, pos;
2011-04-22 22:03:10 +00:00
item.expanded = expanded;
2011-05-11 13:53:29 +00:00
//getItemById(item.id).expanded = expanded;
that.$element.find('.OxItem').each(function() {
var $item = $(this);
2011-04-22 22:03:10 +00:00
if ($item.data('id') == item.id) {
$img = $item.find('.OxToggle');
2011-04-22 22:03:10 +00:00
pos = $item.data('position');
return false;
}
});
$img.attr({
2011-08-09 17:00:39 +00:00
src: Ox.UI.getImageURL(
'symbol' + (expanded ? 'Down' : 'Right')
2011-04-22 22:03:10 +00:00
)
});
that.$element.value(item.id, 'expanded', expanded);
2011-05-11 13:53:29 +00:00
expanded ?
2011-04-22 22:03:10 +00:00
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(data) {
2011-04-22 22:03:10 +00:00
data.ids.forEach(function(id, i) {
var item = getItemById(id);
if (item.items && data.expanded != !!item.expanded) {
toggleItem(item, data.expanded);
}
});
}
2011-04-29 12:40:51 +00:00
self.setOption = function(key, value) {
2011-04-22 22:03:10 +00:00
if (key == 'data') {
2011-05-12 03:29:35 +00:00
} else if (key == 'width') {
2011-04-22 22:03:10 +00:00
}
};
return that;
};