forked from 0x2620/oxjs
better filesystem structure for modules and themes; 'minified' ui if debug option not set; dynamially generated map markers
This commit is contained in:
parent
358ee1bc96
commit
4489e88f44
596 changed files with 115093 additions and 17682 deletions
156
source/Ox.UI/js/List/Ox.IconItem.js
Normal file
156
source/Ox.UI/js/List/Ox.IconItem.js
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
Ox.IconItem = function(options, self) {
|
||||
|
||||
//Ox.print('IconItem', options, self)
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element({}, self)
|
||||
.defaults({
|
||||
height: 128,
|
||||
id: '',
|
||||
info: '',
|
||||
size: 128,
|
||||
title: '',
|
||||
width: 128,
|
||||
url: ''
|
||||
})
|
||||
.options(options || {})
|
||||
|
||||
$.extend(self, {
|
||||
fontSize: self.options.size == 64 ? 6 : 9,
|
||||
height: self.options.size * 1.5,
|
||||
lineLength: self.options.size == 64 ? 15 : 23,
|
||||
lines: self.options.size == 64 ? 4 : 5,
|
||||
url: Ox.PATH + '/png/Ox.UI/transparent.png',
|
||||
width: self.options.size
|
||||
});
|
||||
self.title = formatText(self.options.title, self.lines - 1, self.lineLength);
|
||||
self.info = formatText(self.options.info, 5 - self.title.split('<br/>').length, self.lineLength);
|
||||
|
||||
that.css({
|
||||
width: self.width + 'px',
|
||||
height: self.height + 'px'
|
||||
});
|
||||
that.$icon = $('<div>')
|
||||
.addClass('OxIcon')
|
||||
.css({
|
||||
top: self.options.size == 64 ? -64 : -124,
|
||||
width: (self.options.size + 4) + 'px',
|
||||
height: (self.options.size + 4) + 'px'
|
||||
});
|
||||
that.$iconImage = $('<img>')
|
||||
.addClass('OxLoading OxTarget')
|
||||
.attr({
|
||||
src: self.url
|
||||
})
|
||||
.css({
|
||||
width: self.options.width + 'px',
|
||||
height: self.options.height + 'px'
|
||||
})
|
||||
.mousedown(mousedown)
|
||||
.mouseenter(mouseenter)
|
||||
.mouseleave(mouseleave);
|
||||
self.options.url && that.$iconImage.one('load', load);
|
||||
that.$textBox = $('<div>')
|
||||
.addClass('OxText')
|
||||
.css({
|
||||
top: (self.options.size / 2) + 'px',
|
||||
width: (self.options.size + 4) + 'px',
|
||||
height: (self.options.size == 64 ? 30 : 58) + 'px'
|
||||
})
|
||||
that.$text = $('<div>')
|
||||
.addClass('OxTarget')
|
||||
.css({
|
||||
fontSize: self.fontSize + 'px'
|
||||
})
|
||||
.html(
|
||||
self.title + '<br/><span class="OxInfo">' + self.info + '</span>'
|
||||
)
|
||||
.mouseenter(mouseenter)
|
||||
.mouseleave(mouseleave);
|
||||
that.$reflection = $('<div>')
|
||||
.addClass('OxReflection')
|
||||
.css({
|
||||
top: self.options.size + 'px',
|
||||
width: (self.options.size + 4) + 'px',
|
||||
height: (self.options.size / 2) + 'px'
|
||||
});
|
||||
that.$reflectionImage = $('<img>')
|
||||
.addClass('OxLoading')
|
||||
.attr({
|
||||
src: self.url
|
||||
})
|
||||
.css({
|
||||
width: self.options.width + 'px',
|
||||
height: self.options.height + 'px',
|
||||
// firefox is 1px off when centering images with odd width and scaleY(-1)
|
||||
paddingLeft: ($.browser.mozilla && self.options.width % 2 ? 1 : 0) + 'px'
|
||||
});
|
||||
that.$gradient = $('<div>')
|
||||
.css({
|
||||
//top: (-self.options.size / 2) + 'px',
|
||||
width: self.options.width + 'px',
|
||||
height: (self.options.size / 2) + 'px'
|
||||
});
|
||||
|
||||
that.append(
|
||||
that.$reflection.append(
|
||||
that.$reflectionImage
|
||||
).append(
|
||||
that.$gradient
|
||||
)
|
||||
).append(
|
||||
that.$textBox.append(
|
||||
that.$text
|
||||
)
|
||||
).append(
|
||||
that.$icon.append(
|
||||
that.$iconImage
|
||||
)
|
||||
);
|
||||
|
||||
function formatText(text, maxLines, maxLength) {
|
||||
var lines = Ox.wordwrap(text, maxLength, '<br/>', true, false).split('<br/>');
|
||||
return $.map(lines, function(line, i) {
|
||||
if (i < maxLines - 1) {
|
||||
return line;
|
||||
} else if (i == maxLines - 1) {
|
||||
return lines.length == maxLines ? line : Ox.truncate($.map(lines, function(line, i) {
|
||||
return i < maxLines - 1 ? null : line;
|
||||
}).join(' '), maxLength, '...', 'center');
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}).join('<br/>');
|
||||
}
|
||||
|
||||
function load() {
|
||||
that.$iconImage.attr({
|
||||
src: self.options.url
|
||||
})
|
||||
.one('load', function() {
|
||||
that.$iconImage.removeClass('OxLoading');
|
||||
that.$reflectionImage
|
||||
.attr({
|
||||
src: self.options.url
|
||||
})
|
||||
.removeClass('OxLoading');
|
||||
});
|
||||
}
|
||||
|
||||
function mousedown(e) {
|
||||
// fixme: preventDefault keeps image from being draggable in safari - but also keeps the list from getting focus
|
||||
// e.preventDefault();
|
||||
}
|
||||
|
||||
function mouseenter() {
|
||||
that.addClass('OxHover');
|
||||
}
|
||||
|
||||
function mouseleave() {
|
||||
that.removeClass('OxHover');
|
||||
}
|
||||
|
||||
return that;
|
||||
|
||||
};
|
||||
139
source/Ox.UI/js/List/Ox.IconList.js
Normal file
139
source/Ox.UI/js/List/Ox.IconList.js
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
Ox.IconList = function(options, self) {
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element({}, self)
|
||||
.defaults({
|
||||
centerSelection: false,
|
||||
draggable: true,
|
||||
id: '',
|
||||
item: null,
|
||||
items: null,
|
||||
keys: [],
|
||||
max: -1,
|
||||
min: 0,
|
||||
orientation: 'both',
|
||||
selected: [],
|
||||
size: 128,
|
||||
sort: [],
|
||||
})
|
||||
.options(options || {});
|
||||
|
||||
$.extend(self, {
|
||||
itemHeight: self.options.size * 1.5,
|
||||
itemWidth: self.options.size
|
||||
});
|
||||
|
||||
that.$element = new Ox.List({
|
||||
centered: self.options.centered,
|
||||
construct: constructItem,
|
||||
draggable: self.options.draggable,
|
||||
id: self.options.id,
|
||||
itemHeight: self.itemHeight,
|
||||
items: self.options.items,
|
||||
itemWidth: self.itemWidth,
|
||||
keys: self.options.keys,
|
||||
orientation: self.options.orientation,
|
||||
keys: self.options.keys,
|
||||
max: self.options.max,
|
||||
min: self.options.min,
|
||||
selected: self.options.selected,
|
||||
size: self.options.size,
|
||||
sort: self.options.sort,
|
||||
type: 'icon',
|
||||
unique: self.options.unique
|
||||
}, $.extend({}, self)) // pass event handler
|
||||
.addClass('OxIconList Ox' + Ox.toTitleCase(self.options.orientation))
|
||||
.click(click)
|
||||
.dblclick(dblclick)
|
||||
.scroll(scroll);
|
||||
|
||||
updateKeys();
|
||||
|
||||
function click() {
|
||||
|
||||
}
|
||||
|
||||
function constructItem(data) {
|
||||
var data = !$.isEmptyObject(data) ?
|
||||
self.options.item(data, self.options.sort, self.options.size) :
|
||||
{height: 8, width: 5},
|
||||
ratio = data.width / data.height;
|
||||
return new Ox.IconItem($.extend(data, {
|
||||
height: Math.round(self.options.size / (ratio <= 1 ? 1 : ratio)),
|
||||
size: self.options.size,
|
||||
width: Math.round(self.options.size * (ratio >= 1 ? 1 : ratio))
|
||||
}));
|
||||
}
|
||||
|
||||
function dblclick() {
|
||||
|
||||
}
|
||||
|
||||
function scroll() {
|
||||
|
||||
}
|
||||
|
||||
function updateKeys() {
|
||||
self.options.keys = Ox.unique($.merge(self.options.keys, [self.options.sort[0].key]));
|
||||
that.$element.options({
|
||||
keys: self.options.keys
|
||||
});
|
||||
}
|
||||
|
||||
self.onChange = function(key, value) {
|
||||
if (key == 'items') {
|
||||
that.$element.options(key, value);
|
||||
} else if (key == 'paste') {
|
||||
that.$element.options(key, value);
|
||||
} else if (key == 'selected') {
|
||||
that.$element.options(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
that.closePreview = function() {
|
||||
that.$element.closePreview();
|
||||
};
|
||||
|
||||
that.paste = function(data) {
|
||||
that.$element.paste(data);
|
||||
return that;
|
||||
};
|
||||
|
||||
that.reloadList = function() {
|
||||
that.$element.reloadList();
|
||||
return that;
|
||||
};
|
||||
|
||||
that.scrollToSelection = function() {
|
||||
that.$element.scrollToSelection();
|
||||
};
|
||||
|
||||
that.size = function() {
|
||||
that.$element.size();
|
||||
};
|
||||
|
||||
that.sortList = function(key, operator) {
|
||||
self.options.sort = [{
|
||||
key: key,
|
||||
operator: operator
|
||||
}];
|
||||
updateKeys();
|
||||
that.$element.sortList(key, operator);
|
||||
};
|
||||
|
||||
that.value = function(id, key, value) {
|
||||
// fixme: make this accept id, {k: v, ...}
|
||||
if (arguments.length == 1) {
|
||||
return that.$element.value(id);
|
||||
} else if (arguments.length == 2) {
|
||||
return that.$element.value(id, key);
|
||||
} else {
|
||||
that.$element.value(id, key, value);
|
||||
return that;
|
||||
}
|
||||
}
|
||||
|
||||
return that;
|
||||
|
||||
};
|
||||
55
source/Ox.UI/js/List/Ox.ItemInput.js
Normal file
55
source/Ox.UI/js/List/Ox.ItemInput.js
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
Ox.ItemInput = function(options, self) {
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element({}, self)
|
||||
.defaults({
|
||||
type: 'textarea',
|
||||
value: '',
|
||||
height: 300,
|
||||
width: 100
|
||||
})
|
||||
.options(options || {}),
|
||||
$input;
|
||||
|
||||
that.append(
|
||||
$input = new Ox.Input({
|
||||
height: self.options.height,
|
||||
style: 'square',
|
||||
type: self.options.type,
|
||||
value: self.options.value,
|
||||
width: self.options.width + 6
|
||||
})
|
||||
.bind({
|
||||
mousedown: function(e) {
|
||||
// keep mousedown from reaching list
|
||||
e.stopPropagation();
|
||||
}
|
||||
})
|
||||
)
|
||||
.append(new Ox.Element()
|
||||
.append(new Ox.Button({type: 'text', title: 'Cancel'})
|
||||
.css('width', '42%')
|
||||
.bindEvent({
|
||||
'click': function() {
|
||||
that.triggerEvent('cancel');
|
||||
}
|
||||
}))
|
||||
.append(new Ox.Button({type: 'text', title: 'Save'})
|
||||
.css('width', '42%')
|
||||
.bindEvent({
|
||||
'click': function() {
|
||||
that.triggerEvent('save', {
|
||||
value: $input.value()
|
||||
});
|
||||
}
|
||||
}))
|
||||
.css({
|
||||
'margin-top': self.options.height-8,
|
||||
'height': '16px',
|
||||
'text-align': 'right',
|
||||
})
|
||||
);
|
||||
Ox.print($input);
|
||||
return that;
|
||||
}
|
||||
1423
source/Ox.UI/js/List/Ox.List.js
Normal file
1423
source/Ox.UI/js/List/Ox.List.js
Normal file
File diff suppressed because it is too large
Load diff
42
source/Ox.UI/js/List/Ox.ListItem.js
Normal file
42
source/Ox.UI/js/List/Ox.ListItem.js
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
Ox.ListItem = function(options, self) {
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element({}, self)
|
||||
.defaults({
|
||||
construct: function() {},
|
||||
data: {},
|
||||
draggable: false,
|
||||
position: 0,
|
||||
unique: ''
|
||||
})
|
||||
.options(options || {});
|
||||
|
||||
constructItem();
|
||||
|
||||
function constructItem(update) {
|
||||
var $element = self.options.construct(self.options.data)
|
||||
.addClass('OxItem')
|
||||
.attr({
|
||||
draggable: self.options.draggable
|
||||
})
|
||||
.data({
|
||||
id: self.options.data[self.options.unique],
|
||||
position: self.options.position
|
||||
});
|
||||
if (update) {
|
||||
that.$element.hasClass('OxSelected') && $element.addClass('OxSelected');
|
||||
that.$element.replaceWith($element);
|
||||
}
|
||||
that.$element = $element;
|
||||
}
|
||||
|
||||
self.onChange = function(key, value) {
|
||||
if (key == 'data') {
|
||||
constructItem(true);
|
||||
}
|
||||
}
|
||||
|
||||
return that;
|
||||
|
||||
};
|
||||
7
source/Ox.UI/js/List/Ox.ListPage.js
Normal file
7
source/Ox.UI/js/List/Ox.ListPage.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
Ox.ListPage = function(options, self) {
|
||||
var self = self || {},
|
||||
that = new Ox.Element({}, self)
|
||||
.addClass('OxPage');
|
||||
return that;
|
||||
};
|
||||
720
source/Ox.UI/js/List/Ox.TextList.js
Normal file
720
source/Ox.UI/js/List/Ox.TextList.js
Normal file
|
|
@ -0,0 +1,720 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
Ox.TextList = function(options, self) {
|
||||
|
||||
// fixme: rename to TableList
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element({}, self)
|
||||
.defaults({
|
||||
columns: [],
|
||||
columnsMovable: false,
|
||||
columnsRemovable: false,
|
||||
columnsResizable: false,
|
||||
columnsVisible: false,
|
||||
columnWidth: [40, 800],
|
||||
id: '',
|
||||
items: null, // function() {} {sort, range, keys, callback} or array
|
||||
max: -1,
|
||||
min: 0,
|
||||
pageLength: 100,
|
||||
scrollbarVisible: false,
|
||||
selected: [],
|
||||
sort: []
|
||||
})
|
||||
.options(options || {})
|
||||
.addClass('OxTextList');
|
||||
|
||||
Ox.print('Ox.TextList self.options', self.options)
|
||||
|
||||
self.options.columns.forEach(function(v) { // fixme: can this go into a generic ox.js function?
|
||||
// fixme: and can't these just remain undefined?
|
||||
if (Ox.isUndefined(v.align)) {
|
||||
v.align = 'left';
|
||||
}
|
||||
if (Ox.isUndefined(v.clickable)) {
|
||||
v.clickable = false;
|
||||
}
|
||||
if (Ox.isUndefined(v.editable)) {
|
||||
v.editable = false;
|
||||
}
|
||||
if (Ox.isUndefined(v.unique)) {
|
||||
v.unique = false;
|
||||
}
|
||||
if (Ox.isUndefined(v.visible)) {
|
||||
v.visible = false;
|
||||
}
|
||||
if (v.unique) {
|
||||
self.unique = v.id;
|
||||
}
|
||||
});
|
||||
|
||||
$.extend(self, {
|
||||
columnPositions: [],
|
||||
defaultColumnWidths: $.map(self.options.columns, function(v) {
|
||||
return v.defaultWidth || v.width;
|
||||
}),
|
||||
itemHeight: 16,
|
||||
page: 0,
|
||||
pageLength: 100,
|
||||
scrollLeft: 0,
|
||||
selectedColumn: getColumnIndexById(self.options.sort[0].key),
|
||||
visibleColumns: $.map(self.options.columns, function(v) {
|
||||
return v.visible ? v : null;
|
||||
})
|
||||
});
|
||||
// fixme: there might be a better way than passing both visible and position
|
||||
self.options.columns.forEach(function(v) {
|
||||
if (!Ox.isUndefined(v.position)) {
|
||||
self.visibleColumns[v.position] = v;
|
||||
}
|
||||
})
|
||||
$.extend(self, {
|
||||
columnWidths: $.map(self.visibleColumns, function(v, i) {
|
||||
return v.width;
|
||||
}),
|
||||
pageHeight: self.options.pageLength * self.itemHeight
|
||||
});
|
||||
|
||||
self.format = {};
|
||||
self.options.columns.forEach(function(v, i) {
|
||||
if (v.format) {
|
||||
self.format[v.id] = v.format;
|
||||
}
|
||||
});
|
||||
|
||||
// Head
|
||||
|
||||
if (self.options.columnsVisible) {
|
||||
that.$bar = new Ox.Bar({
|
||||
orientation: 'horizontal',
|
||||
size: 16
|
||||
}).appendTo(that);
|
||||
that.$head = new Ox.Container()
|
||||
.addClass('OxHead')
|
||||
.css({
|
||||
right: self.options.scrollbarVisible ? Ox.UI.SCROLLBAR_SIZE + 'px' : 0
|
||||
})
|
||||
.appendTo(that.$bar);
|
||||
that.$head.$content.addClass('OxTitles');
|
||||
constructHead();
|
||||
if (self.options.columnsRemovable) {
|
||||
that.$select = new Ox.Select({
|
||||
id: self.options.id + 'SelectColumns',
|
||||
items: $.map(self.options.columns, function(v, i) {
|
||||
return {
|
||||
checked: v.visible,
|
||||
disabled: v.removable === false,
|
||||
id: v.id,
|
||||
title: v.title
|
||||
}
|
||||
}),
|
||||
max: -1,
|
||||
min: 1,
|
||||
type: 'image'
|
||||
})
|
||||
.bindEvent('change', changeColumns)
|
||||
.appendTo(that.$bar.$element);
|
||||
}
|
||||
}
|
||||
|
||||
// Body
|
||||
|
||||
that.$body = new Ox.List({
|
||||
construct: constructItem,
|
||||
id: self.options.id,
|
||||
items: self.options.items,
|
||||
itemHeight: 16,
|
||||
items: self.options.items,
|
||||
itemWidth: getItemWidth(),
|
||||
format: self.format, // fixme: not needed, happens in TextList
|
||||
keys: $.map(self.visibleColumns, function(v) {
|
||||
return v.id;
|
||||
}),
|
||||
max: self.options.max,
|
||||
min: self.options.min,
|
||||
pageLength: self.options.pageLength,
|
||||
paste: self.options.paste,
|
||||
orientation: 'vertical',
|
||||
selected: self.options.selected,
|
||||
sort: self.options.sort,
|
||||
sortable: self.options.sortable,
|
||||
type: 'text',
|
||||
unique: self.unique
|
||||
}, $.extend({}, self)) // pass event handler
|
||||
.addClass('OxBody')
|
||||
.css({
|
||||
top: (self.options.columnsVisible ? 16 : 0) + 'px',
|
||||
overflowY: (self.options.scrollbarVisible ? 'scroll' : 'hidden')
|
||||
})
|
||||
.scroll(function() {
|
||||
var scrollLeft = $(this).scrollLeft();
|
||||
if (scrollLeft != self.scrollLeft) {
|
||||
self.scrollLeft = scrollLeft;
|
||||
that.$head && that.$head.scrollLeft(scrollLeft);
|
||||
}
|
||||
})
|
||||
.bindEvent({
|
||||
edit: function(event, data) {
|
||||
that.editCell(data.id, data.key);
|
||||
},
|
||||
select: function(event, data) {
|
||||
self.options.selected = data.ids;
|
||||
}
|
||||
})
|
||||
.appendTo(that);
|
||||
that.$body.$content.css({
|
||||
width: getItemWidth() + 'px'
|
||||
});
|
||||
|
||||
//Ox.print('s.vC', self.visibleColumns)
|
||||
|
||||
function addColumn(id) {
|
||||
//Ox.print('addColumn', id);
|
||||
var column, ids,
|
||||
index = 0;
|
||||
Ox.forEach(self.options.columns, function(v) {
|
||||
if (v.visible) {
|
||||
index++;
|
||||
} else if (v.id == id) {
|
||||
column = v;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
column.visible = true;
|
||||
self.visibleColumns.splice(index, 0, column);
|
||||
self.columnWidths.splice(index, 0, column.width);
|
||||
that.$head.$content.empty();
|
||||
constructHead();
|
||||
that.$body.options({
|
||||
keys: $.map(self.visibleColumns, function(v, i) {
|
||||
return v.id;
|
||||
})
|
||||
});
|
||||
that.$body.reloadPages();
|
||||
}
|
||||
|
||||
function changeColumns(event, data) {
|
||||
var add,
|
||||
ids = [];
|
||||
Ox.forEach(data.selected, function(column) {
|
||||
var index = getColumnIndexById(column.id);
|
||||
if (!self.options.columns[index].visible) {
|
||||
addColumn(column.id);
|
||||
add = true;
|
||||
return false;
|
||||
}
|
||||
ids.push(column.id);
|
||||
});
|
||||
if (!add) {
|
||||
Ox.forEach(self.visibleColumns, function(column) {
|
||||
if (ids.indexOf(column.id) == -1) {
|
||||
removeColumn(column.id);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
triggerColumnChangeEvent();
|
||||
}
|
||||
|
||||
function clickColumn(id) {
|
||||
Ox.print('clickColumn', id);
|
||||
var i = getColumnIndexById(id),
|
||||
isSelected = self.options.sort[0].key == self.options.columns[i].id;
|
||||
that.sortList(
|
||||
self.options.columns[i].id, isSelected ?
|
||||
(self.options.sort[0].operator == '+' ? '-' : '+') :
|
||||
self.options.columns[i].operator
|
||||
);
|
||||
}
|
||||
|
||||
function constructHead() {
|
||||
var offset = 0;
|
||||
that.$titles = [];
|
||||
self.columnOffsets = [];
|
||||
self.visibleColumns.forEach(function(v, i) {
|
||||
var $order, $resize, $left, $center, $right;
|
||||
offset += self.columnWidths[i];
|
||||
self.columnOffsets[i] = offset - self.columnWidths[i] / 2;
|
||||
that.$titles[i] = new Ox.Element()
|
||||
.addClass('OxTitle OxColumn' + Ox.toTitleCase(v.id))
|
||||
.css({
|
||||
width: (self.columnWidths[i] - 9) + 'px',
|
||||
textAlign: v.align
|
||||
})
|
||||
.html(v.title)
|
||||
.bindEvent({
|
||||
anyclick: function(event, e) {
|
||||
clickColumn(v.id);
|
||||
},
|
||||
dragstart: function(event, e) {
|
||||
dragstartColumn(v.id, e);
|
||||
},
|
||||
drag: function(event, e) {
|
||||
dragColumn(v.id, e);
|
||||
},
|
||||
dragend: function(event, e) {
|
||||
dragendColumn(v.id, e);
|
||||
}
|
||||
})
|
||||
.appendTo(that.$head.$content.$element);
|
||||
$order = $('<div>')
|
||||
.addClass('OxOrder')
|
||||
.html(Ox.UI.symbols['triangle_' + (
|
||||
v.operator == '+' ? 'up' : 'down'
|
||||
)])
|
||||
.click(function() {
|
||||
$(this).prev().trigger('click')
|
||||
})
|
||||
.appendTo(that.$head.$content.$element);
|
||||
$resize = new Ox.Element()
|
||||
.addClass('OxResize')
|
||||
.appendTo(that.$head.$content.$element);
|
||||
if (self.options.columnsResizable) {
|
||||
$resize.addClass('OxResizable')
|
||||
.bindEvent({
|
||||
doubleclick: function(event, e) {
|
||||
resetColumn(v.id, e);
|
||||
},
|
||||
dragstart: function(event, e) {
|
||||
dragstartResize(v.id, e);
|
||||
},
|
||||
drag: function(event, e) {
|
||||
dragResize(v.id, e);
|
||||
},
|
||||
dragend: function(event, e) {
|
||||
dragendResize(v.id, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
$left = $('<div>').addClass('OxLeft').appendTo($resize.$element);
|
||||
$center = $('<div>').addClass('OxCenter').appendTo($resize.$element);
|
||||
$right = $('<div>').addClass('OxRight').appendTo($resize.$element);
|
||||
});
|
||||
that.$head.$content.css({
|
||||
width: (Ox.sum(self.columnWidths) + 2) + 'px'
|
||||
});
|
||||
//Ox.print('s.sC', self.selectedColumn)
|
||||
//Ox.print('s.cO', self.columnOffsets)
|
||||
if (getColumnPositionById(self.options.columns[self.selectedColumn].id) > -1) { // fixme: save in var
|
||||
toggleSelected(self.options.columns[self.selectedColumn].id);
|
||||
that.$titles[getColumnPositionById(self.options.columns[self.selectedColumn].id)].css({
|
||||
width: (self.options.columns[self.selectedColumn].width - 25) + 'px'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function constructItem(data) {
|
||||
var $item = $('<div>')
|
||||
.addClass('OxTarget')
|
||||
.css({
|
||||
width: getItemWidth() + 'px'
|
||||
});
|
||||
self.visibleColumns.forEach(function(v, i) {
|
||||
var clickable = Ox.isBoolean(v.clickable) ? v.clickable : v.clickable(data),
|
||||
editable = Ox.isBoolean(v.editable) ? v.editable : v.editable(data),
|
||||
$cell = $('<div>')
|
||||
.addClass(
|
||||
'OxCell OxColumn' + Ox.toTitleCase(v.id) +
|
||||
(clickable ? ' OxClickable' : '') +
|
||||
(editable ? ' OxEditable' : '')
|
||||
)
|
||||
.css({
|
||||
width: (self.columnWidths[i] - (self.options.columnsVisible ? 9 : 8)) + 'px',
|
||||
borderRightWidth: (self.options.columnsVisible ? 1 : 0) + 'px',
|
||||
textAlign: v.align
|
||||
})
|
||||
.html(v.id in data ? formatValue(data[v.id], v.format) : '')
|
||||
.appendTo($item);
|
||||
});
|
||||
function formatValue(value, format) {
|
||||
if (value === null) {
|
||||
value = '';
|
||||
} else if (format) {
|
||||
value = Ox.isObject(format) ?
|
||||
Ox['format' + Ox.toTitleCase(format.type)]
|
||||
.apply(this, $.merge([value], format.args)) :
|
||||
format(value);
|
||||
} else if (Ox.isArray(value)) {
|
||||
value = value.join(', ');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
//Math.random() < 0.01 && Ox.print('item', data, $item);
|
||||
return $item;
|
||||
}
|
||||
|
||||
function dragstartColumn(id, e) {
|
||||
self.drag = {
|
||||
startX: e.clientX,
|
||||
startPos: getColumnPositionById(id)
|
||||
}
|
||||
$.extend(self.drag, {
|
||||
stopPos: self.drag.startPos,
|
||||
offsets: $.map(self.visibleColumns, function(v, i) {
|
||||
return self.columnOffsets[i] - self.columnOffsets[self.drag.startPos]
|
||||
})
|
||||
});
|
||||
$('.OxColumn' + Ox.toTitleCase(id)).css({
|
||||
opacity: 0.25
|
||||
});
|
||||
that.$titles[self.drag.startPos].addClass('OxDrag').css({ // fixme: why does the class not work?
|
||||
cursor: 'move'
|
||||
});
|
||||
}
|
||||
|
||||
function dragColumn(id, e) {
|
||||
var d = e.clientX - self.drag.startX,
|
||||
pos = self.drag.stopPos;
|
||||
Ox.forEach(self.drag.offsets, function(v, i) {
|
||||
if (d < 0 && d < v) {
|
||||
self.drag.stopPos = i;
|
||||
return false;
|
||||
} else if (d > 0 && d > v) {
|
||||
self.drag.stopPos = i;
|
||||
}
|
||||
});
|
||||
if (self.drag.stopPos != pos) {
|
||||
moveColumn(id, self.drag.stopPos);
|
||||
}
|
||||
}
|
||||
|
||||
function dragendColumn(id, e) {
|
||||
var column = self.visibleColumns.splice(self.drag.stopPos, 1)[0],
|
||||
width = self.columnWidths.splice(self.drag.stopPos, 1)[0];
|
||||
self.visibleColumns.splice(self.drag.stopPos, 0, column);
|
||||
self.columnWidths.splice(self.drag.stopPos, 0, width);
|
||||
that.$head.$content.empty();
|
||||
constructHead();
|
||||
$('.OxColumn' + Ox.toTitleCase(id)).css({
|
||||
opacity: 1
|
||||
});
|
||||
that.$titles[self.drag.stopPos].removeClass('OxDrag').css({
|
||||
cursor: 'pointer'
|
||||
});
|
||||
that.$body.clearCache();
|
||||
triggerColumnChangeEvent();
|
||||
}
|
||||
|
||||
function dragstartResize(id, e) {
|
||||
var pos = getColumnPositionById(id);
|
||||
self.drag = {
|
||||
startX: e.clientX,
|
||||
startWidth: self.columnWidths[pos]
|
||||
};
|
||||
}
|
||||
|
||||
function dragResize(id, e) {
|
||||
var width = Ox.limit(
|
||||
self.drag.startWidth - self.drag.startX + e.clientX,
|
||||
self.options.columnWidth[0],
|
||||
self.options.columnWidth[1]
|
||||
);
|
||||
resizeColumn(id, width);
|
||||
}
|
||||
|
||||
function dragendResize(id, e) {
|
||||
var pos = getColumnPositionById(id);
|
||||
that.triggerEvent('columnresize', {
|
||||
id: id,
|
||||
width: self.columnWidths[pos]
|
||||
});
|
||||
}
|
||||
|
||||
function getCell(id, key) {
|
||||
Ox.print('getCell', id, key)
|
||||
var $item = getItem(id);
|
||||
return $($item.find('.OxCell.OxColumn' + Ox.toTitleCase(key))[0]);
|
||||
}
|
||||
|
||||
function getColumnIndexById(id) {
|
||||
return Ox.getPositionById(self.options.columns, id);
|
||||
}
|
||||
|
||||
function getColumnPositionById(id) {
|
||||
return Ox.getPositionById(self.visibleColumns, id);
|
||||
}
|
||||
|
||||
function getItem(id) {
|
||||
//Ox.print('getItem', id)
|
||||
var $item = null;
|
||||
$.each(that.find('.OxItem'), function(i, v) {
|
||||
$v = $(v);
|
||||
if ($v.data('id') == id) {
|
||||
$item = $v;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return $item;
|
||||
}
|
||||
|
||||
function getItemWidth() {
|
||||
return Math.max(
|
||||
Ox.sum(self.columnWidths),
|
||||
that.$element.width() -
|
||||
(self.options.scrollbarVisible ? Ox.UI.SCROLLBAR_SIZE : 0)
|
||||
);
|
||||
//return Ox.sum(self.columnWidths)
|
||||
}
|
||||
|
||||
function moveColumn(id, pos) {
|
||||
// fixme: column head should be one element, not three
|
||||
//Ox.print('moveColumn', id, pos)
|
||||
var startPos = getColumnPositionById(id),
|
||||
stopPos = pos,
|
||||
startClassName = '.OxColumn' + Ox.toTitleCase(id),
|
||||
stopClassName = '.OxColumn' + Ox.toTitleCase(self.visibleColumns[stopPos].id),
|
||||
insert = startPos < stopPos ? 'insertAfter' : 'insertBefore'
|
||||
$column = $('.OxTitle' + startClassName),
|
||||
$order = $column.next(),
|
||||
$resize = $order.next();
|
||||
//Ox.print(startClassName, insert, stopClassName)
|
||||
$column.detach()[insert](insert == 'insertAfter' ? $('.OxTitle' + stopClassName).next().next() : $('.OxTitle' + stopClassName));
|
||||
$order.detach().insertAfter($column);
|
||||
$resize.detach().insertAfter($order);
|
||||
$.each(that.$body.find('.OxItem'), function(i, v) {
|
||||
var $v = $(v);
|
||||
$v.children(startClassName).detach()[insert]($v.children(stopClassName));
|
||||
});
|
||||
var column = self.visibleColumns.splice(startPos, 1)[0],
|
||||
width = self.columnWidths.splice(startPos, 1)[0];
|
||||
self.visibleColumns.splice(stopPos, 0, column);
|
||||
self.columnWidths.splice(stopPos, 0, width);
|
||||
}
|
||||
|
||||
function removeColumn(id) {
|
||||
//Ox.print('removeColumn', id);
|
||||
var className = '.OxColumn' + Ox.toTitleCase(id),
|
||||
index = getColumnIndexById(id),
|
||||
itemWidth,
|
||||
position = getColumnPositionById(id),
|
||||
$column = $('.OxTitle' + className),
|
||||
$order = $column.next(),
|
||||
$resize = $order.next();
|
||||
self.options.columns[index].visible = false;
|
||||
self.visibleColumns.splice(position, 1);
|
||||
self.columnWidths.splice(position, 1);
|
||||
that.$head.$content.empty();
|
||||
constructHead();
|
||||
itemWidth = getItemWidth();
|
||||
$.each(that.$body.find('.OxItem'), function(i, v) {
|
||||
var $v = $(v);
|
||||
$v.children(className).remove();
|
||||
$v.css({
|
||||
width: itemWidth + 'px'
|
||||
});
|
||||
});
|
||||
that.$body.$content.css({
|
||||
width: itemWidth + 'px'
|
||||
});
|
||||
that.$body.options({
|
||||
keys: $.map(self.visibleColumns, function(v, i) {
|
||||
return v.id;
|
||||
})
|
||||
});
|
||||
//that.$body.clearCache();
|
||||
}
|
||||
|
||||
function resetColumn(id) {
|
||||
var width = self.defaultColumnWidths[getColumnIndexById(id)];
|
||||
resizeColumn(id, width);
|
||||
that.triggerEvent('columnresize', {
|
||||
id: id,
|
||||
width: width
|
||||
});
|
||||
}
|
||||
|
||||
function resizeColumn(id, width) {
|
||||
var i = getColumnIndexById(id),
|
||||
pos = getColumnPositionById(id);
|
||||
self.options.columns[i].width = width;
|
||||
self.columnWidths[pos] = width;
|
||||
if (self.options.columnsVisible) {
|
||||
that.$head.$content.css({
|
||||
width: (Ox.sum(self.columnWidths) + 2) + 'px'
|
||||
});
|
||||
that.$titles[pos].css({
|
||||
width: (width - 9 - (i == self.selectedColumn ? 16 : 0)) + 'px'
|
||||
});
|
||||
}
|
||||
that.find('.OxCell.OxColumn' + Ox.toTitleCase(self.options.columns[i].id)).css({
|
||||
width: (width - (self.options.columnsVisible ? 9 : 8)) + 'px'
|
||||
});
|
||||
setWidth();
|
||||
}
|
||||
|
||||
function setWidth() {
|
||||
var width = getItemWidth();
|
||||
that.$body.$content.find('.OxItem').css({ // fixme: can we avoid this lookup?
|
||||
width: width + 'px'
|
||||
});
|
||||
that.$body.$content.css({
|
||||
width: width + 'px' // fixme: check if scrollbar visible, and listen to resize/toggle event
|
||||
});
|
||||
}
|
||||
|
||||
function toggleSelected(id) {
|
||||
var pos = getColumnPositionById(id);
|
||||
if (pos > -1) {
|
||||
updateOrder(id);
|
||||
pos > 0 && that.$titles[pos].prev().children().eq(2).toggleClass('OxSelected');
|
||||
that.$titles[pos].toggleClass('OxSelected');
|
||||
that.$titles[pos].next().toggleClass('OxSelected');
|
||||
that.$titles[pos].next().next().children().eq(0).toggleClass('OxSelected');
|
||||
that.$titles[pos].css({
|
||||
width: (
|
||||
that.$titles[pos].width() + (that.$titles[pos].hasClass('OxSelected') ? -16 : 16)
|
||||
) + 'px'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function triggerColumnChangeEvent() {
|
||||
that.triggerEvent('columnchange', {
|
||||
ids: $.map(self.visibleColumns, function(v, i) {
|
||||
return v.id;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function updateOrder(id) {
|
||||
var pos = getColumnPositionById(id);
|
||||
//Ox.print(id, pos)
|
||||
that.$titles[pos].next().html(Ox.UI.symbols[
|
||||
'triangle_' + (self.options.sort[0].operator == '+' ? 'up' : 'down')
|
||||
]);
|
||||
}
|
||||
|
||||
self.onChange = function(key, value) {
|
||||
if (key == 'items') {
|
||||
//alert('request set!!')
|
||||
that.$body.options(key, value);
|
||||
} else if (key == 'paste') {
|
||||
that.$body.options(key, value);
|
||||
} else if (key == 'selected') {
|
||||
that.$body.options(key, value);
|
||||
}
|
||||
};
|
||||
|
||||
// fixme: doesn't work, doesn't return that
|
||||
that.closePreview = that.$body.closePreview;
|
||||
|
||||
that.editCell = function(id, key) {
|
||||
Ox.print('editCell', id, key)
|
||||
var $item = getItem(id),
|
||||
$cell = getCell(id, key),
|
||||
$input,
|
||||
html = $cell.html(),
|
||||
index = getColumnIndexById(key),
|
||||
column = self.options.columns[index],
|
||||
width = column.width - self.options.columnsVisible;
|
||||
$cell.empty()
|
||||
.addClass('OxEdit')
|
||||
.css({
|
||||
width: width + 'px'
|
||||
});
|
||||
$input = new Ox.Input({
|
||||
autovalidate: column.input ? column.input.autovalidate : null,
|
||||
style: 'square',
|
||||
value: html,
|
||||
width: width
|
||||
})
|
||||
.bind({
|
||||
mousedown: function(e) {
|
||||
// keep mousedown from reaching list
|
||||
e.stopPropagation();
|
||||
}
|
||||
})
|
||||
.bindEvent({
|
||||
blur: submit,
|
||||
})
|
||||
.appendTo($cell);
|
||||
//.focusInput();
|
||||
setTimeout($input.focusInput, 0); // fixme: strange
|
||||
function submit() {
|
||||
var value = $input.value();
|
||||
//$input.loseFocus().remove();
|
||||
// fixme: leaky, inputs remain in focus stack
|
||||
$cell.removeClass('OxEdit')
|
||||
.css({
|
||||
width: (width - 8) + 'px'
|
||||
})
|
||||
.html(value)
|
||||
that.triggerEvent('submit', {
|
||||
id: id,
|
||||
key: key,
|
||||
value: value
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
that.gainFocus = function() {
|
||||
that.$body.gainFocus();
|
||||
return that;
|
||||
};
|
||||
|
||||
that.loseFocus = function() {
|
||||
that.$body.loseFocus();
|
||||
return that;
|
||||
}
|
||||
|
||||
that.paste = function(data) {
|
||||
that.$body.paste();
|
||||
return that;
|
||||
};
|
||||
|
||||
that.reloadList = function() {
|
||||
that.$body.reloadList();
|
||||
return that;
|
||||
};
|
||||
|
||||
that.resizeColumn = function(id, width) {
|
||||
resizeColumn(id, width);
|
||||
return that;
|
||||
}
|
||||
|
||||
that.size = function() {
|
||||
setWidth();
|
||||
that.$body.size();
|
||||
}
|
||||
|
||||
that.sortList = function(key, operator) {
|
||||
var isSelected = key == self.options.sort[0].key;
|
||||
self.options.sort = [{key: key, operator: operator}];
|
||||
if (self.options.columnsVisible) {
|
||||
if (isSelected) {
|
||||
updateOrder(self.options.columns[self.selectedColumn].id);
|
||||
} else {
|
||||
toggleSelected(self.options.columns[self.selectedColumn].id);
|
||||
self.selectedColumn = getColumnIndexById(key);
|
||||
toggleSelected(self.options.columns[self.selectedColumn].id);
|
||||
}
|
||||
}
|
||||
that.$body.sortList(self.options.sort[0].key, self.options.sort[0].operator);
|
||||
return that;
|
||||
};
|
||||
|
||||
that.value = function(id, key, value) {
|
||||
// fixme: make this accept id, {k: v, ...}
|
||||
var $item = getItem(id),
|
||||
//$cell = getCell(id, key),
|
||||
column = self.options.columns[getColumnIndexById(key)];
|
||||
if (arguments.length == 1) {
|
||||
return that.$body.value(id);
|
||||
} else if (arguments.length == 2) {
|
||||
return that.$body.value(id, key);
|
||||
} else {
|
||||
that.$body.value(id, key, value);
|
||||
/*
|
||||
$cell && $cell.html(column.format ? column.format(value) : value);
|
||||
if (column.unique) {
|
||||
that.$body.setId($item.data('id'), value);
|
||||
$item.data({id: value});
|
||||
}
|
||||
*/
|
||||
return that;
|
||||
}
|
||||
}
|
||||
|
||||
return that;
|
||||
|
||||
};
|
||||
197
source/Ox.UI/js/List/Ox.TreeList.js
Normal file
197
source/Ox.UI/js/List/Ox.TreeList.js
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
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 = $('<div>'),
|
||||
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.getImagePath(
|
||||
'symbol' + (data.expanded ? 'Down' : 'Right') + '.svg'
|
||||
)
|
||||
})
|
||||
.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 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;
|
||||
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue