Files
shiny/srcjs/input_binding_tabinput.js
Joe Cheng 980a1e53a7 tabsetPanel binding: unconditionally trigger change on receiveMessage
This brings it into line with all of the other input bindings.
The only exception is sliderInput, which has a more complicated
codepath that goes out of its way to force the slider, for its
own reasons; I didn't change the slider for fear of breaking
something, and it also doesn't exhibit the problem I'm here to
fix (next paragraph).

The goal is to ensure that if forgetLastInput is called on an
input, and then that input receives a message (updateXXXInput)
to update its value, BUT the new value is the SAME as its
existing value, that the input binding still acts like something
changed. This is because we need the id/value to go through
the InputSender code path, and alert the server if a previously
frozen input is now thawed.
2020-10-06 14:30:21 -07:00

54 lines
1.6 KiB
JavaScript

var bootstrapTabInputBinding = new InputBinding();
$.extend(bootstrapTabInputBinding, {
find: function(scope) {
return $(scope).find('ul.nav.shiny-tab-input');
},
getValue: function(el) {
var anchor = $(el).find('li:not(.dropdown).active').children('a');
if (anchor.length === 1)
return this._getTabName(anchor);
return null;
},
setValue: function(el, value) {
let self = this;
let success = false;
if (value) {
let anchors = $(el).find('li:not(.dropdown)').children('a');
anchors.each(function() {
if (self._getTabName($(this)) === value) {
$(this).tab('show');
success = true;
return false; // Break out of each()
}
return true;
});
}
if (!success) {
// This is to handle the case where nothing is selected, e.g. the last tab
// was removed using removeTab.
$(el).trigger("change");
}
},
getState: function(el) {
return { value: this.getValue(el) };
},
receiveMessage: function(el, data) {
if (data.hasOwnProperty('value'))
this.setValue(el, data.value);
$(el).trigger("change");
},
subscribe: function(el, callback) {
$(el).on('change shown.bootstrapTabInputBinding shown.bs.tab.bootstrapTabInputBinding', function(event) {
callback();
});
},
unsubscribe: function(el) {
$(el).off('.bootstrapTabInputBinding');
},
_getTabName: function(anchor) {
return anchor.attr('data-value') || anchor.text();
}
});
inputBindings.register(bootstrapTabInputBinding, 'shiny.bootstrapTabInput');