Explorar el Código

Scaffold shiny input binding

shiny-input
Garrick Aden-Buie hace 6 años
padre
commit
02adb896c5
Se han modificado 2 ficheros con 153 adiciones y 0 borrados
  1. +89
    -0
      inst/shiny-input-app/dev-shiny-input.Rmd
  2. +64
    -0
      inst/shiny-input-app/typing.js

+ 89
- 0
inst/shiny-input-app/dev-shiny-input.Rmd Ver fichero

@@ -8,6 +8,15 @@ knitr::opts_chunk$set(eval = FALSE)
github_sha_link <- function(sha) {
glue::glue("[{sha}](https://github.com/gadenbuie/js4shiny-frappeCharts/commit/{sha})")
}

get_last_sha <- function() {
commit <- git2r::commits()[[1]]
message(commit$summary)
message(commit$sha)
clipr::write_clip(glue::glue(
"`r github_sha_link(\"{commit$sha}\")`"
))
}
```


@@ -58,6 +67,8 @@ Run this app and type in the box.

## Create our own typingSpeedInput()

`r github_sha_link("b7108029b58635652ce87f3e1ea9a2c5a6232020")`

Use Shiny's `textAreaInput()` to get the template
for our own `typingSpeedInput()`

@@ -104,3 +115,81 @@ ui <- fluidPage(
)
```

## Start creating an input binding for `typingSpeedInput()`

Now we can open `typing.js` and create a Shiny input binding.

If you used `js4shiny::snippets_install()`,
you have a `ShinyInputBinding` snippet that provides a template for you.
Or you can copy the chunk below.

<details><summary>Shiny Input Binding Template</summary>

```js
// Ref: https://shiny.rstudio.com/articles/building-inputs.html
// Ref: https://github.com/rstudio/shiny/blob/master/srcjs/input_binding.js

const bindingName = new Shiny.InputBinding();

$.extend(bindingName, {
find: function(scope) {
// Specify the selector that identifies your input. `scope` is a general
// parent of your input elements. This function should return the nodes of
// ALL of the inputs that are inside `scope`. These elements should all
// have IDs that are used as the inputId on the server side.
return scope.querySelectorAll("inputBindingSelector");
},
getValue: function(el) {
// For a particular input, this function is given the element containing
// your input. In this function, find or construct the value that will be
// returned to Shiny. The ID of `el` is used for the inputId.

// e.g: return el.value
return 'FIXME';
},
setValue: function(el, value) {
// This method is used for restoring the bookmarked state of your input
// and allows you to set the input's state without triggering reactivity.
// Basically, reverses .getValue()

// e.g.; el.value = value
console.error('bindingName.setValue() is not yet defined');
},
receiveMessage: function(el, data) {
// Given the input's container and data, update the input
// and its elements to reflect the given data.
// The messages are sent from R/Shiny via
// R> session$sendInputMessage(inputId, data)
console.error('bindingName.receiveMessage() is not yet defined');

// If you want the update to trigger reactivity, trigger a subscribed event
$(el).trigger("change")
},
subscribe: function(el, callback) {
// Listen to events on your input element. The following block listens to
// the change event, but you might want to listen to another event.
// Repeat the block for each event type you want to subscribe to.

$(el).on("change.bindingName", function(e) {
// Use callback() or callback(true).
// If using callback(true) the rate policy applies,
// for example if you need to throttle or debounce
// the values being sent back to the server.
callback();
});
},
getRatePolicy: function() {
return {
policy: 'debounce', // 'debounce', 'throttle' or 'direct' (default)
delay: 100 // milliseconds for debounce or throttle
};
},
unsubscribe: function(el) {
$(el).off(".bindingName");
}
});

Shiny.inputBindings.register(bindingName, 'pkgName.bindingName');
```

</details>

+ 64
- 0
inst/shiny-input-app/typing.js Ver fichero

@@ -0,0 +1,64 @@
// Ref: https://shiny.rstudio.com/articles/building-inputs.html
// Ref: https://github.com/rstudio/shiny/blob/master/srcjs/input_binding.js

const bindingName = new Shiny.InputBinding();

$.extend(bindingName, {
find: function(scope) {
// Specify the selector that identifies your input. `scope` is a general
// parent of your input elements. This function should return the nodes of
// ALL of the inputs that are inside `scope`. These elements should all
// have IDs that are used as the inputId on the server side.
return scope.querySelectorAll("inputBindingSelector");
},
getValue: function(el) {
// For a particular input, this function is given the element containing
// your input. In this function, find or construct the value that will be
// returned to Shiny. The ID of `el` is used for the inputId.

// e.g: return el.value
return 'FIXME';
},
setValue: function(el, value) {
// This method is used for restoring the bookmarked state of your input
// and allows you to set the input's state without triggering reactivity.
// Basically, reverses .getValue()

// e.g.; el.value = value
console.error('bindingName.setValue() is not yet defined');
},
receiveMessage: function(el, data) {
// Given the input's container and data, update the input
// and its elements to reflect the given data.
// The messages are sent from R/Shiny via
// R> session$sendInputMessage(inputId, data)
console.error('bindingName.receiveMessage() is not yet defined');

// If you want the update to trigger reactivity, trigger a subscribed event
$(el).trigger("change")
},
subscribe: function(el, callback) {
// Listen to events on your input element. The following block listens to
// the change event, but you might want to listen to another event.
// Repeat the block for each event type you want to subscribe to.

$(el).on("change.bindingName", function(e) {
// Use callback() or callback(true).
// If using callback(true) the rate policy applies,
// for example if you need to throttle or debounce
// the values being sent back to the server.
callback();
});
},
getRatePolicy: function() {
return {
policy: 'debounce', // 'debounce', 'throttle' or 'direct' (default)
delay: 100 // milliseconds for debounce or throttle
};
},
unsubscribe: function(el) {
$(el).off(".bindingName");
}
});

Shiny.inputBindings.register(bindingName, 'pkgName.bindingName');

Cargando…
Cancelar
Guardar