diff --git a/build/js/ox.ui.js b/build/js/ox.ui.js index e4f717f5..f0116afd 100644 --- a/build/js/ox.ui.js +++ b/build/js/ox.ui.js @@ -45,6 +45,7 @@ requires }(), path: $("script[src*=ox.ui.js]").attr("src") .replace("js/ox.ui.js", ""), + scrollbarSize: $.browser.mozilla ? 16 : 12, symbols: { alt: "\u2325", apple: "\uF8FF", @@ -290,6 +291,7 @@ requires blur: function(id) { if (stack.indexOf(id) > -1) { $elements[Ox.Focus.focused()].removeClass("OxFocus"); + $(".OxFocus").removeClass("OxFocus"); // fixme: the above is better, and should work stack.splice(stack.length - 2, 0, stack.pop()); Ox.Event.unbindKeyboard(id); Ox.Event.bindKeyboard(stack[stack.length - 1]); @@ -656,7 +658,7 @@ requires } ], width: 400, - height: 100 + height: 200 }) .append("Sorry, we have encountered an application error while handling your request. To help us find out what went wrong, you may want to report this error to an administrator. Otherwise, please try again later.") .open(); @@ -2383,12 +2385,15 @@ requires request: function() {}, // {sort:, range:, callback:}, without parameter returns {items, size etc.} rowLength: 1, sort: [], - type: "text" + type: "text", + unique: "" }) .options(options || {}) .click(click) .scroll(scroll); + Ox.print("self.options.unique", self.options.unique) + $.extend(self, { $items: [], $pages: [], @@ -2412,26 +2417,8 @@ requires self.keyboardEvents["key_" + (self.options.orientation == "horizontal" ? "shift_left" : "shift_up")] = addPreviousToSelection; self.keyboardEvents["key_" + (self.options.orientation == "horizontal" ? "shift_right" : "shift_down")] = addNextToSelection; - self.options.request({ - callback: function(result) { - var keys = {}; - Ox.print("items", result.data.items); - $.extend(self, { - listHeight: result.data.items * self.options.itemHeight, // fixme: should be listSize - listLength: result.data.items, - pages: Math.ceil(result.data.items / self.pageLength), - 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 - }); - that.$content.css({ - height: self.listHeight + "px" - }); - loadPages(self.page); - that.bindEvent(self.keyboardEvents); - } - }); + updateQuery(); + that.bindEvent(self.keyboardEvents); function addAllToSelection(pos) { var arr, @@ -2488,15 +2475,28 @@ requires if (!isSelected(pos)) { self.selected.push(pos); if (!Ox.isUndefined(self.$items[pos])) { - Ox.print("pos/item", pos, self.$items[pos]) self.$items[pos].addClass("OxSelected"); } Ox.Event.trigger("select_" + self.options.id, { - items: self.selected.length + ids: $.map(self.selected, function(v, i) { + return self.ids[v]; + }) }); } } + function clear() { + $.each(self.requests, function(i, v) { + Ox.Request.cancel(v); + }); + $.extend(self, { + $items: [], + $pages: [], + page: 0, + requests: [] + }); + } + function click(e) { var $element = $(e.target), pos; that.gainFocus(); @@ -2525,13 +2525,15 @@ requires self.$items[pos].removeClass("OxSelected"); } Ox.Event.trigger("select_" + self.options.id, { - items: self.selected.length + ids: $.map(self.selected, function(v, i) { + return self.ids[v]; + }) }); } } function getHeight() { - return that.height() - (that.$content.width() > that.width() ? 12 : 0); + return that.height() - (that.$content.width() > that.width() ? oxui.scrollbarSize : 0); } function getNext() { @@ -2551,6 +2553,39 @@ requires : Math.floor(that.scrollLeft() / self.pageWidth); } + function getPositions() { + Ox.print("getPositions", $.map(self.selected, function(v, i) { + return self.ids[v]; + })); + // fixme: optimize: send non-selected ids if more than half of the items are selected + if (self.selected.length /*&& self.selected.length < self.listLength*/) { + self.requests.push(self.options.request({ + callback: getPositionsCallback, + ids: $.map(self.selected, function(v, i) { + return self.ids[v]; + }), + sort: self.options.sort + })); + } else { + getPositionsCallback(); + } + } + + function getPositionsCallback(result) { + Ox.print("getPositionsCallback", result) + if (result) { + $.extend(self, { + ids: {}, + selected: [] + }); + $.each(result.data.positions, function(id, pos) { + Ox.print("id", id, "pos", pos) + self.selected.push(pos); + }); + } + load(); + } + function getPrevious() { var pos = -1; if (self.selected.length) { @@ -2560,7 +2595,7 @@ requires } function getWidth() { - return that.width() - (that.$content.height() > that.height() ? 12 : 0); + return that.width() - (that.$content.height() > that.height() ? oxui.scrollbarSize : 0); } function invertSelection() { @@ -2573,9 +2608,16 @@ requires return self.selected.indexOf(pos) > -1; } + function load() { + that.scrollTop(0); + that.$content.empty(); + loadPages(self.page); + } + function loadPage(page, callback) { Ox.print("loadPage", page) - if (page < 0 || page >= self.pages) { // fixme: callback doesn't get called + if (page < 0 || page >= self.pages) { + !Ox.isUndefined(callback) && callback(); return; } var keys = $.inArray("id", self.options.keys) > -1 ? self.options.keys : @@ -2598,22 +2640,20 @@ requires } $.each(result.data.items, function(i, v) { var pos = offset + i; - if (Ox.isUndefined(v.id)) { - v.id = pos; - } self.$items[pos] = new Ox.ListItem({ construct: self.options.construct, data: v, + id: v[self.options.unique], position: pos }); - self.ids[pos] = v.id; + self.ids[pos] = v[self.options.unique]; if (isSelected(pos)) { self.$items[pos].addClass("OxSelected"); } self.$items[pos].appendTo(self.$pages[page]); }); self.$pages[page].appendTo(that.$content); - callback(); + !Ox.isUndefined(callback) && callback(); }, keys: keys, range: range, @@ -2697,7 +2737,7 @@ requires } function scrollToLast() { - + that.scrollTop(self.listHeight); } function select(pos) { @@ -2770,56 +2810,44 @@ requires unloadPage(page + 1) } - that.clearCache = function() { - self.$pages = []; + function updateQuery() { + clear(); + self.requests.push(self.options.request({ + callback: function(result) { + var keys = {}; + Ox.print("items", result.data.items); + $.extend(self, { + listHeight: result.data.items * self.options.itemHeight, // fixme: should be listSize + listLength: result.data.items, + pages: Math.ceil(result.data.items / self.pageLength), + 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 + }); + that.$content.css({ + height: self.listHeight + "px" + }); + getPositions(); + } + })); + } + + function updateSort() { + clear(); + getPositions(); + } + + self.onChange = function(key, value) { + Ox.print("list onChange", key, value); + if (key == "request") { + updateQuery(); + } }; - that.reload = function() { - - $.each(self.requests, function(i, v) { - Ox.Request.cancel(v); - }); - $.extend(self, { - $items: [], - $pages: [], - page: 0, - requests: [] - }); - - // fixme: optimize: send non-selected ids if more than half of the items are selected - Ox.print(self.selected.length, self.listLength); - if (self.selected.length && self.selected.length < self.listLength) { - Ox.print("sort", self.options.sort, "ids", $.map(self.selected, function(v, i) { - return self.ids[v]; - })); - self.requests.push(self.options.request({ - callback: callback, - ids: $.map(self.selected, function(v, i) { - return self.ids[v]; - }), - sort: self.options.sort - })); - } else { - callback(); - } - - function callback(result) { - if (result) { - $.extend(self, { - ids: {}, - selected: [] - }); - $.each(result.data.positions, function(id, pos) { - Ox.print("id", id, "pos", pos) - self.selected.push(pos); - }); - } - that.$content.empty(); - that.scrollTop(0); - loadPages(self.page); - } - - } + that.clearCache = function() { // fixme: unused? make private? + self.$pages = []; + }; that.sort = function(key, operator) { if (key != self.options.sort[0].key || operator != self.options.sort[0].operator) { @@ -2828,7 +2856,7 @@ requires operator: operator } // fixme: trigger sort event here - that.reload(); + updateSort(); } } @@ -2843,6 +2871,7 @@ requires .defaults({ construct: function() {}, data: {}, + id: "", position: 0 }) .options(options || {}); @@ -2853,7 +2882,7 @@ requires that.$element = self.options.construct(self.options.data) .attr({ - id: self.options.data.id + id: self.options.id }) .data("position", self.options.position); @@ -2882,6 +2911,18 @@ requires .options(options || {}) .addClass("OxTextList"); + $.each(self.options.columns, function(i, v) { // fixme: can this go into a generic ox.js function? + 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, { columnWidths: [], itemHeight: 16, @@ -2984,7 +3025,8 @@ requires orientation: "vertical", request: self.options.request, sort: self.options.sort, - type: "text" + type: "text", + unique: self.unique }) .addClass("OxBody") .scroll(function() { @@ -3017,7 +3059,7 @@ requires var $item = $("