Skip to content

Commit 927fda3

Browse files
committed
datagrid: get filtered data as input
1 parent 1ed43eb commit 927fda3

File tree

9 files changed

+177
-19
lines changed

9 files changed

+177
-19
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# toastui 0.4.0
22

33
* New htmlwidget `editor()`, a Markdown WYSIWYG Editor (https://ui.toast.com/tui-editor).
4+
* New input `input$<outputId>_data_filtered` in `datagrid()` to get filtered data displayed in table.
5+
46

57

68
# toastui 0.3.4
@@ -10,6 +12,7 @@
1012
* `datagridOutput()` / `renderDatagrid()` fixed a bug causing table to have a css class `recalculating` added to the outpput element.
1113

1214

15+
1316
# toastui 0.3.3
1417

1518
* New function `grid_col_checkbox()` to add checkboxes into a column.

R/grid-filters.R

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,17 @@ grid_filters <- function(grid,
5656
if (!is.null(operator))
5757
operator <- rep_len(x = operator, length.out = n_col)
5858
if (!is.null(type))
59-
type <- rep_len(x = type, length.out = n_col)
59+
type <- as.list(rep_len(x = type, length.out = n_col))
6060
filters_type <- simple_filters(grid$x$data_df)
6161
for (column in columns) {
6262
i <- which(grid$x$colnames == column)
6363
j <- which(columns == column)
64-
if (identical(type[j], "auto")) {
65-
type[j] <- filters_type[[column]]
64+
if (identical(type[[j]], "auto")) {
65+
type[[j]] <- filters_type[[column]]
6666
}
6767
filtering <- dropNulls(list(
68-
type = type[j],
69-
options = if (type[j] == "date") list(format = format),
68+
type = type[[j]],
69+
options = if (identical(type[[j]], "date")) list(format = format),
7070
showApplyBtn = showApplyBtn[j],
7171
showClearBtn = showClearBtn[j],
7272
operator = operator[j]

R/shiny.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ renderCalendar <- function(expr, env = parent.frame(), quoted = FALSE) {
5959
#' @details # Special inputs
6060
#' The following `input` values will be accessible in the server:
6161
#' * **input$outputId_data** : contain the data displayed in grid, only available when `datagrid(data_as_input = TRUE)` or when using [grid_editor()]
62+
#' * **input$outputId_data_filtered** : contain the filtered data displayed in grid, only available when `datagrid(data_as_input = TRUE)` or when using [grid_editor()]
6263
#' * **input$outputId_validation** : contain results of validation rules applied to data, only available when using `validation` argument in [grid_editor()]
6364
#'
6465
#' These other inputs can be defined using other functions:

examples/shiny-datagrid-input.R

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
library(shiny)
2+
library(toastui)
3+
4+
ui <- fluidPage(
5+
tags$h2("datagrid as input"),
6+
fluidRow(
7+
column(
8+
width = 6,
9+
datagridOutput("grid")
10+
),
11+
column(
12+
width = 6,
13+
verbatimTextOutput("data"),
14+
verbatimTextOutput("data_filtered")
15+
)
16+
)
17+
)
18+
19+
server <- function(input, output, session) {
20+
21+
output$grid <- renderDatagrid({
22+
data <- data.frame(
23+
number = 1:12,
24+
month.abb = month.abb,
25+
month.name = month.name,
26+
date = Sys.Date() + 0:11,
27+
stringsAsFactors = FALSE
28+
)
29+
datagrid(data, data_as_input = TRUE) %>%
30+
grid_filters(
31+
columns = "month.abb",
32+
showApplyBtn = TRUE,
33+
showClearBtn = TRUE,
34+
type = "text"
35+
) %>%
36+
grid_filters(
37+
columns = "month.name",
38+
type = "select"
39+
) %>%
40+
grid_filters(columns = "date") %>%
41+
grid_filters(columns = "number")
42+
})
43+
44+
output$data <- renderPrint({
45+
input$grid_data
46+
})
47+
48+
output$data_filtered <- renderPrint({
49+
input$grid_data_filtered
50+
})
51+
52+
}
53+
54+
if (interactive())
55+
shinyApp(ui, server)

inst/htmlwidgets/datagrid.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/datagrid-shiny.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export class DatagridTextInputRenderer {
2+
constructor(props) {
3+
const el = document.createElement("div");
4+
const classEl = props.columnInfo.renderer.options.class;
5+
el.className = classEl;
6+
const input = document.createElement("input");
7+
const { grid, rowKey, columnInfo } = props;
8+
const value = String(props.value);
9+
input.type = "text";
10+
input.className = "form-check-input";
11+
input.style.width = "100%";
12+
input.value = value;
13+
input.addEventListener("change", () => {
14+
grid.setValue(rowKey, columnInfo.name, input.value);
15+
});
16+
el.appendChild(input);
17+
this.el = el;
18+
this.render(props);
19+
}
20+
21+
getElement() {
22+
return this.el;
23+
}
24+
25+
render(props) {
26+
//const checked = Boolean(props.value);
27+
//this.el.checked = checked;
28+
}
29+
}

srcjs/modules/proxy-grid.js

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ export function ProxyGrid() {
1414
Shiny.setInputValue(obj.id + "_data:datagridEdit", {
1515
data: grid.getData(),
1616
colnames: config.colnames,
17-
});
17+
}, {priority: "event"});
18+
Shiny.setInputValue(obj.id + "_data_filtered:datagridEdit", {
19+
data: grid.getFilteredData(),
20+
colnames: config.colnames,
21+
}, {priority: "event"});
1822
}
1923
}
2024
}
@@ -25,16 +29,20 @@ export function ProxyGrid() {
2529
var grid = utils.getWidget(obj.id);
2630
if (typeof grid != "undefined") {
2731
grid.setColumnValues(
28-
obj.data.columnName,
29-
obj.data.columnValue,
32+
obj.data.columnName,
33+
obj.data.columnValue,
3034
obj.data.checkCellState
3135
);
3236
var config = utils.getConfig(obj.id);
3337
if (config.dataAsInput === true) {
3438
Shiny.setInputValue(obj.id + "_data:datagridEdit", {
3539
data: grid.getData(),
3640
colnames: config.colnames,
37-
});
41+
}, {priority: "event"});
42+
Shiny.setInputValue(obj.id + "_data_filtered:datagridEdit", {
43+
data: grid.getFilteredData(),
44+
colnames: config.colnames,
45+
}, {priority: "event"});
3846
}
3947
}
4048
}
@@ -45,15 +53,19 @@ export function ProxyGrid() {
4553
var grid = utils.getWidget(obj.id);
4654
if (typeof grid != "undefined") {
4755
grid.setRow(
48-
obj.data.rowKey,
56+
obj.data.rowKey,
4957
obj.data.row
5058
);
5159
var config = utils.getConfig(obj.id);
5260
if (config.dataAsInput === true) {
5361
Shiny.setInputValue(obj.id + "_data:datagridEdit", {
5462
data: grid.getData(),
5563
colnames: config.colnames,
56-
});
64+
}, {priority: "event"});
65+
Shiny.setInputValue(obj.id + "_data_filtered:datagridEdit", {
66+
data: grid.getFilteredData(),
67+
colnames: config.colnames,
68+
}, {priority: "event"});
5769
}
5870
}
5971
}
@@ -79,7 +91,11 @@ export function ProxyGrid() {
7991
Shiny.setInputValue(obj.id + "_data:datagridEdit", {
8092
data: grid.getData(),
8193
colnames: config.colnames,
82-
});
94+
}, {priority: "event"});
95+
Shiny.setInputValue(obj.id + "_data_filtered:datagridEdit", {
96+
data: grid.getFilteredData(),
97+
colnames: config.colnames,
98+
}, {priority: "event"});
8399
}
84100
}
85101
}
@@ -100,7 +116,11 @@ export function ProxyGrid() {
100116
Shiny.setInputValue(obj.id + "_data:datagridEdit", {
101117
data: grid.getData(),
102118
colnames: config.colnames,
103-
});
119+
}, {priority: "event"});
120+
Shiny.setInputValue(obj.id + "_data_filtered:datagridEdit", {
121+
data: grid.getFilteredData(),
122+
colnames: config.colnames,
123+
}, {priority: "event"});
104124
}
105125
}
106126
}

