Skip to content

Commit

Permalink
Add disabled argument to actionButton and updateActionButton
Browse files Browse the repository at this point in the history
  • Loading branch information
jcheng5 committed Dec 12, 2023
1 parent 4b6e257 commit 33dc41c
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 48 deletions.
6 changes: 5 additions & 1 deletion R/input-action.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#' @param label The contents of the button or link--usually a text label, but
#' you could also use any other HTML, like an image.
#' @param icon An optional [icon()] to appear on the button.
#' @param disabled If `TRUE`, the button will not be clickable. Use
#' [updateActionButton()] to dynamically enable/disable the button.
#' @param ... Named attributes to be applied to the button or link.
#'
#' @family input elements
Expand Down Expand Up @@ -49,7 +51,8 @@
#' * Event handlers (e.g., [observeEvent()], [eventReactive()]) won't execute on initial load.
#' * Input validation (e.g., [req()], [need()]) will fail on initial load.
#' @export
actionButton <- function(inputId, label, icon = NULL, width = NULL, ...) {
actionButton <- function(inputId, label, icon = NULL, width = NULL,
disabled = FALSE, ...) {

value <- restoreInput(id = inputId, default = NULL)

Expand All @@ -58,6 +61,7 @@ actionButton <- function(inputId, label, icon = NULL, width = NULL, ...) {
type="button",
class="btn btn-default action-button",
`data-val` = value,
disabled = if (isTRUE(disabled)) NA else NULL,
list(validateIcon(icon), label),
...
)
Expand Down
10 changes: 7 additions & 3 deletions R/update-input.R
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ updateCheckboxInput <- function(session = getDefaultReactiveDomain(), inputId, l
#' Change the label or icon of an action button on the client
#'
#' @template update-input
#' @param disabled If `TRUE`, the button will not be clickable; if `FALSE`, it
#' will be.
#' @inheritParams actionButton
#'
#' @seealso [actionButton()]
Expand Down Expand Up @@ -169,16 +171,18 @@ updateCheckboxInput <- function(session = getDefaultReactiveDomain(), inputId, l
#' }
#' @rdname updateActionButton
#' @export
updateActionButton <- function(session = getDefaultReactiveDomain(), inputId, label = NULL, icon = NULL) {
updateActionButton <- function(session = getDefaultReactiveDomain(), inputId, label = NULL, icon = NULL, disabled = NULL) {
validate_session_object(session)

if (!is.null(icon)) icon <- as.character(validateIcon(icon))
message <- dropNulls(list(label=label, icon=icon))
message <- dropNulls(list(label=label, icon=icon, disabled=disabled))
session$sendInputMessage(inputId, message)
}
#' @rdname updateActionButton
#' @export
updateActionLink <- updateActionButton
updateActionLink <- function(session = getDefaultReactiveDomain(), inputId, label = NULL, icon = NULL) {
updateActionButton(session, inputId=inputId, label=label, icon=icon)
}


#' Change the value of a date input on the client
Expand Down
35 changes: 22 additions & 13 deletions inst/www/shared/shiny.js
Original file line number Diff line number Diff line change
Expand Up @@ -9970,22 +9970,31 @@
key: "receiveMessage",
value: function receiveMessage(el, data) {
var $el = (0, import_jquery16.default)(el);
var label = $el.text();
var icon = "";
if ($el.find("i[class]").length > 0) {
var iconHtml = $el.find("i[class]")[0];
if (iconHtml === $el.children()[0]) {
icon = (0, import_jquery16.default)(iconHtml).prop("outerHTML");
if (hasDefinedProperty(data, "label") || hasDefinedProperty(data, "icon")) {
var label = $el.text();
var icon = "";
if ($el.find("i[class]").length > 0) {
var iconHtml = $el.find("i[class]")[0];
if (iconHtml === $el.children()[0]) {
icon = (0, import_jquery16.default)(iconHtml).prop("outerHTML");
}
}
if (hasDefinedProperty(data, "label")) {
label = data.label;
}
if (hasDefinedProperty(data, "icon")) {
var _data$icon;
icon = Array.isArray(data.icon) ? "" : (_data$icon = data.icon) !== null && _data$icon !== void 0 ? _data$icon : "";
}
$el.html(icon + " " + label);
}
if (hasDefinedProperty(data, "label")) {
label = data.label;
}
if (hasDefinedProperty(data, "icon")) {
var _data$icon;
icon = Array.isArray(data.icon) ? "" : (_data$icon = data.icon) !== null && _data$icon !== void 0 ? _data$icon : "";
if (hasDefinedProperty(data, "disabled")) {
if (data.disabled) {
$el.attr("disabled", "");
} else {
$el.attr("disabled", null);
}
}
$el.html(icon + " " + label);
}
}, {
key: "unsubscribe",
Expand Down
4 changes: 2 additions & 2 deletions inst/www/shared/shiny.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion inst/www/shared/shiny.min.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions inst/www/shared/shiny.min.js.map

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion man/actionButton.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion man/updateActionButton.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 37 additions & 23 deletions srcts/src/bindings/input/actionbutton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import $ from "jquery";
import { hasDefinedProperty } from "../../utils";
import { InputBinding } from "./inputBinding";

type ActionButtonReceiveMessageData = { label?: string; icon?: string | [] };
type ActionButtonReceiveMessageData = {
label?: string;
icon?: string | [];
disabled?: boolean;
};

class ActionButtonInputBinding extends InputBinding {
find(scope: HTMLElement): JQuery<HTMLElement> {
Expand Down Expand Up @@ -38,34 +42,44 @@ class ActionButtonInputBinding extends InputBinding {
receiveMessage(el: HTMLElement, data: ActionButtonReceiveMessageData): void {
const $el = $(el);

// retrieve current label and icon
let label: string = $el.text();
let icon = "";
if (hasDefinedProperty(data, "label") || hasDefinedProperty(data, "icon")) {
// retrieve current label and icon
let label: string = $el.text();
let icon = "";

// to check (and store) the previous icon, we look for a $el child
// object that has an i tag, and some (any) class (this prevents
// italicized text - which has an i tag but, usually, no class -
// from being mistakenly selected)
if ($el.find("i[class]").length > 0) {
const iconHtml = $el.find("i[class]")[0];
// to check (and store) the previous icon, we look for a $el child
// object that has an i tag, and some (any) class (this prevents
// italicized text - which has an i tag but, usually, no class -
// from being mistakenly selected)
if ($el.find("i[class]").length > 0) {
const iconHtml = $el.find("i[class]")[0];

if (iconHtml === $el.children()[0]) {
// another check for robustness
icon = $(iconHtml).prop("outerHTML");
if (iconHtml === $el.children()[0]) {
// another check for robustness
icon = $(iconHtml).prop("outerHTML");
}
}
}

// update the requested properties
if (hasDefinedProperty(data, "label")) {
label = data.label;
}
if (hasDefinedProperty(data, "icon")) {
// `data.icon` can be an [] if user gave `character(0)`.
icon = Array.isArray(data.icon) ? "" : data.icon ?? "";
// update the requested properties
if (hasDefinedProperty(data, "label")) {
label = data.label;
}
if (hasDefinedProperty(data, "icon")) {
// `data.icon` can be an [] if user gave `character(0)`.
icon = Array.isArray(data.icon) ? "" : data.icon ?? "";
}

// produce new html
$el.html(icon + " " + label);
}

// produce new html
$el.html(icon + " " + label);
if (hasDefinedProperty(data, "disabled")) {
if (data.disabled) {
$el.attr("disabled", "");
} else {
$el.attr("disabled", null);
}
}
}

unsubscribe(el: HTMLElement): void {
Expand Down
1 change: 1 addition & 0 deletions srcts/types/src/bindings/input/actionbutton.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { InputBinding } from "./inputBinding";
type ActionButtonReceiveMessageData = {
label?: string;
icon?: string | [];
disabled?: boolean;
};
declare class ActionButtonInputBinding extends InputBinding {
find(scope: HTMLElement): JQuery<HTMLElement>;
Expand Down

0 comments on commit 33dc41c

Please sign in to comment.