Files
shiny/srcjs/input_binding_radio.js
colin 770ebc394f updateRadioButton with character(0) (#3043)
Squashed commit of the following:

commit a095d75b67a0bad439e8d6c495ef81af25c0b1a9
Author: Winston Chang <winston@stdout.org>
Date:   Thu Sep 24 10:30:47 2020 -0500

    Update NEWS

commit 715a10ebd63c34eb2f464a7388e0b89b994bee0f
Author: Winston Chang <winston@stdout.org>
Date:   Thu Sep 24 10:24:24 2020 -0500

    Update docs for radioButtons about having none selected

commit eff9036884693002a84f84df16cf699be2358c1c
Author: Winston Chang <winston@stdout.org>
Date:   Thu Sep 24 10:15:59 2020 -0500

    Cleaner check for no selected radioButtons

commit 1666baa746f4dea986be4929720de2a5653acbb6
Merge: c0d35e84 b04ba393
Author: Winston Chang <winston@stdout.org>
Date:   Thu Sep 24 10:02:16 2020 -0500

    Merge branch '2688' of https://github.com/ColinFay/shiny into ColinFay-2688

commit b04ba393b8
Author: colin <colin@thinkr.fr>
Date:   Thu Sep 24 08:37:58 2020 +0200

    changed the test structure

commit 866a86946a
Author: colin <colin@thinkr.fr>
Date:   Sun Sep 13 20:50:44 2020 +0200

    restore old `$escape` behavior

commit d45af353fd
Author: colin <colin@thinkr.fr>
Date:   Fri Sep 11 08:54:25 2020 +0200

    added trailing ; and space before {

commit 5e95ee03a1
Author: colin <colin@thinkr.fr>
Date:   Thu Sep 10 21:55:02 2020 +0200

    return early if the value is undefined in setValue of radio

commit 24ac6ec624
Author: colin <colin@thinkr.fr>
Date:   Thu Sep 10 21:53:41 2020 +0200

    Testing that the type of val is a string, instead of relying on the length

commit 18ec3b8540
Author: colin <colin@thinkr.fr>
Date:   Wed Sep 9 22:08:45 2020 +0200

    Radio buttons can now be reset with character(0), and their value is set to NULL

    Close #2688 and close #2266

commit d7f66165d0
Author: colin <colin@thinkr.fr>
Date:   Wed Sep 9 22:08:06 2020 +0200

    Correct bug when $escape received an empty value
2020-09-24 10:38:12 -05:00

96 lines
3.1 KiB
JavaScript

var radioInputBinding = new InputBinding();
$.extend(radioInputBinding, {
find: function(scope) {
return $(scope).find('.shiny-input-radiogroup');
},
getValue: function(el) {
// Select the radio objects that have name equal to the grouping div's id
var checked_items = $('input:radio[name="' + $escape(el.id) + '"]:checked');
if (checked_items.length === 0) {
// If none are checked, the input will return null (it's the default on load,
// but it wasn't emptied when calling updateRadioButtons with character(0)
return null;
}
return checked_items.val();
},
setValue: function(el, value) {
if ($.isArray(value) && value.length === 0) {
// Removing all checked item if the sent data is empty
$('input:radio[name="' + $escape(el.id) + '"]').prop('checked', false);
} else {
$('input:radio[name="' + $escape(el.id) + '"][value="' + $escape(value) + '"]').prop('checked', true);
}
},
getState: function(el) {
var $objs = $('input:radio[name="' + $escape(el.id) + '"]');
// Store options in an array of objects, each with with value and label
var options = new Array($objs.length);
for (var i = 0; i < options.length; i++) {
options[i] = { value: $objs[i].value,
label: this._getLabel($objs[i]) };
}
return {
label: this._getLabelNode(el).text(),
value: this.getValue(el),
options: options
};
},
receiveMessage: function(el, data) {
var $el = $(el);
// This will replace all the options
if (data.hasOwnProperty('options')) {
// Clear existing options and add each new one
$el.find('div.shiny-options-group').remove();
// Backward compatibility: for HTML generated by shinybootstrap2 package
$el.find('label.radio').remove();
$el.append(data.options);
}
if (data.hasOwnProperty('value'))
this.setValue(el, data.value);
updateLabel(data.label, this._getLabelNode(el));
$(el).trigger('change');
},
subscribe: function(el, callback) {
$(el).on('change.radioInputBinding', function(event) {
callback();
});
},
unsubscribe: function(el) {
$(el).off('.radioInputBinding');
},
// Get the DOM element that contains the top-level label
_getLabelNode: function(el) {
return $(el).parent().find('label[for="' + $escape(el.id) + '"]');
},
// Given an input DOM object, get the associated label. Handles labels
// that wrap the input as well as labels associated with 'for' attribute.
_getLabel: function(obj) {
// If <label><input /><span>label text</span></label>
if (obj.parentNode.tagName === "LABEL") {
return $(obj.parentNode).find('span').text().trim();
}
return null;
},
// Given an input DOM object, set the associated label. Handles labels
// that wrap the input as well as labels associated with 'for' attribute.
_setLabel: function(obj, value) {
// If <label><input /><span>label text</span></label>
if (obj.parentNode.tagName === "LABEL") {
$(obj.parentNode).find('span').text(value);
}
return null;
}
});
inputBindings.register(radioInputBinding, 'shiny.radioInput');