Skip to content

Commit

Permalink
Use latest bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan Kuethe committed Sep 24, 2024
1 parent ad8e4e6 commit 7645f87
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 5 deletions.
2 changes: 1 addition & 1 deletion docs/examples/getting_started/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def tabulator():
df = pd.read_csv(
"https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"
)
return Tabulator(df, table_options={"height": 311})
return Tabulator(df, options={"height": 311})

@render.code
async def txt():
Expand Down
4 changes: 4 additions & 0 deletions get-py-bindings.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
branch=${1:-dev}
# curl -O https://raw.githubusercontent.com/eodaGmbH/tabulator-bindings/${branch}/r-bindings/rtabulator.js
curl -o pytabulator/srcjs/pytabulator.js https://raw.githubusercontent.com/eodaGmbH/tabulator-bindings/refs/heads/feature/typescript/py-bindings/pytabulator.js
4 changes: 2 additions & 2 deletions pytabulator/shiny_bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ def tabulator_dep() -> HTMLDependency:


tabulator_bindings_dep = HTMLDependency(
"tabulator-bindings",
"pytabulator",
"0.1.0",
source={"package": "pytabulator", "subdir": "srcjs"},
script={"src": "tabulator-bindings.js", "type": "module"},
script={"src": "pytabulator.js", "type": "module"},
all_files=False,
)

Expand Down
129 changes: 129 additions & 0 deletions pytabulator/srcjs/pytabulator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
"use strict";
(() => {
// built/utils.js
function convertToDataFrame(data) {
const res = {};
if (data.length === 0) {
return res;
}
const keys = Object.keys(data[0]);
keys.forEach((key) => res[key] = data.map((item) => item[key]));
return res;
}

// built/events.js
function addEventListeners(tabulatorWidget) {
const table = tabulatorWidget.getTable();
const elementId = tabulatorWidget.getElementId();
const bindingLang = tabulatorWidget.getBindingLang();
console.log("binding lang", bindingLang);
table.on("rowClick", function(e, row) {
const inputName = `${elementId}_row_clicked`;
console.log(inputName, row.getData());
Shiny.onInputChange(inputName, row.getData());
});
table.on("rowClick", (e, row) => {
const inputName = bindingLang === "r" ? `${elementId}_data:rtabulator.data` : `${elementId}_data`;
const data = table.getSelectedRows().map((row2) => row2.getData());
console.log(inputName, data);
Shiny.onInputChange(inputName, { data: convertToDataFrame(data) });
});
table.on("cellEdited", function(cell) {
const inputName = `${elementId}_cell_edited`;
console.log(inputName, cell.getData());
Shiny.onInputChange(inputName, cell.getData());
});
table.on("dataFiltered", function(filters, rows) {
const inputName = bindingLang === "r" ? `${elementId}_data:rtabulator.data` : `${elementId}_data`;
const data = rows.map((row) => row.getData());
console.log(inputName, data);
Shiny.onInputChange(inputName, { data: convertToDataFrame(data) });
});
}

// built/widget.js
function run_calls(tabulatorWidget, calls) {
const table = tabulatorWidget.getTable();
const elementId = tabulatorWidget.getElementId();
const bindingLang = tabulatorWidget.getBindingLang();
console.log("binding lang", bindingLang);
calls.forEach(([method_name, options]) => {
if (method_name === "getData") {
const inputName = bindingLang === "r" ? `${elementId}_data:rtabulator.data` : `${elementId}_data`;
console.log("custom call", inputName);
Shiny.setInputValue(inputName, { data: convertToDataFrame(table.getData()) }, { priority: "event" });
return;
}
if (method_name === "deleteSelectedRows") {
console.log("custom call");
const rows = table.getSelectedRows();
rows.forEach((row) => {
console.log(row.getIndex());
table.deleteRow(row.getIndex());
});
return;
}
if (method_name === "getSheetData") {
const inputName = bindingLang === "r" ? `${elementId}_sheet_data:rtabulator.sheet_data` : `${elementId}_sheet_data`;
console.log("custom call", inputName);
Shiny.setInputValue(inputName, { data: table.getSheetData() }, { priority: "event" });
return;
}
console.log(method_name, options);
table[method_name](...options);
});
}
var TabulatorWidget = class {
constructor(container, data, options, bindingOptions) {
options.data = data;
this._container = container;
this._bindingOptions = bindingOptions;
console.log("columns", options.columns);
if (data !== null && options.columns == null) {
options.autoColumns = true;
}
if (options.spreadsheet && options.spreadsheetData == null) {
options.spreadsheetData = [];
}
this._table = new Tabulator(this._container, options);
if (typeof Shiny === "object") {
addEventListeners(this);
this._addShinyMessageHandler();
}
}
_addShinyMessageHandler() {
const messageHandlerName = `tabulator-${this._container.id}`;
Shiny.addCustomMessageHandler(messageHandlerName, (payload) => {
console.log(payload);
run_calls(this, payload.calls);
});
}
getTable() {
return this._table;
}
getElementId() {
return this._container.id;
}
getBindingLang() {
return this._bindingOptions.lang;
}
};

// built/index-py.js
var TabulatorOutputBinding = class extends Shiny.OutputBinding {
find(scope) {
return scope.find(".shiny-tabulator-output");
}
renderValue(el, payload) {
console.log("payload", payload);
const widget = new TabulatorWidget(el, payload.data, payload.options, payload.bindingOptions);
const table = widget.getTable();
table.on("tableBuilt", function() {
if (payload.options.columnUpdates != null) {
console.log("column updates", payload.options.columnUpdates);
}
});
}
};
Shiny.outputBindings.register(new TabulatorOutputBinding(), "shiny-tabulator-output");
})();
1 change: 0 additions & 1 deletion pytabulator/srcjs/tabulator-bindings.js

This file was deleted.

6 changes: 5 additions & 1 deletion pytabulator/tabulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ def set_options(self, **kwargs) -> Self:
return self

def to_dict(self) -> dict:
# TODO: Rename 'data' to ???
# TODO: Rename 'data' to ??? model!?
data = df_to_dict(self.df)
data["options"] = self._options.to_dict()
data["bindingOptions"] = dict(lang = "python")
return data

def to_html(self):
pass

0 comments on commit 7645f87

Please sign in to comment.