srcjs/widgets/datagrid.js

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,49 @@ HTMLWidgets.widget({
199199
data: grid.getData(),
200200
colnames: x.colnames,
201201
}, {priority: "event"});
202+
Shiny.setInputValue(el.id + "_data_filtered:datagridEdit", {
203+
data: grid.getFilteredData(),
204+
colnames: x.colnames,
205+
}, {priority: "event"});
202206
grid.on("afterSort", function (ev) {
203207
Shiny.setInputValue(el.id + "_data:datagridEdit", {
204208
data: ev.instance.getData(),
205209
colnames: x.colnames,
206210
}, {priority: "event"});
211+
Shiny.setInputValue(el.id + "_data_filtered:datagridEdit", {
212+
data: ev.instance.getFilteredData(),
213+
colnames: x.colnames,
214+
}, {priority: "event"});
215+
});
216+
grid.on("afterUnsort", function (ev) {
217+
Shiny.setInputValue(el.id + "_data:datagridEdit", {
218+
data: ev.instance.getData(),
219+
colnames: x.colnames,
220+
}, {priority: "event"});
221+
Shiny.setInputValue(el.id + "_data_filtered:datagridEdit", {
222+
data: ev.instance.getFilteredData(),
223+
colnames: x.colnames,
224+
}, {priority: "event"});
225+
});
226+
grid.on("afterFilter", function (ev) {
227+
Shiny.setInputValue(el.id + "_data:datagridEdit", {
228+
data: ev.instance.getData(),
229+
colnames: x.colnames,
230+
}, {priority: "event"});
231+
Shiny.setInputValue(el.id + "_data_filtered:datagridEdit", {
232+
data: ev.instance.getFilteredData(),
233+
colnames: x.colnames,
234+
}, {priority: "event"});
235+
});
236+
grid.on("afterUnfilter", function (ev) {
237+
Shiny.setInputValue(el.id + "_data:datagridEdit", {
238+
data: ev.instance.getData(),
239+
colnames: x.colnames,
240+
}, {priority: "event"});
241+
Shiny.setInputValue(el.id + "_data_filtered:datagridEdit", {
242+
data: ev.instance.getFilteredData(),
243+
colnames: x.colnames,
244+
}, {priority: "event"});
207245
});
208246
if (x.validationInput === true) {
209247
Shiny.setInputValue(
@@ -224,11 +262,15 @@ HTMLWidgets.widget({
224262
if (editButton === null) {
225263
console.log("datagrid editor updateOnClick: could not find ID.");
226264
} else {
227-
editButton.addEventListener("click", function (event) {
228-
grid.finishEditing();
229-
grid.blur();
265+
editButton.addEventListener("click", function (ev) {
266+
ev.instance.finishEditing();
267+
ev.instance.blur();
230268
Shiny.setInputValue(el.id + "_data:datagridEdit", {
231-
data: grid.getData(),
269+
data: ev.instance.getData(),
270+
colnames: x.colnames,
271+
}, {priority: "event"});
272+
Shiny.setInputValue(el.id + "_data_filtered:datagridEdit", {
273+
data: ev.instance.getFilteredData(),
232274
colnames: x.colnames,
233275
}, {priority: "event"});
234276
});
@@ -239,6 +281,10 @@ HTMLWidgets.widget({
239281
data: ev.instance.getData(),
240282
colnames: x.colnames,
241283
}, {priority: "event"});
284+
Shiny.setInputValue(el.id + "_data_filtered:datagridEdit", {
285+
data: ev.instance.getFilteredData(),
286+
colnames: x.colnames,
287+
}, {priority: "event"});
242288
});
243289
}
244290
}
@@ -262,6 +308,10 @@ HTMLWidgets.widget({
262308
data: ev.instance.getData(),
263309
colnames: x.colnames,
264310
}, {priority: "event"});
311+
Shiny.setInputValue(el.id + "_data_filtered:datagridEdit", {
312+
data: ev.instance.getFilteredData(),
313+
colnames: x.colnames,
314+
}, {priority: "event"});
265315
});
266316
}
267317
},
@@ -274,7 +324,6 @@ HTMLWidgets.widget({
274324
},
275325

276326
resize: function (width, height) {
277-
// TODO: code to re-render the widget with a new size
278327
if (typeof grid !== "undefined") {
279328
grid.refreshLayout();
280329
}

0 commit comments

Comments
 (0)