adding List object

This commit is contained in:
Rolux 2010-06-25 17:55:25 +02:00
parent b5cf89ce73
commit bd08670324
5 changed files with 730 additions and 1 deletions

View file

@ -424,6 +424,7 @@ OxSelect
Layers Layers
================================================================================ ================================================================================
*/ */
.OxLayer { .OxLayer {
position: absolute; position: absolute;
width: 100%; width: 100%;
@ -444,6 +445,138 @@ Layers
overflow: hidden; overflow: hidden;
z-index: 10; z-index: 10;
} }
/*
================================================================================
Lists
================================================================================
*/
.OxListPage {
position: absolute;
}
.OxTextList .OxCell {
float: left;
height: 12px;
padding: 2px 4px 2px 4px;
}
.OxTextList .OxBar {
z-index: 10;
-moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.75);
-webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.75);
}
.OxTextList .OxBar .OxHead {
position: absolute;
left: 0;
right: 12px;
height: 16px;
overflow: hidden;
white-space: nowrap;
}
.OxTextList .OxBar .OxCell {
float: left;
padding: 2px 4px 2px 4px;
height: 12px;
}
.OxTextList .OxBar .OxCell:nthChild(1) {
margin-left: 0;
}
.OxTextList .OxBar .OxTitle {
float: left;
height: 15px;
padding: 1px 2px 0 2px;
font-weight: bold;
font-size: 10px;
text-overflow: ellipsis;
cursor: pointer;
overflow: hidden;
white-space: nowrap;
}
.OxTextList .OxBar .OxTitle:first-child {
padding-left: 4px;
}
.OxTextList .OxBar .OxOrder {
float: left;
width: 10px;
height: 13px;
padding: 3px 0 0 6px;
font-size: 7px;
display: none;
}
.OxTextList .OxBar .OxOrder.OxSelected {
cursor: pointer;
display: block;
}
.OxTextList .OxBar .OxResize {
float: left;
width: 5px;
height: 16px;
}
.OxTextList .OxBar .OxResize .OxLeft,
.OxTextList .OxBar .OxResize .OxCenter,
.OxTextList .OxBar .OxResize .OxRight {
float: left;
height: 16px;
cursor: ew-resize;
}
.OxTextList .OxBar .OxResize .OxLeft,
.OxTextList .OxBar .OxResize .OxRight {
width: 2px;
}
.OxTextList .OxBar .OxResize .OxCenter {
width: 1px;
}
.OxTextList .OxBar .OxResize .OxCenter {
float: left;
width: 1px;
height: 16px;
background: rgb(24, 24, 24);
cursor: ew-resize;
}
.OxTextList .OxBar .OxSelect {
position: absolute;
right: 0px;
width: 11px;
height: 16px;
font-size: 11px;
text-align: center;
cursor: pointer;
}
.OxTextList .OxBody {
float: left;
position: absolute;
left: 0;
top: 16px;
right: 0;
bottom: 0;
}
.OxTextList .OxBody .OxContent {
width: 100%;
}
.OxTextList .OxBody .OxItem {
height: 16px;
}
.OxTextList .OxBody .OxItem .OxCell {
float: left;
height: 14px;
padding: 2px 4px 0 4px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.OxTextList .OxBody .OxItem .OxSpace {
float: left;
width: 4px;
height: 16px;
}
.OxTextList .OxBody .OxItem .OxLine {
float: left;
width: 1px;
height: 16px;
}
/* /*
================================================================================ ================================================================================
Menus Menus

View file

@ -98,6 +98,58 @@ Forms
color: rgb(96, 96, 96) color: rgb(96, 96, 96)
} }
/*
================================================================================
Lists
================================================================================
*/
.OxThemeModern .OxTextList .OxItem .OxCell {
border-right: 1px solid rgb(32, 32, 32);
}
.OxThemeModern .OxTextList .OxItem:nth-child(odd) {
background: rgb(14, 14, 14);
}
.OxThemeModern .OxTextList .OxItem:nth-child(even) {
background: rgb(18, 18, 18);
}
.OxThemeModern .OxTextList .OxItem.OxSelected:nth-child(odd) {
background: rgb(30, 30, 30);
}
.OxThemeModern .OxTextList .OxItem.OxSelected:nth-child(even) {
background: rgb(34, 34, 34);
}
.OxThemeModern .OxTextList.OxFocus .OxItem.OxSelected:nth-child(odd) {
background: rgb(62, 62, 62);
}
.OxThemeModern .OxTextList.OxFocus .OxItem.OxSelected:nth-child(even) {
background: rgb(66, 66, 66);
}
.OxThemeModern .OxTextList .OxBar .OxSelected {
background: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(80, 80, 80)), color-stop(1, rgb(48, 48, 48)));
color: rgb(255, 255, 255);
}
.OxThemeModern .OxTextList .OxBar .OxOrder {
color: rgb(255, 255, 255);
}
.OxThemeModern .OxTextList .OxBar .OxResize .OxCenter {
background: rgb(24, 24, 24);
}
.OxThemeModern .OxTextList .OxBody .OxItem .OxCell {
border-right: 1px solid rgb(24, 24, 24);
}
.OxThemeModern .OxTextList .OxItem.OxSelected .OxCell {
border-right: 1px solid rgb(40, 40, 40);
}
.OxThemeModern .OxTextList.OxFocus .OxItem.OxSelected .OxCell {
border-right: 1px solid rgb(72, 72, 72);
color: rgb(255, 255, 255);
}
.OxThemeModern .OxTextList .OxBody .OxItem .OxLine {
background: rgb(24, 24, 24);
}
/* /*
================================================================================ ================================================================================
Menus Menus

View file

@ -686,6 +686,7 @@ requires
data: data, data: data,
time: Ox.getTime() time: Ox.getTime()
}; };
//Ox.print("callback", callback, "options.callback", options.callback, "data", data)
callback(data); callback(data);
} }
@ -2382,7 +2383,243 @@ requires
Ox.List = function(options, self) { Ox.List = function(options, self) {
var self = self || {}, var self = self || {},
that = new Ox.Container({}, self); that = new Ox.Container({}, self)
.defaults({
itemHeight: 16,
itemWidth: 16,
orientation: "vertical",
request: function() {}, // {sort:, range:, callback:}, without parameter returns {items, size etc.}
rowLength: 1,
sort: [],
type: "text"
})
.options(options || {});
Ox.print("self1", self)
$.extend(self, {
$items: [],
$pages: [],
page: 0,
pageLength: 100,
pages: 0,
selected: []
});
Ox.print("self2", self)
$.extend(self, {
pageWidth: self.options.orientation == "horizontal" ?
self.pageLength * self.options.itemWidth : 0,
pageHeight: self.options.orientation == "horizontal" ? 0 :
self.pageLength * self.options.itemHeight / self.options.rowLength
});
function addAllToSelection(pos) {
var arr,
len = self.$items.length;
if (!isSelected(pos)) {
if (selected.length == 0) {
addToSelection(pos);
} else {
if (Ox.min(selected) < pos) {
var arr = [pos];
for (var i = pos - 1; i >= 0; i--) {
if (isSelected(i)) {
$.each(arr, function(i, v) {
addToSelection(v);
});
break;
}
arr.push(i);
}
}
if (Ox.max(selected) > pos) {
var arr = [pos];
for (var i = pos + 1; i < len; i++) {
if (isSelected(i)) {
$.each(arr, function(i, v) {
addToSelection(v);
});
break;
}
arr.push(i);
}
}
}
}
}
function addToSelection(pos) {
if (!isSelected(pos)) {
selected.push(pos);
if (!Ox.isUndefined(self.$items[pos])) {
self.$items[pos].addClass("OxSelected");
}
Ox.Event.trigger("select_" + self.options.id, {
items: selected.length
});
}
}
function deselect(pos) {
if (isSelected(pos)) {
selected.splice(selected.indexOf(pos), 1);
if (!Ox.isUndefined(self.$items[pos])) {
self.$items[pos].removeClass("OxSelected");
}
Ox.Event.trigger("select_" + self.options.id, {
items: selected.length
});
}
}
function getNext() {
var pos = -1;
if (selected.length) {
var pos = Ox.max(selected) + 1;
if (pos == self.$items.length) {
pos = -1;
}
}
return pos;
}
function getPage() {
return self.options.orientation == "vertical"
? Math.floor(that.scrollTop() / pageHeight)
: Math.floor(that.scrollLeft() / pageWidth);
}
function getPrevious() {
var pos = -1;
if (selected.length) {
var pos = Ox.min(selected) - 1;
}
return pos;
}
function invertSelection() {
$.each(self.options.items, function(i, v) {
toggleSelection(i);
});
}
function isSelected(pos) {
return selected.indexOf(pos) > -1;
}
function loadPage(page, callback) {
if (page < 0 || page >= pages) {
return;
}
var offset = page * self.pageLength,
range = [offset, offset + (page < self.pages - 1 ?
self.pageLength : self.listLength % self.pageLength)];
if (Ox.isUndefined(self.$pages[page])) {
Ox.Request.send({
callback: function(data) {
self.$pages[page] = new Ox.ListPage();
if (self.options.type == "text") {
self.$pages[page].css({
top: (page * self.pageHeight) + "px"
});
} else {
self.$pages[page].css({
});
}
$.each(data, function(i, v) {
var pos = offset + i;
self.$items[pos] = new Ox.ListItem(v);
if (isSelected(pos)) {
self.$items[pos].addClass("OxSelected");
}
self.$items[pos].appendTo(self.$pages[page])
});
},
range: range,
sort: self.options.sort
});
}
self.$pages[page].appendTo(that.$content);
}
function loadPages(page, callback) {
var counter = 0,
fn = function() {
counter++;
counter == 2 && !Ox.isUndefined(callback) && callback();
};
loadPage(page, function() {
loadPage(page - 1, fn);
loadPage(page + 1, fn);
});
}
function select(pos) {
if (!isSelected(pos) || selected.length > 1) {
selectNone();
addToSelection(pos);
}
}
function selectAll() {
$.each(self.$items, function(i, v) {
addToSelection(i);
});
}
function selectNext() {
var pos = getNext();
if (pos > -1) {
select(pos);
scrollTo(pos);
}
}
function selectNone() {
$.each(self.$items, function(i, v) {
deselect(i);
});
}
function selectPrevious() {
var pos = getPrevious();
if (pos > -1) {
select(pos);
scrollTo(pos);
}
}
function selectQuery(str) {
$.each(self.$items, function(i, v) {
if (Ox.toLatin(v.title).toUpperCase().indexOf(str) == 0) {
select(i);
scrollTo(i);
return false;
}
});
}
function scrollTo(pos) {
}
function toggleSelection(pos) {
if (!isSelected(pos)) {
addToSelection(pos);
} else {
deselect(pos);
}
}
function unloadPage(page) {
!Ox.isUndefined(self.$pages[page]) && self.$pages[page].remove();
}
function unloadPages(page) {
unloadPage(page);
unloadPage(page - 1);
unloadPage(page + 1)
}
return that; return that;
@ -2392,6 +2629,250 @@ requires
}; };
Ox.ListPage = function(options, self) {
var self = self || {},
that = new Ox.Element({}, self)
.addClass("OxListPage");
return that;
};
Ox.TextList = function(options, self) {
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
columns: [],
request: function() {}, // {sort, range, keys, callback}
sort: {}
})
.options(options || {})
.addClass("OxTextList");
$.extend(self, {
columnWidths: [],
itemHeight: 16,
page: 0,
pageLength: 100,
scrollLeft: 0,
selectedColumn: getColumnById(self.options.sort.key)
});
$.extend(self, {
pageHeight: self.pageLength * self.itemHeight
});
Ox.print("self", self);
// Head
that.$bar = new Ox.Bar({
orientation: "horizontal",
size: 16
}).appendTo(that);
that.$head = new Ox.Container()
.addClass("OxHead")
.appendTo(that.$bar);
that.$head.$content.addClass("OxTitles");
that.$titles = [];
$.each(self.options.columns, function(i, v) {
var $order, $resize, $left, $center, $right;
self.columnWidths[i] = v.width;
that.$titles[i] = $("<div>")
.addClass("OxTitle")
.css({
width: (v.width - 9) + "px",
textAlign: v.align
})
.html(v.title)
.click(function() {
if (self.options.sort.key != v.id) {
that.sort(v.id, v.operator);
} else {
that.order(self.options.operator == "+" ? "-" : "+");
}
})
.appendTo(that.$head.$content.$element);
$order = $("<div>")
.addClass("OxOrder")
.html(oxui.symbols["triangle_" + (
self.options.sort.operator == "+" ? "up" : "down"
)])
.click(function() {
$(this).prev().trigger("click")
})
.appendTo(that.$head.$content.$element);
$resize = $("<div>")
.addClass("OxResize")
.mousedown(function(e) {
var initialWidth = self.columnWidths[i],
initialX = e.clientX;
$window.mousemove(function(e) {
var x = e.clientX,
width = Ox.limit(initialWidth - initialX + x, 40, 512);
resizeColumn(i, width);
});
$window.mouseup(function() {
$window.unbind("mousemove");
$window.unbind("mouseup");
});
})
.dblclick(function() {
resizeColumn(i, v.width);
})
.appendTo(that.$head.$content.$element);
$left = $("<div>").addClass("OxLeft").appendTo($resize);
$center = $("<div>").addClass("OxCenter").appendTo($resize);
$right = $("<div>").addClass("OxRight").appendTo($resize);
});
that.$head.$content.css({
width: Ox.sum(self.columnWidths) + "px"
});
toggleSelected(self.selectedColumn);
that.$titles[self.selectedColumn].css({
width: (self.options.columns[self.selectedColumn].width - 25) + "px"
});
that.$select = $("<div>")
.addClass("OxSelect")
.html(oxui.symbols.select)
.appendTo(that.$bar.$element);
// Body
self.options.request({
callback: function(result) {
Ox.print("result", result);
$.extend(self, {
listHeight: result.data.items * self.itemHeight,
listLength: result.data.items,
pages: Math.ceil(result.data.items / self.pageLength)
});
Ox.print("self", self);
that.$body = new Ox.List({
itemHeight: 16,
itemWidth: Ox.sum(self.columnWidths),
orientation: "vertical",
request: self.options.request,
sort: self.options.sort,
type: "text"
}, self)
.addClass("OxBody")
.scroll(function() {
var scrollLeft = $(this).scrollLeft();
if (scrollLeft != self.scrollLeft) {
self.scrollLeft = scrollLeft;
that.$head.scrollLeft(scrollLeft);
}
})
.appendTo(that);
Ox.print("that.$body", that.$body)
that.$body.$content.css({
width: Math.max(Ox.sum(self.columnWidths), that.$element.width() - 12) + "px",
height: self.listHeight + "px"
});
}
});
function constructItem(item, pos) {
var item = $("<div>")
.addClass("OxListItem")
.css({
width: Ox.sum(columnWidths) + "px"
})
.data("pos", pos)
.click(function() {});
$.each(self.options.columns, function(i, v) {
var $cell = $("<div>")
.addClass("OxCell OxColumn" + Ox.toTitleCase(v.id))
.css({
width: (columnWidths[i] - 9) + "px",
textAlign: v.align
})
.html(item[v.id])
.appendTo($item)
});
return $item;
}
function getColumnById(id) {
var pos = -1;
$.each(self.options.columns, function(i, v) {
if (v.id == id) {
pos = i;
return false;
}
});
return pos;
}
function resizeColumn(pos, width) {
self.columnWidths[pos] = width;
that.$head.$content.css({
width: (Ox.sum(self.columnWidths) + 2) + "px"
});
that.$titles[pos].css({
width: (width - 9 - (pos == self.selectedColumn ? 16 : 0)) + "px"
});
that.$body.$content.find(".OxItem").css({ // fixme: can we avoid this lookup?
width: Ox.sum(self.columnWidths) + "px"
});
that.$body.$content.css({
width: Math.max(Ox.sum(self.columnWidths), that.$element.width() - 12) + "px" // fixme: check if scrollbar visible, and listen to resize/toggle event
});
$(".OxColumn" + Ox.toTitleCase(args.columns[pos].id)).css({
width: (width - 9) + "px"
});
that.$body.clearCache();
}
function selectColumn(pos) {
that.sort(args.columns[pos].id, args.columns[pos].operator);
}
function toggleOrder(pos) {
self.options.columns[pos].operator = self.options.columns[pos].operator == "+" ? "-" : "+";
that.$titles[pos].next().html(oxui.symbols[
"triangle" + self.options.columns[pos].operator == "+" ? "up" : "down"
]);
}
function toggleSelected(pos) {
if (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() + pos == self.selectedColumn ? -16 : 16
) + "px"
});
}
that.order = function(operator) {
if (operator != self.options.sort.operator) {
self.options.sort.operator = operator;
toggleOrder(self.selectedColumn);
that.$body.order(operator);
}
};
that.sort = function(key, operator) {
if (key != self.options.sort.key || operator != self.options.sort.operator) {
self.options.sort = {
key: key,
operator: operator
};
toggleSelected(self.selectedColumn);
selectedColumn = getColumnById(key);
toggleSelected(self.selectedColumn);
that.$body.sort(self.options.sort.key, self.options.sort.operator);
}
};
return that;
};
/* /*
============================================================================ ============================================================================
Menus Menus

13
demos/test/list.html Normal file
View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" type="text/css" href="../../build/css/ox.ui.css"/>
<script type="text/javascript" src="../../build/js/jquery-1.4.2.js"></script>
<script type="text/javascript" src="../../build/js/ox.js"></script>
<script type="text/javascript" src="../../build/js/ox.ui.js"></script>
<script type="text/javascript" src="list.js"></script>
</head>
<body>
</body>
</html>

50
demos/test/list.js Normal file
View file

@ -0,0 +1,50 @@
$(function() {
Ox.theme("modern");
var $body = $("body"),
app = new Ox.App({
requestURL: "http://blackbook.local:8000/api/"
}),
$list = new Ox.TextList({
columns: [
{
align: "left",
id: "title",
operator: "+",
title: "Title",
width: 160
},
{
align: "left",
id: "director",
operator: "+",
title: "Director",
width: 160
},
{
align: "right",
id: "year",
operator: "-",
title: "Year",
width: 80
}
],
request: function(options) {
app.request("find", $.extend(options, {
query: {
conditions: [
{
key: "country",
value: "france",
operator: ""
}
],
operator: ""
}
}), options.callback);
},
sort: {
key: "year",
operator: "-"
}
}).appendTo($body);
});