diff --git a/.gitignore b/.gitignore
index 3151c335..6ba72d89 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,4 @@
-.Rproj.user
-.Rhistory
-.RData
-tools/DataTables*
-tools/Plugins
-rsconnect/
-large.txt
-inst/examples/random.R
-.*.Rnb.cached
-revdep/
+.Rproj.user
+.Rhistory
+.RData
+.DS_Store
diff --git a/inst/examples/DT-edit/app.R b/inst/examples/DT-edit/app.R
index 36db1cd5..116dd425 100644
--- a/inst/examples/DT-edit/app.R
+++ b/inst/examples/DT-edit/app.R
@@ -3,43 +3,29 @@ library(DT)
shinyApp(
ui = fluidPage(
title = 'Double-click to edit table cells',
- fluidRow(column(12, h1('Client-side processing'), hr(), DTOutput('x1'))),
- fluidRow(column(12, h1('Server-side processing'), hr(), DTOutput('x2'))),
- fluidRow(column(12, h1('Server-side processing (no row names)'), hr(), DTOutput('x3')))
+ titlePanel('Double-click to edit table cells'),
+ DTOutput('x1')
),
server = function(input, output, session) {
d1 = iris
- d1$Date = Sys.time() + seq_len(nrow(d1))
- d2 = d3 = d1
- options(DT.options = list(pageLength = 5))
+ output$x1 = renderDT(d1, selection = "none", editable = T, rownames = T, options = list(
+ editType = list("0" = "text", "1" = "text", "2" = "text", "3" = "text", "4" = "select"),
+ editAttribs = list("0" = list(placeholder = "Length"), "1" = list(placeholder = "Width"),
+ "2" = list(placeholder = "Length"), "3" = list(placeholder = "Width"),
+ "4" = list(options = c("setosa", "versicolor", "virginica")))
+ ))
- output$x1 = renderDT(d1, selection = 'none', server = FALSE, editable = TRUE)
- output$x2 = renderDT(d2, selection = 'none', editable = TRUE)
- output$x3 = renderDT(d3, selection = 'none', rownames = FALSE, editable = TRUE)
-
- proxy2 = dataTableProxy('x2')
-
- observeEvent(input$x2_cell_edit, {
- info = input$x2_cell_edit
+ proxy1 = dataTableProxy('x1')
+
+ observeEvent(input$x1_cell_edit, {
+ info = input$x1_cell_edit
str(info)
i = info$row
j = info$col
v = info$value
- d2[i, j] <<- DT::coerceValue(v, d2[i, j])
- replaceData(proxy2, d2, resetPaging = FALSE) # important
- })
-
- proxy3 = dataTableProxy('x3')
-
- observeEvent(input$x3_cell_edit, {
- info = input$x3_cell_edit
- str(info)
- i = info$row
- j = info$col + 1 # column index offset by 1
- v = info$value
- d3[i, j] <<- DT::coerceValue(v, d3[i, j])
- replaceData(proxy3, d3, resetPaging = FALSE, rownames = FALSE)
+ d1[i, j] <<- DT::coerceValue(v, d1[i, j])
+ replaceData(proxy1, d1, resetPaging = FALSE) # important
})
}
)
diff --git a/inst/htmlwidgets/datatables.js b/inst/htmlwidgets/datatables.js
index d66752c9..7ff11415 100644
--- a/inst/htmlwidgets/datatables.js
+++ b/inst/htmlwidgets/datatables.js
@@ -682,29 +682,136 @@ HTMLWidgets.widget({
// run the callback function on the table instance
if (typeof data.callback === 'function') data.callback(table);
- // double click to edit the cell
- if (data.editable) table.on('dblclick.dt', 'tbody td', function() {
- var $input = $('');
- var $this = $(this), value = table.cell(this).data(), html = $this.html();
- var changed = false;
- $input.val(value);
- $this.empty().append($input);
- $input.css('width', '100%').focus().on('change', function() {
- changed = true;
- var valueNew = $input.val();
- if (valueNew != value) {
- table.cell($this).data(valueNew);
- if (HTMLWidgets.shinyMode) changeInput('cell_edit', cellInfo($this));
- // for server-side processing, users have to call replaceData() to update the table
- if (!server) table.draw(false);
- } else {
- $this.html(html);
+ // editor is enabled
+ if (data.editable) {
+ var editorNextCell = null; // declare variable for next cell to be acivated by the tab key
+ var options = table.init(); // load table options
+ if ('editType' in options) {
+ for (var key in options.editType) {
+ colIndex = parseInt(key);
+ if (table.column(0).header().innerHTML == ' ')
+ colIndex = colIndex + 1;
+ $(table.column(colIndex).header()).attr('data-editortype', options.editType[key]).attr('data-editoroptions', JSON.stringify(options.editAttribs[key])); // set column editor attributes
+ }
+ } else {
+ table.columns().every(function() {
+ if (this.header().innerHTML != ' ')
+ $(this.header()).attr('data-editortype', 'text').attr('data-editoroptions', JSON.stringify({placeholder: this.header().innerHTML})); // set column editor attributes
+ });
+ }
+
+ // double click to edit the cell
+ table.on('dblclick.dt', 'tbody td', function() {
+ if (table.column(this).header().hasAttribute('data-editortype')) { // cell is marked as editable
+ var $this = $(this), value = table.cell(this).data(), html = $this.html();
+ var changed = false;
+ if (table.column(this).header().getAttribute('data-editortype') == 'text') { // cell shall display a textinput
+ var $input = $('');
+ $input.val(value);
+ $input.attr('placeholder', JSON.parse(table.column(this).header().getAttribute('data-editoroptions')).placeholder);
+ } else if (table.column(this).header().getAttribute('data-editortype') == 'select') { // cell shall display a selectinput
+ var $input = $('