如何使用更新的 UI 在 Shiny 中格式化 numericInput?
How to format the numericInput in Shiny with updated UI?
下面的工作示例是从我之前的问题. Now I want to format the numericInput
field with commas to assist the users to read large numbers. I followed the example of Option 2 from this post "https://beta.rstudioconnect.com/barbara/format-numbers/”中派生出来的,用这种风格改变Total
numericInput
。关键是创建一个.js
文件格式化数字并将其存储在与闪亮脚本相同的文件夹下的 www
目录中。
这与 Total
numericInput 配合使用效果很好。但是,如何对那些更新后添加的 numericINputs
使用相同的格式?挑战是我无法知道稍后会添加多少 numericInput
,因此如果我不知道要添加到该文件的 inpur ID,则很难修改 format_numbers.js
文件。
format_numbers.js
如下
$(document).ready(function() {
// Helper function to guarantee cross-browser compatibility
// adapted from:
function localeString(x, sep, grp) {
var sx = (''+x).split('.'), s = '', i, j;
sep || (sep = ','); // default separator
grp || grp === 0 || (grp = 3); // default grouping
i = sx[0].length;
while (i > grp) {
j = i - grp;
s = sep + sx[0].slice(j, i) + s;
i = j;
}
s = sx[0].slice(0, i) + s;
sx[0] = s;
return sx.join('.');
}
// To change Total's input field (lose arrows and other functionality)
$('#Total')[0].type = 'text';
// To format the number when the app starts up
$('#Total').val(localeString($('#Total').val()));
// To format the number whenever the input changes
$('#Total').keyup(function(event) {
$(this).val(localeString($(this).val().replace(/,/g, '')));
});
});
闪亮脚本如下
library(shiny)
# Define UI
ui <- fluidPage(
# Modify tags
tags$head(tags$script(src = "format_numbers.js")),
# Action button to add numeric input
actionButton("add", "Add UI"),
actionButton("sum", "Sum"),
# Numeric Input
numericInput(inputId = "Total", label = "Total", value = 0),
# Text output
"The number is ",
textOutput(outputId = "out_num", inline = TRUE)
)
# Server logic
server <- function(input, output, session){
# Add numeric input
observeEvent(input$add, {
insertUI(
selector = "#add",
where = "afterEnd",
ui = numericInput(paste0("txt", input$add), label = "Number", value = 0)
)
})
# Reactive values for Total
Num_In <- reactiveValues(
Total_In = 0
)
# Convert number to character
# This is to fill in the Total numeric input formatting with comma
total_num_as_char <- reactive({format(Num_In$Total_In, big.mark = ",", trim = TRUE)})
total_input <- reactive({Num_In$Total_In})
observeEvent(input$sum, {
num_names <- names(input)[grepl("^txt", names(input))]
if (length(num_names) == 0) {
foo <- 0
} else {
foo <- sum(sapply(num_names, function(x) input[[x]]), na.rm = TRUE)
}
Num_In$Total_In <- foo
updateNumericInput(session = session,
inputId = "Total",
value = total_num_as_char())
})
# Convert input to numeric
total_num <- reactive({as.numeric(gsub(",", "", input$Total))})
# Create text output
output$out_num <- renderText({total_num()})
}
# Complete app with UI and server components
shinyApp(ui, server)
对我来说,下面的作品。
当UI组件添加insertUI
时,触发JS事件shiny:bound
。然后我们可以利用它:
// Helper function to guarantee cross-browser compatibility
// adapted from:
function localeString(x, sep, grp) {
var sx = (''+x).split('.'), s = '', i, j;
sep || (sep = ','); // default separator
grp || grp === 0 || (grp = 3); // default grouping
i = sx[0].length;
while (i > grp) {
j = i - grp;
s = sep + sx[0].slice(j, i) + s;
i = j;
}
s = sx[0].slice(0, i) + s;
sx[0] = s;
return sx.join('.');
}
$(document).ready(function() {
// To change Total's input field (lose arrows and other functionality)
$('#Total')[0].type = 'text';
// To format the number when the app starts up
$('#Total').val(localeString($('#Total').val()));
// To format the number whenever the input changes
$('#Total').keyup(function(event) {
$(this).val(localeString($(this).val().replace(/,/g, '')));
});
});
$(document).on('shiny:bound', function(evt){
var id = evt.target.getAttribute('id');
if((/^(txt)/).test(id)){
var selector = '#' + id;
$(selector)[0].type = 'text';
$(selector).val(localeString($(selector).val()));
$(selector).keyup(function(event) {
$(this).val(localeString($(this).val().replace(/,/g, '')));
});
}
});
现在,在 R 中:
unformat <- function(x) as.numeric(gsub(",", "", x))
和
observeEvent(input$sum, {
num_names <- names(input)[grepl("^txt", names(input))]
if (length(num_names) == 0) {
foo <- 0
} else {
foo <- sum(sapply(num_names,
function(x) unformat(input[[x]])), na.rm = TRUE)
}
Num_In$Total_In <- foo
updateNumericInput(session = session,
inputId = "Total",
value = total_num_as_char())
})
下面的工作示例是从我之前的问题numericInput
field with commas to assist the users to read large numbers. I followed the example of Option 2 from this post "https://beta.rstudioconnect.com/barbara/format-numbers/”中派生出来的,用这种风格改变Total
numericInput
。关键是创建一个.js
文件格式化数字并将其存储在与闪亮脚本相同的文件夹下的 www
目录中。
这与 Total
numericInput 配合使用效果很好。但是,如何对那些更新后添加的 numericINputs
使用相同的格式?挑战是我无法知道稍后会添加多少 numericInput
,因此如果我不知道要添加到该文件的 inpur ID,则很难修改 format_numbers.js
文件。
format_numbers.js
如下
$(document).ready(function() {
// Helper function to guarantee cross-browser compatibility
// adapted from:
function localeString(x, sep, grp) {
var sx = (''+x).split('.'), s = '', i, j;
sep || (sep = ','); // default separator
grp || grp === 0 || (grp = 3); // default grouping
i = sx[0].length;
while (i > grp) {
j = i - grp;
s = sep + sx[0].slice(j, i) + s;
i = j;
}
s = sx[0].slice(0, i) + s;
sx[0] = s;
return sx.join('.');
}
// To change Total's input field (lose arrows and other functionality)
$('#Total')[0].type = 'text';
// To format the number when the app starts up
$('#Total').val(localeString($('#Total').val()));
// To format the number whenever the input changes
$('#Total').keyup(function(event) {
$(this).val(localeString($(this).val().replace(/,/g, '')));
});
});
闪亮脚本如下
library(shiny)
# Define UI
ui <- fluidPage(
# Modify tags
tags$head(tags$script(src = "format_numbers.js")),
# Action button to add numeric input
actionButton("add", "Add UI"),
actionButton("sum", "Sum"),
# Numeric Input
numericInput(inputId = "Total", label = "Total", value = 0),
# Text output
"The number is ",
textOutput(outputId = "out_num", inline = TRUE)
)
# Server logic
server <- function(input, output, session){
# Add numeric input
observeEvent(input$add, {
insertUI(
selector = "#add",
where = "afterEnd",
ui = numericInput(paste0("txt", input$add), label = "Number", value = 0)
)
})
# Reactive values for Total
Num_In <- reactiveValues(
Total_In = 0
)
# Convert number to character
# This is to fill in the Total numeric input formatting with comma
total_num_as_char <- reactive({format(Num_In$Total_In, big.mark = ",", trim = TRUE)})
total_input <- reactive({Num_In$Total_In})
observeEvent(input$sum, {
num_names <- names(input)[grepl("^txt", names(input))]
if (length(num_names) == 0) {
foo <- 0
} else {
foo <- sum(sapply(num_names, function(x) input[[x]]), na.rm = TRUE)
}
Num_In$Total_In <- foo
updateNumericInput(session = session,
inputId = "Total",
value = total_num_as_char())
})
# Convert input to numeric
total_num <- reactive({as.numeric(gsub(",", "", input$Total))})
# Create text output
output$out_num <- renderText({total_num()})
}
# Complete app with UI and server components
shinyApp(ui, server)
对我来说,下面的作品。
当UI组件添加insertUI
时,触发JS事件shiny:bound
。然后我们可以利用它:
// Helper function to guarantee cross-browser compatibility
// adapted from:
function localeString(x, sep, grp) {
var sx = (''+x).split('.'), s = '', i, j;
sep || (sep = ','); // default separator
grp || grp === 0 || (grp = 3); // default grouping
i = sx[0].length;
while (i > grp) {
j = i - grp;
s = sep + sx[0].slice(j, i) + s;
i = j;
}
s = sx[0].slice(0, i) + s;
sx[0] = s;
return sx.join('.');
}
$(document).ready(function() {
// To change Total's input field (lose arrows and other functionality)
$('#Total')[0].type = 'text';
// To format the number when the app starts up
$('#Total').val(localeString($('#Total').val()));
// To format the number whenever the input changes
$('#Total').keyup(function(event) {
$(this).val(localeString($(this).val().replace(/,/g, '')));
});
});
$(document).on('shiny:bound', function(evt){
var id = evt.target.getAttribute('id');
if((/^(txt)/).test(id)){
var selector = '#' + id;
$(selector)[0].type = 'text';
$(selector).val(localeString($(selector).val()));
$(selector).keyup(function(event) {
$(this).val(localeString($(this).val().replace(/,/g, '')));
});
}
});
现在,在 R 中:
unformat <- function(x) as.numeric(gsub(",", "", x))
和
observeEvent(input$sum, {
num_names <- names(input)[grepl("^txt", names(input))]
if (length(num_names) == 0) {
foo <- 0
} else {
foo <- sum(sapply(num_names,
function(x) unformat(input[[x]])), na.rm = TRUE)
}
Num_In$Total_In <- foo
updateNumericInput(session = session,
inputId = "Total",
value = total_num_as_char())
})