You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by hn...@apache.org on 2020/03/04 13:08:45 UTC
[myfaces-tobago] branch tobago-4.x updated: TOBAGO-2021: Sheet
should be able to lazy load rows by scroll events (#28)
This is an automated email from the ASF dual-hosted git repository.
hnoeth pushed a commit to branch tobago-4.x
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git
The following commit(s) were added to refs/heads/tobago-4.x by this push:
new 96e8d95 TOBAGO-2021: Sheet should be able to lazy load rows by scroll events (#28)
96e8d95 is described below
commit 96e8d95d02370ddb6c892ab5d9e2d9486a195b35
Author: Udo Schnurpfeil <lo...@apache.org>
AuthorDate: Wed Mar 4 14:08:37 2020 +0100
TOBAGO-2021: Sheet should be able to lazy load rows by scroll events (#28)
TOBAGO-2021: Sheet should be able to lazy load rows by scroll events
---
.../myfaces/tobago/component/Attributes.java | 1 +
.../apache/myfaces/tobago/event/SheetAction.java | 7 +-
.../tobago/internal/component/AbstractUISheet.java | 18 ++
.../internal/renderkit/renderer/SheetRenderer.java | 16 +-
.../taglib/component/SheetTagDeclaration.java | 8 +
.../tobago/renderkit/html/DataAttributes.java | 20 +-
.../tobago/example/demo/SheetController.java | 9 +-
.../apache/myfaces/tobago/example/demo/Demo.xml | 1 +
.../080-sheet/90-lazy/sheet_lazy.xhtml} | 6 +-
.../tobago-bootstrap/_version/js/tobago-sheet.js | 270 ++++++++++++++++-----
10 files changed, 289 insertions(+), 67 deletions(-)
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
index dddc245..65e2723 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
@@ -145,6 +145,7 @@ public enum Attributes {
labelWidth,
large,
layoutOrder,
+ lazy,
left,
level,
lang,
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/event/SheetAction.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/event/SheetAction.java
index 277ab29..5580176 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/event/SheetAction.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/event/SheetAction.java
@@ -56,7 +56,12 @@ public enum SheetAction {
/**
* Sorting
*/
- sort;
+ sort,
+
+ /**
+ * A lazy load is requested
+ */
+ lazy;
private String bundleKey;
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
index 52c1601..83cdfbb 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
@@ -91,6 +91,21 @@ public abstract class AbstractUISheet extends AbstractUIData
@Override
public void encodeAll(FacesContext facesContext) throws IOException {
+ if (isLazy()) {
+ if (getRows() == 0) {
+ LOG.warn("Sheet id={} has lazy=true set, but not set the rows attribute!", getClientId(facesContext));
+ }
+ if (getShowRowRange() != ShowPosition.none) {
+ LOG.warn("Sheet id={} has lazy=true set, but also set showRowRange!=none!", getClientId(facesContext));
+ }
+ if (getShowPageRange() != ShowPosition.none) {
+ LOG.warn("Sheet id={} has lazy=true set, but also set showPageRange!=none!", getClientId(facesContext));
+ }
+ if (getShowDirectLinks() != ShowPosition.none) {
+ LOG.warn("Sheet id={} has lazy=true set, but also set showDirectLinks!=none!", getClientId(facesContext));
+ }
+ }
+
final AbstractUIReload reload = ComponentUtils.getReloadFacet(this);
if (reload != null && AjaxUtils.isAjaxRequest(facesContext) && reload.isRendered() && !reload.isUpdate()) {
@@ -544,6 +559,7 @@ public abstract class AbstractUISheet extends AbstractUIData
first = getFirstRowIndexOfLastPage();
break;
case toRow:
+ case lazy:
first = pageEvent.getValue() - 1;
if (hasRowCount() && first > getFirstRowIndexOfLastPage()) {
first = getFirstRowIndexOfLastPage();
@@ -609,4 +625,6 @@ public abstract class AbstractUISheet extends AbstractUIData
public abstract ShowPosition getShowPageRange();
public abstract ShowPosition getShowDirectLinks();
+
+ public abstract boolean isLazy();
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
index 9133706..0f20820 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
@@ -73,6 +73,7 @@ import org.slf4j.LoggerFactory;
import javax.el.ValueExpression;
import javax.faces.application.Application;
+import javax.faces.component.NamingContainer;
import javax.faces.component.UIColumn;
import javax.faces.component.UIComponent;
import javax.faces.component.UIData;
@@ -98,6 +99,7 @@ public class SheetRenderer extends RendererBase {
private static final String SUFFIX_COLUMN_RENDERED = ComponentUtils.SUB_SEPARATOR + "rendered";
private static final String SUFFIX_SCROLL_POSITION = ComponentUtils.SUB_SEPARATOR + "scrollPosition";
private static final String SUFFIX_SELECTED = ComponentUtils.SUB_SEPARATOR + "selected";
+ private static final String SUFFIX_LAZY = NamingContainer.SEPARATOR_CHAR + "pageActionlazy";
private static final String SUFFIX_PAGE_ACTION = "pageAction";
@Override
@@ -195,6 +197,7 @@ public class SheetRenderer extends RendererBase {
break;
case toPage:
case toRow:
+ case lazy:
event = new PageActionEvent(component, action);
final Integer target;
final Object value;
@@ -280,6 +283,9 @@ public class SheetRenderer extends RendererBase {
writer.writeAttribute(DataAttributes.BEHAVIOR_COMMANDS, JsonUtils.encode(commands), false);
writer.writeAttribute(DataAttributes.SELECTION_MODE, sheet.getSelectable().name(), false);
writer.writeAttribute(DataAttributes.FIRST, Integer.toString(sheet.getFirst()), false);
+ writer.writeAttribute(DataAttributes.ROWS, Integer.toString(sheet.getRows()), false);
+ writer.writeAttribute(DataAttributes.ROW_COUNT, Integer.toString(sheet.getRowCount()), false);
+ writer.writeAttribute(DataAttributes.LAZY, sheet.isLazy());
final StringBuilder builder = new StringBuilder();
final boolean autoLayout = sheet.isAutoLayout();
@@ -346,6 +352,10 @@ public class SheetRenderer extends RendererBase {
sheetId + SUFFIX_SELECTED);
}
+ if (sheet.isLazy()) {
+ encodeHiddenInput(writer,null, sheetId + SUFFIX_LAZY);
+ }
+
StringBuilder expandedValue = null;
if (sheet.isTreeModel()) {
expandedValue = new StringBuilder(",");
@@ -661,11 +671,7 @@ public class SheetRenderer extends RendererBase {
}
writer.startElement(HtmlElements.TR);
- if (rowRendered instanceof Boolean) {
- // if rowRendered attribute is set we need the rowIndex on the client
- writer.writeAttribute(DataAttributes.ROW_INDEX, rowIndex);
- }
-
+ writer.writeAttribute(DataAttributes.ROW_INDEX, rowIndex);
final boolean selected = selectedRows.contains(rowIndex);
final String[] rowMarkups = (String[]) sheet.getAttributes().get("rowMarkup");
Markup rowMarkup = Markup.NULL;
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
index d845e5b..ec0086a 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
@@ -24,6 +24,7 @@ import org.apache.myfaces.tobago.apt.annotation.BodyContentDescription;
import org.apache.myfaces.tobago.apt.annotation.DynamicExpression;
import org.apache.myfaces.tobago.apt.annotation.Facet;
import org.apache.myfaces.tobago.apt.annotation.Markup;
+import org.apache.myfaces.tobago.apt.annotation.Preliminary;
import org.apache.myfaces.tobago.apt.annotation.Tag;
import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
@@ -260,6 +261,13 @@ public interface SheetTagDeclaration
methodSignature = "javax.faces.event.ActionEvent")
void setSortActionListener(String sortActionListener);
+ /**
+ * Preliminary feature: lazy loading by scrolling.
+ */
+ @Preliminary
+ @TagAttribute
+ @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
+ void setLazy(String lazy);
/**
* Flag indicating if paging arrows are shown near direct links
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
index 7825257..fb70fd3 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
@@ -101,6 +101,12 @@ public enum DataAttributes implements MarkupLanguageAttributes {
LAYOUT("data-tobago-layout"),
/**
+ * Lazy loading in sheet.
+ * (Preliminary)
+ */
+ LAZY("data-tobago-lazy"),
+
+ /**
* Defines the depth level of a tree node.
*/
LEVEL("data-tobago-level"),
@@ -147,10 +153,22 @@ public enum DataAttributes implements MarkupLanguageAttributes {
ROW_ACTION("data-tobago-row-action"),
/*
- * Holds the index of the row in a sheet, if the sheet has a rowRendered attribute.
+ * Holds the index of the row in a sheet.
*/
ROW_INDEX("data-tobago-row-index"),
+ /**
+ * Number of rows to show/load for lazy loading in sheet.
+ * (Preliminary)
+ */
+ ROWS("data-tobago-rows"),
+
+ /**
+ * Number of all rows in sheet.
+ * (Preliminary)
+ */
+ ROW_COUNT("data-tobago-row-count"),
+
SELECTION_MODE("data-tobago-selection-mode"),
/**
diff --git a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java
index 5bff77c..ce3968b8 100644
--- a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java
+++ b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java
@@ -82,12 +82,17 @@ public class SheetController implements Serializable {
private void init() {
solarList = astroData.findAll().collect(Collectors.toList());
+ int j = 1;
hugeSolarList = new ArrayList<>();
- for (int i = 1; i <= 12; i++) {
+ for (int i = 1;; i++) {
for (final SolarObject solarObject : solarList) {
final SolarObject solarObjectClone = new SolarObject(solarObject);
- solarObjectClone.setName(solarObject.getName() + " (" + i + ". entry)");
hugeSolarList.add(solarObjectClone);
+ solarObjectClone.setName("#" + j++ + " " + solarObject.getName());
+
+ if (j > 10000) {
+ return;
+ }
}
}
}
diff --git a/tobago-example/tobago-example-demo/src/main/resources/org/apache/myfaces/tobago/example/demo/Demo.xml b/tobago-example/tobago-example-demo/src/main/resources/org/apache/myfaces/tobago/example/demo/Demo.xml
index 1190e1f..7441472 100644
--- a/tobago-example/tobago-example-demo/src/main/resources/org/apache/myfaces/tobago/example/demo/Demo.xml
+++ b/tobago-example/tobago-example-demo/src/main/resources/org/apache/myfaces/tobago/example/demo/Demo.xml
@@ -121,6 +121,7 @@
<entry key="sheet_multi_header">Multi Header</entry>
<entry key="sheet_tree">Column Tree</entry>
<entry key="sheet_editable">Editable Sheet</entry>
+ <entry key="sheet_lazy">Lazy Loading</entry>
<entry key="tree">Tree Control</entry>
<entry key="tree_command_types">Command</entry>
<entry key="tree_select">Select</entry>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/3000-sheet/20-1000-entries/1000-entries.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/90-lazy/sheet_lazy.xhtml
similarity index 88%
rename from tobago-example/tobago-example-demo/src/main/webapp/content/40-test/3000-sheet/20-1000-entries/1000-entries.xhtml
rename to tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/90-lazy/sheet_lazy.xhtml
index 185ee4a..f9232fc 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/3000-sheet/20-1000-entries/1000-entries.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/90-lazy/sheet_lazy.xhtml
@@ -21,9 +21,11 @@
xmlns="http://www.w3.org/1999/xhtml"
xmlns:tc="http://myfaces.apache.org/tobago/component"
xmlns:ui="http://java.sun.com/jsf/facelets">
- <ui:param name="title" value="#{demoBundle.sheet_types}"/>
+ <ui:param name="title" value="Lazy Loading Large Data"/>
<tc:sheet value="#{sheetController.hugeSolarList}" id="sheet" var="luminary"
- rows="10" markup="small" >
+ rows="100" markup="small" lazy="true"
+ showRowRange="none" showDirectLinks="none" showPageRange="none">
+ <tc:style maxHeight="500px"/>
<tc:column label="Name">
<tc:out value="#{luminary.name}" labelLayout="skip"/>
</tc:column>
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/resources/tobago/standard/tobago-bootstrap/_version/js/tobago-sheet.js b/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/resources/tobago/standard/tobago-bootstrap/_version/js/tobago-sheet.js
index 5fe4529..1c73169 100644
--- a/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/resources/tobago/standard/tobago-bootstrap/_version/js/tobago-sheet.js
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/resources/tobago/standard/tobago-bootstrap/_version/js/tobago-sheet.js
@@ -51,6 +51,9 @@ Tobago.Sheet.init = function(elements) {
sheets.each(function initSheets() {
var sheet = jQuery(this);
var id = sheet.attr("id");
+ if (sheet.data("tobago-lazy-initialized")) {
+ return;
+ }
var commands = sheet.data("tobago-row-action");
var click = commands ? commands.click : undefined;
var dblclick = commands ? commands.dblclick : undefined;
@@ -90,24 +93,89 @@ Tobago.Sheet.prototype.reloadWithAction = function(source, action) {
console.debug("reload sheet with action '" + action + "'"); // @DEV_ONLY
var executeIds = this.id;
var renderIds = this.id;
-// if (this.behaviorCommands && this.behaviorCommands.reload) {
-// if (this.behaviorCommands.reload.execute) {
-// executeIds += " " + behaviorCommands.reload.execute;
-// }
-// if (this.behaviorCommands.reload.render) {
-// renderIds += " " + this.behaviorCommands.reload.render;
-// }
-// }
+ var lazy = jQuery(Tobago.Utils.escapeClientId(this.id)).data("tobago-lazy");
+
jsf.ajax.request(
action,
null,
{
"javax.faces.behavior.event": "reload",
execute: executeIds,
- render: renderIds
+ render: renderIds,
+ onevent: lazy ? Tobago.Sheet.lazyResponse : undefined,
+ onerror: lazy ? Tobago.Sheet.lazyError: undefined
});
};
+Tobago.Sheet.lazyResponse = function(event) {
+ if (event.status === "complete") {
+ var updates = event.responseXML.querySelectorAll("update");
+ for (var i = 0; i < updates.length; i++) {
+ var update = updates[i];
+ var id = update.getAttribute("id");
+ if (id.indexOf(":") > -1) { // is a JSF element id, but not a technical id from the framework
+ console.debug("[tobago-sheet][complete] Update after jsf.ajax complete: #" + id); // @DEV_ONLY
+
+ var sheet = document.getElementById(id);
+ sheet.id = id + "::lazy-temporary";
+
+ var page = Tobago.findPage();
+ page.get(0).insertAdjacentHTML("beforeend", "<div id='" + id + "'></div>");
+ var sheetLoader = document.getElementById(id);
+ }
+ }
+ } else if (event.status === "success") {
+ updates = event.responseXML.querySelectorAll("update");
+ for (i = 0; i < updates.length; i++) {
+ update = updates[i];
+ id = update.getAttribute("id");
+ if (id.indexOf(":") > -1) { // is a JSF element id, but not a technical id from the framework
+ console.debug("[tobago-sheet][success] Update after jsf.ajax complete: #" + id); // @DEV_ONLY
+
+ // sync the new rows into the sheet
+ sheetLoader = document.getElementById(id);
+ sheet = document.getElementById(id + "::lazy-temporary");
+ sheet.id = id;
+ var tbody = sheet.querySelector(".tobago-sheet-bodyTable > tbody");
+
+ var newRows = sheetLoader.querySelectorAll(".tobago-sheet-bodyTable > tbody > tr");
+ for (i = 0; i < newRows.length; i++) {
+ var newRow = newRows[i];
+ var rowIndex = Number(newRow.dataset.tobagoRowIndex);
+ var row = tbody.querySelector("tr[data-tobago-row-index='" + rowIndex + "']");
+ // replace the old row with the new row
+ row.insertAdjacentElement("afterend", newRow);
+ tbody.removeChild(row);
+ }
+
+ sheetLoader.parentElement.removeChild(sheetLoader);
+ jQuery(sheet).data("tobago-lazy-active", false);
+ }
+ }
+ }
+
+};
+
+Tobago.Sheet.lazyError = function(data) {
+ updates = event.responseXML.querySelectorAll("update");
+ for (i = 0; i < updates.length; i++) {
+ update = updates[i];
+ id = update.getAttribute("id");
+ if (id.indexOf(":") > -1) { // is a JSF element id, but not a technical id from the framework
+ var sheet = document.getElementById(id);
+ jQuery(sheet).data("tobago-lazy-active", false);
+ console.error("Sheet lazy loading error:"
+ + "\nError Description: " + data.description
+ + "\nError Name: " + data.errorName
+ + "\nError errorMessage: " + data.errorMessage
+ + "\nResponse Code: " + data.responseCode
+ + "\nResponse Text: " + data.responseText
+ + "\nStatus: " + data.status
+ + "\nType: " + data.type);
+ }
+ }
+};
+
Tobago.Sheet.setup2 = function (sheets) {
// synchronize column widths
@@ -426,7 +494,65 @@ Tobago.Sheet.setup2 = function (sheets) {
sheet.find(".tobago-sheet-cell > input.tobago-sheet-columnSelector").click(function(event) {event.preventDefault()});
});
- // init reload
+ // lazy load by scrolling
+ jQuery(sheets).each(function () {
+ var $sheet = jQuery(this);
+ var lazy = $sheet.data("tobago-lazy");
+
+ function getTemplate(height, columns, rowIndex) {
+ var tr = document.createElement("tr");
+ tr.dataset.tobagoRowIndex = rowIndex;
+ tr.classList.add("tobago-sheet-row");
+ tr.setAttribute("dummy", "dummy");
+ tr.style.height = height + "px";
+ var td = document.createElement("td");
+ td.classList.add("tobago-sheet-cell");
+ td.colSpan = columns;
+ tr.appendChild(td);
+ return tr;
+ }
+
+ if (lazy) {
+ // prepare the sheet with some auto-created (empty) rows
+ var rows = $sheet.data("tobago-rows");
+ var rowCount = $sheet.data("tobago-row-count");
+ var $sheetBody = $sheet.find(".tobago-sheet-body");
+ var $tbody = $sheetBody.find("tbody");
+ var columns = $tbody.find("tr:first").find("td").length;
+ var height = $tbody.height() / rows;
+ var pointer = $tbody.get(0).rows[0]; // points current row
+ for (var i = 0; i < rowCount; i++) {
+ if (pointer) {
+ var rowIndex = Number(pointer.dataset.tobagoRowIndex);
+ if (i < rowIndex) {
+ var template = getTemplate(height, columns, i);
+ pointer.insertAdjacentElement("beforebegin", template);
+ } else if (i === rowIndex) {
+ pointer = pointer.nextElementSibling;
+ } else {
+ template = getTemplate(height, columns, i);
+ pointer.insertAdjacentElement("afterend", template);
+ pointer = template;
+ }
+ } else {
+ template = getTemplate(height, columns, i);
+ $tbody.get(0).insertAdjacentElement("beforeend", template);
+ pointer = template;
+ }
+ }
+
+ $sheetBody.bind("scroll", function () {
+ Tobago.Sheet.lazyCheck($sheet);
+ });
+
+ // initial
+ Tobago.Sheet.lazyCheck($sheet);
+
+ $sheet.data("tobago-lazy-initialized", true);
+ }
+ });
+
+ // init reload
jQuery(sheets).filter("[data-tobago-reload]").each(function() {
var sheet = jQuery(this);
Tobago.Sheets.get(sheet.attr("id")).initReload();
@@ -453,6 +579,82 @@ Tobago.Sheet.setup2 = function (sheets) {
});
};
+/*
+ when an event occurs (initial load OR scroll event OR AJAX response)
+
+ then -> Tobago.Sheet.lazyCheck()
+ 1. check, if the lazy reload is currently active
+ a) yes -> do nothing and exit
+ b) no -> step 2.
+ 2. check, if there are data need to load (depends on scroll position and already loaded data)
+ a) yes -> set lazy reload to active and make an AJAX request with Tobago.Sheet.reloadLazy()
+ b) no -> do nothing and exit
+
+ AJAX response -> 1. update the rows in the sheet from the response
+ 2. go to the first part of this description
+*/
+
+Tobago.Sheet.lazyCheck = function($sheet) {
+ if ($sheet.data("tobago-lazy-active")) {
+ // nothing to do, because there is an active AJAX running
+ return;
+ }
+
+ var lastCheck = $sheet.data("tobago-lazy-last-check");
+ if (lastCheck && Date.now() - lastCheck < 100) {
+ // do nothing, because the last call was just a moment ago
+ return;
+ }
+
+ $sheet.data("tobago-lazy-last-check", Date.now());
+ var next = Tobago.Sheet.nextLazyLoad($sheet);
+ // console.info("next %o", next); // @DEV_ONLY
+ if (next) {
+ $sheet.data("tobago-lazy-active", true);
+ var id = $sheet.attr("id");
+ var input = document.getElementById(id + ":pageActionlazy");
+ input.value = next;
+ Tobago.Sheets.get(id).reloadWithAction(input, input.id);
+ }
+};
+
+Tobago.Sheet.nextLazyLoad = function($sheet) {
+ // find first tr in current visible area
+ var $sheetBody = $sheet.find(".tobago-sheet-body");
+ var rows = $sheet.data("tobago-rows");
+ var $tbody = $sheetBody.find("table tbody");
+ var min = 0;
+ var trElements = $tbody.prop("rows");
+ var max = trElements.length;
+ // binary search
+ while (min < max) {
+ var i = Math.floor((max - min) / 2) + min;
+ // console.log("min i max -> %d %d %d", min, i, max); // @DEV_ONLY
+ if (Tobago.Sheet.isRowAboveVisibleArea($sheetBody, trElements[i])) {
+ min = i + 1;
+ } else {
+ max = i;
+ }
+ }
+ for (i = min; i < min + rows && i < trElements.length; i++) {
+ if (Tobago.Sheet.isRowDummy($sheetBody, trElements[i])) {
+ return i + 1;
+ }
+ }
+
+ return null;
+};
+
+Tobago.Sheet.isRowAboveVisibleArea = function($sheetBody, tr) {
+ var viewStart = $sheetBody.prop("scrollTop");
+ var trEnd = tr.offsetTop + tr.clientHeight;
+ return trEnd < viewStart;
+};
+
+Tobago.Sheet.isRowDummy = function($sheetBody, tr) {
+ return tr.hasAttribute("dummy");
+};
+
Tobago.Sheet.hideInputOrSubmit = function(input) {
var output = input.siblings(".tobago-sheet-pagingOutput");
var changed = output.html() !== input.val();
@@ -574,11 +776,7 @@ Tobago.Sheet.getRows = function($sheet) {
};
Tobago.Sheet.isRowSelected = function(sheet, row) {
- var rowIndex = +row.data("tobago-row-index");
- if (!rowIndex) {
- rowIndex = row.index() + sheet.data("tobago-first");
- }
- return Tobago.Sheet.isSelected(sheet, rowIndex);
+ return Tobago.Sheet.isSelected(sheet, row.data("tobago-row-index"));
};
Tobago.Sheet.isSelected = function(sheet, rowIndex) {
@@ -638,12 +836,7 @@ Tobago.Sheet.selectRange = function($sheet, $rows, first, last, selectDeselected
};
Tobago.Sheet.getDataIndex = function(sheet, row) {
- var rowIndex = row.data("tobago-row-index");
- if (rowIndex) {
- return +rowIndex;
- } else {
- return row.index() + sheet.data("tobago-first");
- }
+ return row.data("tobago-row-index");
};
/**
@@ -685,38 +878,3 @@ Tobago.Sheet.isInputElement = function($element) {
});
};
})(jQuery);
-
-/*
- var header = $(".tobago-sheet-headerTable");
- var body = $(".tobago-sheet-bodyTable");
-
- header;
- body;
-
- header.find("col").each(function(){
-
- console.info($(this).attr("width"));
- $(this).attr("width", 100);
- ;
- })
-
- header.find("col").each(function(){
-
- console.info($(this).attr("width"));
- ;
- })
-
-
- body.find("col").each(function(){
-
- console.info($(this).attr("width"));
- $(this).attr("width", 100);
- ;
- })
-
- body.find("col").each(function(){
-
- console.info($(this).attr("width"));
- ;
- })
- */