forked from 0x2620/oxjs
rename Ox.UI source files, remove Ox. prefix
This commit is contained in:
parent
005d50c389
commit
91e1065aab
101 changed files with 0 additions and 0 deletions
290
source/Ox.UI/js/List/TreeList.js
Normal file
290
source/Ox.UI/js/List/TreeList.js
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
'use strict';
|
||||
|
||||
/*@
|
||||
Ox.TreeList <f:Ox.Element> TreeList Object
|
||||
([options[, self]]) -> <o> 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
|
||||
@*/
|
||||
|
||||
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: 'auto'
|
||||
})
|
||||
.options(options || {})
|
||||
.update({
|
||||
data: function() {
|
||||
// ...
|
||||
},
|
||||
selected: function() {
|
||||
//self.$list.options({selected: self.options.selected});
|
||||
selectItem({ids: self.options.selected});
|
||||
self.$list.scrollToSelection();
|
||||
},
|
||||
width: function() {
|
||||
// ...
|
||||
}
|
||||
});
|
||||
|
||||
if (self.options.data) {
|
||||
self.options.items = [];
|
||||
Ox.sort(Object.keys(self.options.data)).forEach(function(key) {
|
||||
self.options.items.push(parseData(key, self.options.data[key]));
|
||||
});
|
||||
}
|
||||
|
||||
that.setElement(
|
||||
self.$list = Ox.List({
|
||||
_tree: true,
|
||||
construct: constructItem,
|
||||
itemHeight: 16,
|
||||
items: parseItems(),
|
||||
itemWidth: self.options.width,
|
||||
keys: ['expanded', 'id', 'items', 'level', 'title'],
|
||||
max: self.options.max,
|
||||
min: self.options.min,
|
||||
unique: 'id'
|
||||
}, Ox.clone(self))
|
||||
.addClass('OxTextList OxTreeList')
|
||||
.css({
|
||||
width: self.options.width + 'px',
|
||||
overflowY: 'scroll'
|
||||
})
|
||||
.bindEvent({
|
||||
anyclick: clickItem,
|
||||
select: selectItem,
|
||||
toggle: toggleItems
|
||||
})
|
||||
);
|
||||
|
||||
self.options.selected.length && selectItem({ids: self.options.selected});
|
||||
|
||||
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 = $('<div>').css({width: self.options.width + 'px'}),
|
||||
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({
|
||||
src: Ox.UI.getImageURL(
|
||||
'symbol' + (data.expanded ? 'Down' : 'Right')
|
||||
)
|
||||
})
|
||||
)
|
||||
.appendTo($item);
|
||||
}
|
||||
$('<div>')
|
||||
.addClass('OxCell OxTarget' + (!data.items ? ' OxSelectable' : ''))
|
||||
.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 = Ox.extend(item, {
|
||||
level: level
|
||||
});
|
||||
Ox.Break();
|
||||
}
|
||||
if (item.items) {
|
||||
ret = getItemById(id, item.items, level + 1);
|
||||
if (ret) {
|
||||
Ox.Break();
|
||||
}
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getParent(id, items) {
|
||||
var ret;
|
||||
Ox.forEach(items, function(item) {
|
||||
if (item.items) {
|
||||
if (Ox.getObjectById(item.items, id)) {
|
||||
ret = item.id;
|
||||
} else {
|
||||
ret = getParent(id, item.items);
|
||||
}
|
||||
if (ret) {
|
||||
Ox.Break();
|
||||
}
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
function parseData(key, value) {
|
||||
var ret = {
|
||||
expanded: false,
|
||||
id: Ox.uid().toString(),
|
||||
title: key.toString() + ': '
|
||||
},
|
||||
type = Ox.typeOf(value);
|
||||
if (type == 'array' || type == 'object') {
|
||||
ret.title += Ox.toTitleCase(type)
|
||||
+ ' <span class="OxLight">[' + Ox.len(value) + ']</span>';
|
||||
ret.items = Ox.sort(
|
||||
type == 'array' ? value.map(function(v, i) {
|
||||
return parseData(i, v);
|
||||
}) : Object.keys(value).map(function(k) {
|
||||
return parseData(k, value[k]);
|
||||
})
|
||||
);
|
||||
} else {
|
||||
ret.title += (
|
||||
type == 'function'
|
||||
? value.toString().split('{')[0]
|
||||
: JSON.stringify(value)
|
||||
.replace(/(^"|"$)/g, '<span class="OxLight">"</span>')
|
||||
);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function parseItems(items, level) {
|
||||
var ret = [];
|
||||
items = items || self.options.items;
|
||||
level = level || 0;
|
||||
items.forEach(function(item, i) {
|
||||
var item_ = Ox.extend({
|
||||
level: level
|
||||
}, item, item.items
|
||||
? {
|
||||
items: !!item.expanded
|
||||
? parseItems(item.items, level + 1)
|
||||
: []
|
||||
}
|
||||
: {}
|
||||
);
|
||||
ret.push(item_);
|
||||
if (item.items) {
|
||||
ret = ret.concat(item_.items);
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
function selectItem(data) {
|
||||
var id = data.ids[0], parent = id, parents = [];
|
||||
while (parent = getParent(parent, self.options.items)) {
|
||||
parents.push(parent);
|
||||
}
|
||||
parents = parents.reverse();
|
||||
toggleItems({
|
||||
expanded: true,
|
||||
ids: parents
|
||||
});
|
||||
self.$list.options({selected: data.ids})
|
||||
}
|
||||
|
||||
function toggleItem(item, expanded) {
|
||||
var $img, pos;
|
||||
item.expanded = expanded;
|
||||
that.find('.OxItem').each(function() {
|
||||
var $item = $(this);
|
||||
if ($item.data('id') == item.id) {
|
||||
$img = $item.find('.OxToggle');
|
||||
pos = $item.data('position');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
//that.$element.value(item.id, 'expanded', expanded);
|
||||
$img.attr({
|
||||
src: Ox.UI.getImageURL(
|
||||
'symbol' + (expanded ? 'Down' : 'Right')
|
||||
)
|
||||
});
|
||||
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(data) {
|
||||
data.ids.forEach(function(id, i) {
|
||||
var item = getItemById(id);
|
||||
if (item.items && data.expanded != !!item.expanded) {
|
||||
toggleItem(item, data.expanded);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*@
|
||||
gainFocus <f> gainFocus
|
||||
@*/
|
||||
that.gainFocus = function() {
|
||||
self.$list.gainFocus();
|
||||
return that;
|
||||
};
|
||||
|
||||
/*@
|
||||
hasFocus <f> hasFocus
|
||||
@*/
|
||||
that.hasFocus = function() {
|
||||
return self.$list.hasFocus();
|
||||
};
|
||||
|
||||
/*@
|
||||
loseFocus <f> loseFocus
|
||||
@*/
|
||||
that.loseFocus = function() {
|
||||
self.$list.loseFocus();
|
||||
return that;
|
||||
};
|
||||
|
||||
return that;
|
||||
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue