More input binding stuff

This commit is contained in:
Joe Cheng
2012-09-06 16:59:39 -07:00
parent b9f8f28768
commit 1931ce887c
2 changed files with 69 additions and 4 deletions

View File

@@ -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:
<dl>
@@ -74,9 +80,9 @@ Each custom input component you design needs an *input binding*, an object you c
<dd>
<p>Unsubscribe DOM event listeners that were bound in <code>subscribe</code>.</p>
<p>Example:</p>
<pre>exampleInputBinding.unsubscribe = function(el) {
<pre><code class="javascript">exampleInputBinding.unsubscribe = function(el) {
$(el).off(".exampleComponentName");
};</pre>
};</code></pre>
</dd>
<dt>
<code>getRatePolicy()</code>
@@ -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 <code>callback</code> function in <code>subscribe</code> is called with <code>true</code> 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.
</p>
</dd>
</dl>
</dl>
### 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.
<p>Example:</p>
<p>
<button class="increment btn" type="button">0</button>
</p>
<script>
$(document).on("click", "button.increment", function(evt) {
var el = $(evt.target);
el.text(parseInt(el.text()) + 1);
});
</script>
<p>HTML:</p>
<pre><code class="html">&lt;button class="increment btn" type="button">0&lt;/button></code></pre>
<p>JavaScript:</p>
<pre><code class="html">// 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);</code></pre>

View File

@@ -86,6 +86,8 @@ var hljs=new function(){function m(p){return p.replace(/&/gm,"&amp;").replace(/<
hljs.initHighlightingOnLoad();
</script>
<script src="jquery.js"></script>
</head>
<body>
@@ -275,7 +277,6 @@ hljs.initHighlightingOnLoad();
<!-- Placed at the end of the document so the pages load faster -->
<script src="jquery.js"></script>
<script src="jquery.ba-hashchange.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
<script>