package com.sksamuel.jqm4gwt.plugins.datatables;
import java.util.List;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayInteger;
import com.google.gwt.core.client.JsArrayMixed;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.dom.client.Element;
import com.sksamuel.jqm4gwt.Empty;
import com.sksamuel.jqm4gwt.StrUtils;
import com.sksamuel.jqm4gwt.table.ColumnDef;
public class JsDataTable {
private JsDataTable() {} // static class
static {
defineChangeRowsFunc();
}
static class JsSortItem extends JsArrayMixed {
protected JsSortItem() {}
public static native JsSortItem create(int col, String jsSortDir) /*-{
return [col, jsSortDir];
}-*/;
public final int getCol() {
return (int) getNumber(0);
}
public final void setCol(int value) {
set(0, value);
}
public final String getJsSortDir() {
return getString(1);
}
public final void setJsSortDir(String value) {
set(1, value);
}
}
static class JsSortItems extends JsArray<JsSortItem> {
protected JsSortItems() {}
/** @param item - if null returns empty array */
public static native JsSortItems create(JsSortItem item) /*-{
if(item) return [item];
else return [];
}-*/;
}
static native void setOrder(Element elt, JsSortItems sorts) /*-{
var t = $wnd.$(elt).DataTable();
if (sorts) t.order(sorts).draw();
else t.order.neutral().draw(); // http://datatables.net/plug-ins/api/order.neutral()
}-*/;
static native JsSortItems getOrder(Element elt) /*-{
return $wnd.$(elt).DataTable().order();
}-*/;
static class JsColumn extends JavaScriptObject {
protected JsColumn() {}
public static native JsColumn create() /*-{
return {};
}-*/;
public final native String getName() /*-{
return this.name;
}-*/;
public final native void setName(String value) /*-{
this.name = value;
}-*/;
public final native boolean isVisible() /*-{
return this.visible;
}-*/;
public final native void setVisible(boolean value) /*-{
this.visible = value;
}-*/;
public final native boolean isOrderable() /*-{
return this.orderable;
}-*/;
public final native void setOrderable(boolean value) /*-{
this.orderable = value;
}-*/;
public final native boolean isSearchable() /*-{
return this.searchable;
}-*/;
public final native void setSearchable(boolean value) /*-{
this.searchable = value;
}-*/;
public final native String getClassName() /*-{
return this.className;
}-*/;
public final native void setClassName(String value) /*-{
this.className = value;
}-*/;
public final native String getCellType() /*-{
return this.cellType;
}-*/;
public final native void setCellType(String value) /*-{
this.cellType = value;
}-*/;
public final native String getDefaultContent() /*-{
return this.defaultContent;
}-*/;
public final native void setDefaultContent(String value) /*-{
this.defaultContent = value;
}-*/;
public final native String getWidth() /*-{
return this.width;
}-*/;
public final native void setWidth(String value) /*-{
this.width = value;
}-*/;
public final native String getData() /*-{
if (this.data === null) return null;
else if (typeof this.data === 'string') return this.data;
else if (typeof this.data === 'function') return null;
else return '' + this.data;
}-*/;
public final native void setData(String value) /*-{
this.data = value;
}-*/;
public final native int getDataIdx() /*-{
if (typeof this.data === 'number') return this.data;
else return -1;
}-*/;
public final native void setDataIdx(int value) /*-{
this.data = value;
}-*/;
public final native void setDataFunc(final Element tableElt, final RowData rowData) /*-{
this.data = function ( row, type, val, meta ) {
var opType = type ? type : null;
var setVal = val ? val : null;
var rslt = rowData.@com.sksamuel.jqm4gwt.plugins.datatables.JsDataTable.RowData::onData(
Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;Lcom/google/gwt/core/client/JavaScriptObject;)
(tableElt, row, opType, setVal, meta);
return rslt[0];
};
}-*/;
public final native void setRenderFunc(final Element tableElt, final ColumnDef column,
final CellRender render) /*-{
this.render = function ( data, type, row, meta ) {
var cellData = [data];
var rslt = render.@com.sksamuel.jqm4gwt.plugins.datatables.JsDataTable.CellRender::onRender(
Lcom/google/gwt/dom/client/Element;Lcom/sksamuel/jqm4gwt/table/ColumnDef;Lcom/google/gwt/core/client/JsArrayMixed;Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;)
(tableElt, column, cellData, row, type, meta);
if (rslt) return rslt;
else return data;
};
}-*/;
}
public static interface CellRender {
/**
* See <a href="https://datatables.net/reference/option/columns.render">Description of function render()</a>
*
* @param cellData - the data for the cell, always array of length 1.
* @param rowData - the data for the whole row, usually JsArray or JavaScriptObject.
* @param opType - possible values: "display", "filter", "sort", "type".
* @param metaInfo - an object that contains additional information about the cell being requested.
* @return - valid html for the cell, for example: <a href="...">Download</a>
* <br> In case you return null, then default cell rendering will be used.
*/
String onRender(Element tableElt, ColumnDef col, JsArrayMixed cellData,
JavaScriptObject rowData, String opType,
JavaScriptObject/*JsRowDataMetaInfo*/ metaInfo);
}
static class JsColumns extends JsArray<JsColumn> {
protected JsColumns() {}
/** @param item - if null returns empty array */
public static native JsColumns create(JsColumn item) /*-{
if(item) return [item];
else return [];
}-*/;
}
/** See <a href="https://datatables.net/reference/option/#Internationalisation">Internationalisation</a> */
static class JsLanguage extends JavaScriptObject implements Language {
protected JsLanguage() {}
public static native JsLanguage create() /*-{
return {};
}-*/;
public static native JsLanguage create(String languageJSON) /*-{
var l = JSON.parse(languageJSON);
return l;
}-*/;
@Override
public final native String getDecimal() /*-{
return this.decimal;
}-*/;
@Override
public final native void setDecimal(String value) /*-{
this.decimal = value;
}-*/;
@Override
public final native String getThousands() /*-{
return this.thousands;
}-*/;
@Override
public final native void setThousands(String value) /*-{
this.thousands = value;
}-*/;
@Override
public final native String getLengthMenu() /*-{
return this.lengthMenu;
}-*/;
@Override
public final native void setLengthMenu(String value) /*-{
this.lengthMenu = value;
}-*/;
@Override
public final native String getEmptyTable() /*-{
return this.emptyTable;
}-*/;
@Override
public final native void setEmptyTable(String value) /*-{
this.emptyTable = value;
}-*/;
@Override
public final native String getZeroRecords() /*-{
return this.zeroRecords;
}-*/;
@Override
public final native void setZeroRecords(String value) /*-{
this.zeroRecords = value;
}-*/;
@Override
public final native String getInfo() /*-{
return this.info;
}-*/;
@Override
public final native void setInfo(String value) /*-{
this.info = value;
}-*/;
@Override
public final native String getInfoEmpty() /*-{
return this.infoEmpty;
}-*/;
@Override
public final native void setInfoEmpty(String value) /*-{
this.infoEmpty = value;
}-*/;
@Override
public final native String getInfoFiltered() /*-{
return this.infoFiltered;
}-*/;
@Override
public final native void setInfoFiltered(String value) /*-{
this.infoFiltered = value;
}-*/;
@Override
public final native String getLoadingRecords() /*-{
return this.loadingRecords;
}-*/;
@Override
public final native void setLoadingRecords(String value) /*-{
this.loadingRecords = value;
}-*/;
@Override
public final native String getProcessing() /*-{
return this.processing;
}-*/;
@Override
public final native void setProcessing(String value) /*-{
this.processing = value;
}-*/;
@Override
public final native String getSearch() /*-{
return this.search;
}-*/;
@Override
public final native void setSearch(String value) /*-{
this.search = value;
}-*/;
@Override
public final native String getSearchPlaceholder() /*-{
return this.searchPlaceholder;
}-*/;
@Override
public final native void setSearchPlaceholder(String value) /*-{
this.searchPlaceholder = value;
}-*/;
@Override
public final native String getUrl() /*-{
return this.url;
}-*/;
@Override
public final native void setUrl(String value) /*-{
this.url = value;
}-*/;
@Override
public final String getPaginate() {
return getPaginateStr();
}
@Override
public final void setPaginate(String value) {
setPaginateStr(value);
if (!Empty.is(value)) {
List<String> lst = StrUtils.commaSplit(value);
String[] arr = new String[] { null, null, null, null };
if (lst != null) {
for (int i = 0; i < lst.size(); i++) {
if (i >= arr.length) break;
arr[i] = StrUtils.replaceAllBackslashCommas(lst.get(i).trim());
}
}
nativeSetPaginate(arr[0], arr[1], arr[2], arr[3]);
} else {
nativeSetPaginate(null, null, null, null);
}
}
private final native String getPaginateStr() /*-{
return this.paginateStr;
}-*/;
private final native void setPaginateStr(String value) /*-{
this.paginateStr = value;
}-*/;
private final native void nativeSetPaginate(String sPrev, String sNext,
String sFirst, String sLast) /*-{
var empty = true;
var p = {};
if (sPrev) {
empty = false;
p.previous = sPrev;
}
if (sNext) {
empty = false;
p.next = sNext;
}
if (sFirst) {
empty = false;
p.first = sFirst;
}
if (sLast) {
empty = false;
p.last = sLast;
}
if (!empty) this.paginate = p;
}-*/;
}
/** See <a href="https://datatables.net/examples/server_side/pipeline.html">Pipelining data to reduce Ajax calls</a> */
public static interface AjaxHandler {
/**
* @param drawCallback - must be called back when data is ready with JsAjaxResponse as input parameter.
* @param request - actually it's JsAjaxRequest, so you can cast it safely.
**/
void getData(Element tableElt, JavaScriptObject/*JsAjaxRequest*/ request,
JavaScriptObject drawCallback);
}
/** See <a href="https://datatables.net/manual/server-side">Server-side processing</a> */
/* Example:
{ "draw": 987,
"columns": [
{"data":"code", "name":"col1", "searchable":true, "orderable":true, "search":{"value":"","regex":false}},
{"data":"name", "name":"col2", "searchable":true, "orderable":true, "search":{"value":"","regex":false}}
],
"order": [ {"column":0,"dir":"asc"} ],
"start": 0,
"length": 10,
"search": {"value":"","regex":false}
}
*/
public static class JsAjaxRequest extends JavaScriptObject {
protected JsAjaxRequest() {}
public static native JsAjaxRequest create() /*-{
return {};
}-*/;
public final native int getDraw() /*-{
if (this.draw) return this.draw;
else return 0;
}-*/;
public final native void setDraw(int value) /*-{
this.draw = value;
}-*/;
public final native int getStart() /*-{
return this.start;
}-*/;
public final native void setStart(int value) /*-{
this.start = value;
}-*/;
public final native int getLength() /*-{
return this.length;
}-*/;
public final native void setLength(int value) /*-{
this.length = value;
}-*/;
public final native String getSearchValue() /*-{
return this.search.value;
}-*/;
public final native void setSearchValue(String v) /*-{
this.search.value = v;
}-*/;
public final native boolean isSearchRegex() /*-{
return this.search.regex;
}-*/;
public final native void setSearchRegex(boolean value) /*-{
this.search.regex = value;
}-*/;
public final native JsOrderItems getOrder() /*-{
return this.order;
}-*/;
public final native void setOrder(JsOrderItems value) /*-{
this.order = value;
}-*/;
public final native JsColItems getColumns() /*-{
return this.columns;
}-*/;
public final native void setColumns(JsColItems value) /*-{
this.columns = value;
}-*/;
}
public static class JsOrderItem extends JavaScriptObject {
protected JsOrderItem() {}
public final native int getCol() /*-{
return this.column;
}-*/;
public final native String getDir() /*-{
return this.dir;
}-*/;
}
public static class JsOrderItems extends JsArray<JsOrderItem> {
protected JsOrderItems() {}
}
public static class JsColItem extends JavaScriptObject {
protected JsColItem() {}
public final native String getData() /*-{
if (this.data === null) return null;
else if (typeof this.data === 'string') return this.data;
else if (typeof this.data === 'function') return null;
else return '' + this.data;
}-*/;
public final native String getName() /*-{
return this.name;
}-*/;
public final native boolean isOrderable() /*-{
return this.orderable;
}-*/;
public final native boolean isSearchable() /*-{
return this.searchable;
}-*/;
public final native String getSearchValue() /*-{
return this.search.value;
}-*/;
public final native boolean isSearchRegex() /*-{
return this.search.regex;
}-*/;
}
public static class JsColItems extends JsArray<JsColItem> {
protected JsColItems() {}
}
/** See <a href="https://datatables.net/manual/server-side">Server-side processing</a> */
public static class JsAjaxResponse extends JavaScriptObject {
protected JsAjaxResponse() {}
public static native JsAjaxResponse create() /*-{
return {};
}-*/;
public final native int getDraw() /*-{
return this.draw;
}-*/;
public final native void setDraw(int value) /*-{
this.draw = value;
}-*/;
public final native int getRecordsTotal() /*-{
return this.recordsTotal;
}-*/;
public final native void setRecordsTotal(int value) /*-{
this.recordsTotal = value;
}-*/;
public final native int getRecordsFiltered() /*-{
return this.recordsFiltered;
}-*/;
public final native void setRecordsFiltered(int value) /*-{
this.recordsFiltered = value;
}-*/;
public final native JavaScriptObject getData() /*-{
return this.data;
}-*/;
/**
* @param value - usually it's JsArray<JsArrayMixed> or JsArray<JavaScriptObject>
*/
public final native void setData(JavaScriptObject value) /*-{
this.data = value;
}-*/;
public final native String getError() /*-{
return this.error;
}-*/;
public final native void setError(String value) /*-{
this.error = value;
}-*/;
}
public static class JsAjax extends JavaScriptObject {
protected JsAjax() {}
public static native JsAjax create() /*-{
return {};
}-*/;
public final native String getUrl() /*-{
return this.url;
}-*/;
public final native void setUrl(String value) /*-{
this.url = value;
}-*/;
public final native String getDataSrc() /*-{
return this.dataSrc;
}-*/;
public final native void setDataSrc(String value) /*-{
this.dataSrc = value;
}-*/;
public final native String getMethod() /*-{
return this.method;
}-*/;
public final native void setMethod(String value) /*-{
this.method = value;
}-*/;
}
static class JsLengthMenu extends JsArrayMixed {
protected JsLengthMenu() {}
public static native JsLengthMenu create(JsArrayInteger values, JsArrayString names) /*-{
return [values, names];
}-*/;
public static native JsLengthMenu create(JsArrayInteger values) /*-{
return values;
}-*/;
}
static class JsEnhanceParams extends JavaScriptObject {
protected JsEnhanceParams() {}
public static native JsEnhanceParams create() /*-{
return {};
}-*/;
public final native boolean isPaging() /*-{
return this.paging;
}-*/;
public final native void setPaging(boolean value) /*-{
this.paging = value;
}-*/;
public final native boolean isLengthChange() /*-{
return this.lengthChange;
}-*/;
public final native void setLengthChange(boolean value) /*-{
this.lengthChange = value;
}-*/;
public final native JsLengthMenu getLengthMenu() /*-{
return this.lengthMenu;
}-*/;
public final native void setLengtMenu(JsLengthMenu value) /*-{
this.lengthMenu = value;
}-*/;
public final native boolean isInfo() /*-{
return this.info;
}-*/;
public final native void setInfo(boolean value) /*-{
this.info = value;
}-*/;
public final native boolean isOrdering() /*-{
return this.ordering;
}-*/;
public final native void setOrdering(boolean value) /*-{
this.ordering = value;
}-*/;
public final native boolean isSearching() /*-{
return this.searching;
}-*/;
public final native void setSearching(boolean value) /*-{
this.searching = value;
}-*/;
public final native JsSortItems getOrder() /*-{
return this.order;
}-*/;
public final native void setOrder(JsSortItems value) /*-{
this.order = value;
}-*/;
public final native JsColumns getColumns() /*-{
return this.columns;
}-*/;
public final native void setColumns(JsColumns value) /*-{
this.columns = value;
}-*/;
public final native boolean isScrollX() /*-{
if (typeof this.scrollX === 'boolean') return this.scrollX;
else if (typeof this.scrollX === 'string' && this.scrollX !== '') return true;
else return false;
}-*/;
public final native void setScrollX(boolean value) /*-{
this.scrollX = value;
}-*/;
public final native String getScrollXcss() /*-{
if (typeof this.scrollX === 'string') return this.scrollX;
else return null;
}-*/;
public final native void setScrollXcss(String value) /*-{
this.scrollX = value;
this.scrollXInner = value; // even in 1.10.10 nothing is working without this line!
}-*/;
public final native String getScrollY() /*-{
return this.scrollY;
}-*/;
public final native void setScrollY(String value) /*-{
this.scrollY = value;
}-*/;
public final native boolean isScrollCollapse() /*-{
return this.scrollCollapse;
}-*/;
public final native void setScrollCollapse(boolean value) /*-{
this.scrollCollapse = value;
}-*/;
public final native JsLanguage getLanguage() /*-{
return this.language;
}-*/;
public final native void setLanguage(JsLanguage value) /*-{
this.language = value;
}-*/;
public final native String getPagingType() /*-{
return this.pagingType;
}-*/;
public final native void setPagingType(String value) /*-{
this.pagingType = value;
}-*/;
public final native String getAjax() /*-{
if (typeof this.ajax === 'string') return this.ajax;
else return null;
}-*/;
public final native void setAjax(String value) /*-{
this.ajax = value;
}-*/;
public final native JsAjax getAjaxObj() /*-{
if (typeof this.ajax === 'string') return { url: this.ajax };
else if (typeof this.ajax === 'function') return null;
else return this.ajax;
}-*/;
public final native void setAjaxObj(JsAjax value) /*-{
this.ajax = value;
}-*/;
public final native void setAjaxHandler(final Element tableElt, final AjaxHandler handler) /*-{
this.ajax = function ( request, drawCallback, settings ) {
handler.@com.sksamuel.jqm4gwt.plugins.datatables.JsDataTable.AjaxHandler::getData(
Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/core/client/JavaScriptObject;Lcom/google/gwt/core/client/JavaScriptObject;)
(tableElt, request, drawCallback);
};
}-*/;
public final native boolean isServerSide() /*-{
return this.serverSide;
}-*/;
public final native void setServerSide(boolean value) /*-{
this.serverSide = value;
}-*/;
public final native boolean isDeferRender() /*-{
return this.deferRender;
}-*/;
public final native void setDeferRender(boolean value) /*-{
this.deferRender = value;
}-*/;
public final native boolean isProcessing() /*-{
return this.processing;
}-*/;
public final native void setProcessing(boolean value) /*-{
this.processing = value;
}-*/;
public final native boolean isStateSave() /*-{
return this.stateSave;
}-*/;
public final native void setStateSave(boolean value) /*-{
this.stateSave = value;
}-*/;
public final native int getStateDuration() /*-{
return this.stateDuration;
}-*/;
public final native void setStateDuration(int value) /*-{
this.stateDuration = value;
}-*/;
public final native boolean isAutoWidth() /*-{
return this.autoWidth;
}-*/;
public final native void setAutoWidth(boolean value) /*-{
this.autoWidth = value;
}-*/;
public final native void setInitComplete(final JsCallback done) /*-{
this.initComplete = function(settings, json) {
done.@com.sksamuel.jqm4gwt.plugins.datatables.JsDataTable.JsCallback::onSuccess()();
};
}-*/;
public final native void setRowCallback(final JsRowCallback callback) /*-{
this.rowCallback = function( row, data ) {
callback.@com.sksamuel.jqm4gwt.plugins.datatables.JsDataTable.JsRowCallback::onRow(
Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/core/client/JavaScriptObject;)
(row, data);
};
}-*/;
}
static interface JsCallback {
void onSuccess();
}
static interface JsRowCallback {
void onRow(Element row, JavaScriptObject rowData);
}
static native void enhance(Element elt, JsEnhanceParams params) /*-{
if (params) $wnd.$(elt).DataTable(params); // $wnd.$.parseJSON(jsonParams)
else $wnd.$(elt).DataTable();
}-*/;
static native void setDataRoleNone(Element elt) /*-{
var i = $wnd.$(elt);
i.attr('data-role', 'none');
i.find('*').attr('data-role', 'none');
}-*/;
static native void ajaxReload(Element elt, boolean resetPaging) /*-{
$wnd.$(elt).DataTable().ajax.reload(
null, // no callback
resetPaging);
}-*/;
static native void ajaxReload(Element elt, String newUrl, boolean resetPaging) /*-{
$wnd.$(elt).DataTable().ajax.url(newUrl).load();
}-*/;
static native void draw(Element elt, boolean resetPaging) /*-{
$wnd.$(elt).DataTable().draw(resetPaging);
}-*/;
static native void drawPage(Element elt) /*-{
$wnd.$(elt).DataTable().draw('page');
}-*/;
/** Invalidate all rows. draw() or drawPage() must be called after it to repaint dataTable. */
static native void rowsInvalidate(Element elt) /*-{
$wnd.$(elt).DataTable().rows().invalidate();
}-*/;
static native JavaScriptObject getData(Element elt) /*-{
return $wnd.$(elt).DataTable().data();
}-*/;
static native void clearData(Element elt) /*-{
$wnd.$(elt).DataTable().clear();
}-*/;
/** See <a href="https://datatables.net/reference/api/destroy()">Remove all enhancements
* and return the table to its original un-enhanced state</a>
**/
static native void destroy(Element elt) /*-{
$wnd.$(elt).DataTable().destroy();
}-*/;
/**
* Allows multiple additions, like addRow(); addRow(); ...; draw();
* <br> draw() or drawPage() must be called after it to repaint dataTable.
*/
static native void addRow(Element elt, JavaScriptObject newRow) /*-{
$wnd.$(elt).DataTable().row.add(newRow);
}-*/;
/**
* Allows multiple removals, like removeRow(); removeRow(); ...; draw();
* <br> draw() or drawPage() must be called after it to repaint dataTable.
*/
static native void removeRow(Element elt, int rowIndex) /*-{
$wnd.$(elt).DataTable().row(rowIndex).remove();
}-*/;
static native void invalidateRow(Element tableElt, int rowIndex) /*-{
$wnd.$(elt).DataTable().row(rowIndex).invalidate();
}-*/;
static native void invalidateRow(Element tableElt, Element cellElt) /*-{
var tr = $wnd.$(cellElt).closest('tr');
var r = $wnd.$(tableElt).DataTable().row(tr);
r.invalidate();
}-*/;
static native void invalidateCell(Element tableElt, Element cellElt) /*-{
var $cell = $wnd.$(cellElt);
var cellSel = $cell.closest('td');
if (cellSel.length === 0) cellSel = $cell.closest('th');
if (cellSel.length !== 0) {
var cell = $wnd.$(tableElt).DataTable().cell(cellSel);
cell.invalidate();
}
}-*/;
public static native Element findTableElt(Element tableChildElt) /*-{
var t = $wnd.$(tableChildElt).closest('table');
return t ? t[0] : null;
}-*/;
public static interface CellClickHandler {
/**
* @param cellElt - could be ButtonElement, InputElement, ..., i.e. content of this cell.
* @return - if true then event.stopPropagation() will be called.
*/
boolean onClick(Element cellElt, JavaScriptObject rowData, int rowIndex,
int colIndex, int colVisibleIdx);
}
/**
* @param cellWidget - for example "button", "input[type='checkbox']"
* @param rowColRequired - true means that handler will be called back only
* if both row and column are known during click processing.
*/
static native void addCellClickHandler(Element elt, String cellWidget,
CellClickHandler handler, boolean rowColRequired) /*-{
var t = $wnd.$(elt);
t.children('tbody').first().on('click.cell', cellWidget, function(event) {
var that = $wnd.$(this);
var cellSel = that.closest('td');
if (cellSel.length === 0) cellSel = that.closest('th');
if (cellSel.length !== 0) {
var cell = t.DataTable().cell(cellSel);
var colIdx = -1, colVisibleIdx = -1;
if (cell) {
var cellIdx = cell.index();
if (cellIdx) {
colIdx = cellIdx.column;
colVisibleIdx = cellIdx.columnVisible;
}
}
var row = t.DataTable().row(that.closest('tr'));
var rowData = null, rowIdx = -1;
if (row) {
if (row.data()) rowData = row.data();
rowIdx = row.index();
}
if (rowColRequired && (rowIdx === -1 || colIdx === -1)) {
// probably row details widget was clicked
} else {
var rslt = handler.@com.sksamuel.jqm4gwt.plugins.datatables.JsDataTable.CellClickHandler::onClick(
Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/core/client/JavaScriptObject;III)
(this, rowData, rowIdx, colIdx, colVisibleIdx);
if (rslt) event.stopPropagation();
}
}
});
}-*/;
static native void removeCellClickHandler(Element elt, String cellWidget) /*-{
var t = $wnd.$(elt);
t.children('tbody').first().off('click.cell', cellWidget);
}-*/;
/** Predefined class for cell checkboxes, which are going to select/unselect rows. */
static final String CHECKBOX_ROWSEL = "checkbox-rowsel";
private static native void defineChangeRowsFunc() /*-{
if ($wnd.dataTableChangeRows) return;
$wnd.dataTableChangeRows = function(rows, selected, elt) {
if (rows) {
if (selected) {
rows.addClass('selected');
rows.find('.checkbox-rowsel').prop('checked', true);
} else {
rows.removeClass('selected');
rows.find('.checkbox-rowsel').prop('checked', false);
}
var rowSelChanged = $wnd.$(elt).closest('table').data('rowSelChanged');
if (rowSelChanged) {
rows.each(function(index) {
rowSelChanged(this, selected);
});
}
}
};
}-*/;
/** JsRowSelect.onRowSelChanged() will not be called, this method is needed for initial
* rows initialization after draw changed.
**/
static native void initRow(Element cellElt, boolean selected) /*-{
var row = $wnd.$(cellElt);
if (selected) {
row.addClass('selected');
row.find('.checkbox-rowsel').prop('checked', true);
} else {
row.removeClass('selected');
row.find('.checkbox-rowsel').prop('checked', false);
}
}-*/;
static interface JsRowSelect {
void onRowSelChanged(Element row, boolean selected, JavaScriptObject rowData);
}
static native void setRowSelChanged(final Element tableElt, JsRowSelect handler) /*-{
$wnd.$(tableElt).data('rowSelChanged', function(row, selected) {
var rowData = $wnd.$(tableElt).DataTable().row(row).data();
handler.@com.sksamuel.jqm4gwt.plugins.datatables.JsDataTable.JsRowSelect::onRowSelChanged(
Lcom/google/gwt/dom/client/Element;ZLcom/google/gwt/core/client/JavaScriptObject;)
(row, selected, rowData);
});
}-*/;
static native void switchOffSingleRowSelect(Element elt) /*-{
var t = $wnd.$(elt);
t.children('tbody').off('click.singlerowsel', 'tr[role=row]');
}-*/;
static native void switchOnSingleRowSelect(Element elt) /*-{
var t = $wnd.$(elt);
t.children('tbody').on('click.singlerowsel', 'tr[role=row]', function() {
var $this = $wnd.$(this);
if ($this.hasClass('selected')) {
$wnd.dataTableChangeRows($this, false, elt);
} else {
$wnd.dataTableChangeRows(t.DataTable().$('tr.selected'), false, elt);
$wnd.dataTableChangeRows($this, true, elt);
}
});
}-*/;
static native void switchOffMultiRowSelect(Element elt) /*-{
var t = $wnd.$(elt);
t.children('tbody').off('click.multirowsel', 'tr[role=row]');
}-*/;
static native void switchOnMultiRowSelect(Element elt) /*-{
var t = $wnd.$(elt);
t.children('tbody').on('click.multirowsel', 'tr[role=row]', function() {
var $this = $wnd.$(this);
if ($this.hasClass('selected')) {
$wnd.dataTableChangeRows($this, false, elt);
} else {
$wnd.dataTableChangeRows($this, true, elt);
}
});
}-*/;
static native void changeRow(Element cellElt, boolean selected) /*-{
$wnd.dataTableChangeRows($wnd.$(cellElt).closest('tr'), selected, cellElt);
}-*/;
static native void selectOneRowOnly(Element cellElt) /*-{
var rows = $wnd.$(cellElt).closest('tr');
if (rows.length) {
var row = rows.first();
$wnd.dataTableChangeRows(row.closest('tbody').children('tr.selected'), false, cellElt);
$wnd.dataTableChangeRows(row, true, cellElt);
}
}-*/;
static native void unselectAllRows(Element tableElt) /*-{
var t = $wnd.$(tableElt);
$wnd.dataTableChangeRows(t.DataTable().$('tr.selected'), false, tableElt);
}-*/;
static native JsArrayInteger getSelRowIndexes(Element tableElt) /*-{
return $wnd.$(tableElt).DataTable().rows('tr.selected').indexes().toArray();
}-*/;
static native JsArray<JavaScriptObject> getSelRowDatas(Element tableElt) /*-{
return $wnd.$(tableElt).DataTable().rows('tr.selected').data().toArray();
}-*/;
static interface JsRowDetails {
void onChanged(Element row, boolean opened, JavaScriptObject rowData);
}
static native void setRowDetailsChanged(final Element tableElt, JsRowDetails handler) /*-{
$wnd.$(tableElt).data('rowDetailsChanged', function(row, opened) {
var rowData = $wnd.$(tableElt).DataTable().row(row).data();
handler.@com.sksamuel.jqm4gwt.plugins.datatables.JsDataTable.JsRowDetails::onChanged(
Lcom/google/gwt/dom/client/Element;ZLcom/google/gwt/core/client/JavaScriptObject;)
(row, opened, rowData);
});
}-*/;
public static interface RowDetailsRenderer {
String getHtml(Element tableElt, JavaScriptObject rowData, int rowIndex);
}
static native void addRowDetailsRenderer(Element tableElt, RowDetailsRenderer renderer) /*-{
// Add event listener for opening and closing details
var t = $wnd.$(tableElt);
t.children('tbody').first().on('click', 'td.details-control', function(event) {
var tr = $wnd.$(this).closest('tr');
var row = t.DataTable().row(tr);
var rowDetailsChanged = $wnd.$(tableElt).data('rowDetailsChanged');
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
if (rowDetailsChanged) rowDetailsChanged(tr[0], false);
} else {
// Open this row
var html = renderer.@com.sksamuel.jqm4gwt.plugins.datatables.JsDataTable.RowDetailsRenderer::getHtml(
Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/core/client/JavaScriptObject;I)
(t[0], row.data(), row.index());
row.child(html).show();
tr.addClass('shown');
if (rowDetailsChanged) rowDetailsChanged(tr[0], true);
}
event.stopPropagation(); // no row selection is needed
});
}-*/;
static native void openRowDetails(Element tableElt, JsArrayString rowIds) /*-{
$wnd.$.each(rowIds, function ( i, id ) {
$wnd.$('#' + id + ' td.details-control', $wnd.$(tableElt)).trigger('click');
});
}-*/;
static native void closeRowDetails(Element tableElt, Element rowDetailElt) /*-{
var t = $wnd.$(tableElt);
var detailsTr = $wnd.$(rowDetailElt).closest('tr');
if (detailsTr[0]) {
var tr = detailsTr.prev('tr');
if (tr[0]) {
var row = t.DataTable().row(tr);
var rowDetailsChanged = t.data('rowDetailsChanged');
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
if (rowDetailsChanged) rowDetailsChanged(tr[0], false);
}
}
}
}-*/;
public static interface DrawHandler {
/**
* @param settings - actually it's private object, can be used to obtain an API instance if required.
*/
void afterDraw(Element tableElt, JavaScriptObject settings);
/**
* @return - false means cancel the draw.
*/
boolean beforeDraw(Element tableElt, JavaScriptObject settings);
}
static native void addDrawHandler(final Element tableElt, final DrawHandler handler) /*-{
var t = $wnd.$(tableElt);
t.on('draw.dt', function (event, settings) {
handler.@com.sksamuel.jqm4gwt.plugins.datatables.JsDataTable.DrawHandler::afterDraw(
Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/core/client/JavaScriptObject;)
(tableElt, settings);
});
t.on('preDraw.dt', function (event, settings) {
return handler.@com.sksamuel.jqm4gwt.plugins.datatables.JsDataTable.DrawHandler::beforeDraw(
Lcom/google/gwt/dom/client/Element;Lcom/google/gwt/core/client/JavaScriptObject;)
(tableElt, settings);
});
}-*/;
static native JavaScriptObject getCellData(Element elt, int rowIndex, int colIndex) /*-{
var v = $wnd.$(elt).DataTable().cells(rowIndex, colIndex).data();
return v.toArray();
}-*/;
static native JavaScriptObject getCellData(Element elt, int rowIndex, String colName) /*-{
var v = $wnd.$(elt).DataTable().cells(rowIndex, colName + ':name').data();
return v.toArray();
}-*/;
static native void createFooterIndividualColumnSearches(Element tableElt, String i18nSearchPrefix) /*-{
// Setup - add a text input to each footer cell
var t = $wnd.$(tableElt);
var prefix;
if (i18nSearchPrefix === null) {
prefix = t.DataTable().settings()[0].oLanguage.sSearch;
prefix = prefix.match(/_INPUT_/) ? prefix.replace('_INPUT_', '') : prefix;
prefix += ' ';
} else {
prefix = i18nSearchPrefix ? i18nSearchPrefix + ' ' : '';
}
$wnd.$('tfoot th', t).each(function () {
var $this = $wnd.$(this);
var s = $this.text();
if (s) {
$this.html('<input type="text" data-role="none" placeholder="' + prefix + s
+ '" style="width:100%;" />');
}
});
// Apply the search
t.DataTable().columns().every(function () {
var that = this;
$wnd.$('input', this.footer()).on('keyup change', function () {
that.search(this.value).draw();
});
});
}-*/;
/** See topic <b>Function</b> in <a href="https://datatables.net/reference/option/columns.data">columns.data</a> */
public static interface RowData {
/**
* @param rowData - the data for the whole row, usually JsArray or JavaScriptObject.
* @param opType - possible values: "set", "display", "filter", "sort", "type", null.
* @param setVal - should be used only when opType is "set".
* @param metaInfo - an object that contains additional information about the cell being requested.
* @return - array of length 1, it's not used by itself, only the first element is important/needed,
* so array can be reused for performance optimization.
*/
JsArrayMixed onData(Element tableElt, JavaScriptObject rowData, String opType,
JavaScriptObject setVal, JavaScriptObject/*JsRowDataMetaInfo*/ metaInfo);
}
public static class JsRowDataMetaInfo extends JavaScriptObject {
protected JsRowDataMetaInfo() {}
public final native int getRow() /*-{
return this.row;
}-*/;
public final native int getCol() /*-{
return this.col;
}-*/;
/** Actually it's private object, can be used to obtain an API instance if required. */
public final native JavaScriptObject getSettings() /*-{
return this.settings;
}-*/;
}
/**
* Creates groups bands by specified column.
* <br> Could be called from afterDraw() event handler, see addDrawHandler()
*
* <br> You should define group styling in CSS like this:
* <br> .dataTable tr.group, .dataTable tr.group:hover { background-color: #ddd !important; }
* <br> OR you can directly process group row elements, which are returned by this method.
*
* @param additionalSorts - will be sorted by colIdx column + additionalSorts
*
* @return - array of group rows, can be used for additional adjustments.
**/
static native JsArray<Element> doGrouping(JavaScriptObject settings, int colIdx, JsSortItems additionalSorts) /*-{
var api = new $wnd.$.fn.dataTable.Api(settings);
var rows = api.rows({page:'current'}).nodes();
var cnt = 0;
api.columns().visible().each(function (v) { if (v) cnt++; });
var last = null;
var grpRows = [];
api.column(colIdx, {page:'current'}).data().each(function (group, i) {
if (last !== group) {
var firstGrpRow = $wnd.$(rows).eq(i).before(
'<tr class="group"><td colspan="' + cnt + '">' + group + '</td></tr>'
);
grpRows.push(firstGrpRow.prev()[0]);
last = group;
}
});
// Order by the grouping on group band click
$wnd.$(api.table().body()).off('click.group');
$wnd.$(api.table().body()).on('click.group', 'tr.group', function (event) {
var newSorts = [];
var currentOrder = api.order()[0];
if (currentOrder[0] === colIdx && currentOrder[1] === 'asc') {
newSorts.push([colIdx, 'desc']);
} else if (currentOrder[0] !== colIdx || currentOrder[1] !== 'asc') {
newSorts.push([colIdx, 'asc']);
}
if (additionalSorts) newSorts.push.apply(newSorts, additionalSorts);
api.order(newSorts).draw();
});
return grpRows;
}-*/;
static native void clearSearch(Element tableElt) /*-{
var t = $wnd.$(tableElt).DataTable();
t.search( '' ).columns().search( '' ).draw();
}-*/;
static native void adjustColumnSizing(Element tableElt) /*-{
var t = $wnd.$(tableElt).dataTable();
t.fnAdjustColumnSizing(false); // no redraw
}-*/;
static native void setColVisible(Element tableElt, String colName, boolean visible) /*-{
if (colName) {
var t = $wnd.$(tableElt).DataTable();
var col = t.column(colName + ':name');
if (col) col.visible(visible);
}
}-*/;
}