From 1931ce887c13a8d84bc433ecd199737238769b31 Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Thu, 6 Sep 2012 16:59:39 -0700 Subject: [PATCH] More input binding stuff --- _includes/tutorial/building-inputs.md | 70 +++++++++++++++++++++++++-- tutorial/index.html | 3 +- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/_includes/tutorial/building-inputs.md b/_includes/tutorial/building-inputs.md index abd52ec43..ba66871c7 100644 --- a/_includes/tutorial/building-inputs.md +++ b/_includes/tutorial/building-inputs.md @@ -7,6 +7,12 @@ Shiny input components should try to adhere to the following principles, if poss * **Designed to be used from HTML and R:** Shiny user interfaces can either be written using R code (that generates HTML), or by writing the HTML directly. A well-designed Shiny input component will take both styles into account: offer an R function for creating the component, but also have thoughtfully designed and documented HTML markup. * **Configurable using HTML attributes:** Avoid requiring the user to make JavaScript calls to configure the component. Instead, it's better to use HTML attributes. In your component's JavaScript logic, you can [easily access these values using jQuery](http://api.jquery.com/data/#data-html5) (or simply by reading the DOM attribute directly). +### Design the Component + + + +### Write an Input Binding + Each custom input component you design needs an *input binding*, an object you create that tells Shiny how to identify instances of your component and how to interact with it. An input binding object needs to have the following methods:
@@ -74,9 +80,9 @@ Each custom input component you design needs an *input binding*, an object you c

Unsubscribe DOM event listeners that were bound in subscribe.

Example:

-
exampleInputBinding.unsubscribe = function(el) {
+
exampleInputBinding.unsubscribe = function(el) {
   $(el).off(".exampleComponentName");
-};
+};
getRatePolicy() @@ -104,4 +110,62 @@ Each custom input component you design needs an *input binding*, an object you c Rate policies are only applied when the callback function in subscribe is called with true as the first parameter. It's important that input components be able to control which events are rate-limited and which are not, as different events may have different expectations to the user. For example, for a textbox, it would make sense to rate-limit events while the user is typing, but if the user hits Enter or focus leaves the textbox, then the input should always be sent immediately.

-
\ No newline at end of file + + +### Register Input Binding + +``` +Shiny.inputBindings.register(exampleInputBinding); +``` + +### Example + +For this example, we'll create a button that displays a number, whose value increases by one each time the button is clicked. + +

Example:

+

+ ​​​​​​​​​​​​​​​​​​​​​​​ +

+ + +

HTML:

+
<button class="increment btn" type="button">0</button>​​​​​​​​​​​​​​​​​​​​​​​
+

JavaScript:

+
// Non-Shiny-specific code that drives the basic behavior
+
+$(document).on("click", "button.increment", function(evt) {
+  var el = $(evt.target);
+  el.text(parseInt(el.text()) + 1);
+  el.trigger("change");
+});
+
+
+// Shiny-specific binding code
+
+var incrementBinding = new Shiny.InputBinding();
+$.extend(incrementBinding, {
+  find: function(scope) {
+    return $(scope).find(".increment");
+  },
+  getValue: function(el) {
+    return parseInt($(el).text());
+  },
+  setValue: function(el, value) {
+    $(el).text(value);
+  },
+  subscribe: function(el, callback) {
+    $(el).on("change.incrementBinding", function(e) {
+      callback();
+    });
+  },
+  unsubscribe: function(el) {
+    $(el).off(".incrementBinding");
+  }
+});
+
+Shiny.inputBindings.register(incrementBinding);
diff --git a/tutorial/index.html b/tutorial/index.html index ab4d36b9f..69454a56f 100644 --- a/tutorial/index.html +++ b/tutorial/index.html @@ -86,6 +86,8 @@ var hljs=new function(){function m(p){return p.replace(/&/gm,"&").replace(/< hljs.initHighlightingOnLoad(); + + @@ -275,7 +277,6 @@ hljs.initHighlightingOnLoad(); -