|
|
|
|
|
|
|
|
github_sha_link <- function(sha) { |
|
|
github_sha_link <- function(sha) { |
|
|
glue::glue("[{sha}](https://github.com/gadenbuie/js4shiny-frappeCharts/commit/{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}\")`" |
|
|
|
|
|
)) |
|
|
|
|
|
} |
|
|
``` |
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Create our own typingSpeedInput() |
|
|
## Create our own typingSpeedInput() |
|
|
|
|
|
|
|
|
|
|
|
`r github_sha_link("b7108029b58635652ce87f3e1ea9a2c5a6232020")` |
|
|
|
|
|
|
|
|
Use Shiny's `textAreaInput()` to get the template |
|
|
Use Shiny's `textAreaInput()` to get the template |
|
|
for our own `typingSpeedInput()` |
|
|
for our own `typingSpeedInput()` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
) |
|
|
) |
|
|
``` |
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
## 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> |