Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add binding and el fields to shiny:inputchanged event #1596

Merged
merged 18 commits into from Mar 3, 2017
Merged

Conversation

wch
Copy link
Collaborator

@wch wch commented Feb 27, 2017

With this PR, the shiny:inputchanged JavaScript event gets two new fields, binding and el, which contain the input binding and DOM element, respectively. Additionally, Shiny.onInputChange() now accepts an optional argument, opts, which can contain the same fields.

@wch wch added the review label Feb 27, 2017
@jcheng5
Copy link
Member

jcheng5 commented Feb 28, 2017

I'd prefer to walk through this PR together.

@@ -128,7 +136,13 @@ function initShiny() {

var type = binding.getType(el);
var effectiveId = type ? id + ":" + type : id;
currentValues[effectiveId] = binding.getValue(el);
inputItems[effectiveId] = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From discussion, it seems like the behavior we have today would cause immediate=FALSE when the exported bindAll is called. Please follow up to see if indeed immediate=FALSE. In any case we want this to be immediate going forward.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #1595 (commit 0ef15fa) removed the following code in bindInputs because we thought it was redundant:

        if (shinyapp.isConnected()) {
          valueChangeCallback(binding, el, false);
        }

It turns out that the false in this call is important, and wasn't being used in the other call to inputs.setInput from exports.bindAll. So we'll need to need to make sure that the value of immediate is set properly here.

var InputEventDecorator = function(target) {
this.target = target;
};
(function() {
this.setInput = function(name, value, immediate) {
this.setInput = function(name, value, opts) {
opts = Object.assign({
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to have a global default options object instead of creating it each time.

var InputRateDecorator = function(target) {
this.target = target;
this.inputRatePolicies = {};
};
(function() {
this.setInput = function(name, value, immediate) {
this.setInput = function(name, value, opts) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of checking opts at each level of input decorator, it would be cleaner to add another level, like inputValidatorDecorator to the top of the stack, which checks that name isn't null, the opts are valid, and so on.

@@ -29,7 +32,10 @@ var ShinyApp = function() {

$.extend(initialInput, {
// IE8 and IE9 have some limitations with data URIs
".clientdata_allowDataUriScheme": typeof WebSocket !== 'undefined'
".clientdata_allowDataUriScheme": {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be moved init_shiny.

@@ -4,6 +4,9 @@ var ShinyApp = function() {
// Cached input values
this.$inputValues = {};

// Input values at initialization (and reconnect)
this.$initialInput = {};
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.$initialInput and this$inputValues should not keep opts, because it would prevent the el from being garbage collected. The opts are only used in the input decorator stack; there's no need to keep them outside of that.


var inputs = inputsValidate;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Total nitpick but I would've had var inputs above the if/else block, and have inputs = inputsRate and inputs = inputsDefer as before, and then after the if/else block, inputs = new InputValidateDecorator(inputs).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I can make that change.

@wch wch merged commit 4264760 into master Mar 3, 2017
@wch wch deleted the wch/setinput-binding branch March 3, 2017 21:27
@wch wch removed the review label Mar 3, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants