Как получить входные значения с помощью списков?

#html #jquery #r #shiny #shinyjs

#HTML #jquery #r #блестящий #shinyjs

Вопрос:

Я хотел бы использовать двустороннее поле множественного выбора (также известное как списки) в блестящем приложении. Я нашел библиотеку jQuery mutliselect, которая кажется многообещающей: https://crlcu.github.io/multiselect /#. Я создал блестящее приложение с этой библиотекой.

Кажется, он работает хорошо, но ввод отображается только тогда, когда элементы выбраны в правом поле. В идеале я хотел бы, чтобы элементы выбирались сразу после их ввода в нужное поле.

Зависимость jquery можно найти здесь: https://raw.githubusercontent.com/crlcu/multiselect/master/dist/js/multiselect.js

 library(shiny)

# function for make UI HTML
MultiselectHTML <- function(mylist, myname) {
    paste_sum <- ""
    for (i in 1:length(mylist)) {
        paste_sum <- paste0(paste_sum, "<option value=", i, ">", mylist[i], "</option>")
    }
    
    # make tag list
    tagList(div(class = "item_search",
                div(
                    class = "row",
                    div(
                        class = "col-xs-5",
                        tags$select(
                            name = "from[]",
                            id = myname,
                            class = "form-control",
                            multiple = "multiple",
                            size = "8",
                            HTML(paste_sum)
                        )
                    ),
                    div(
                        class = "col-xs-2",
                        tags$button(
                            type = "button",
                            class = "btn btn-primary btn-block",
                            id = paste0(myname, "_undo"),
                            "undo"
                        ),
                        tags$button(
                            type = "button",
                            class = "btn btn-block",
                            id = paste0(myname, "_rightAll"),
                            tags$i(class = "glyphicon glyphicon-forward")
                        ),
                        tags$button(
                            type = "button",
                            class = "btn btn-block",
                            id = paste0(myname, "_rightSelected"),
                            tags$i(class = "glyphicon glyphicon-chevron-right")
                        ),
                        tags$button(
                            type = "button",
                            class = "btn btn-block",
                            id = paste0(myname, "_leftSelected"),
                            tags$i(class = "glyphicon glyphicon-chevron-left")
                        ),
                        tags$button(
                            type = "button",
                            class = "btn btn-block",
                            id = paste0(myname, "_leftAll"),
                            tags$i(class = "glyphicon glyphicon-backward")
                        ),
                        tags$button(
                            type = "button",
                            class = "btn btn-warning btn-block",
                            id = paste0(myname, "_redo"),
                            "redo"
                        )
                    ),
                    div(
                        class = "col-xs-5"
                        ,
                        tags$select(
                            name = "to[]",
                            id = paste0(myname, "_to"),
                            class = "form-control" ,
                            size = "8",
                            multiple = "multiple"
                        )
                    )
                )), 
            br())
}

ui <- fluidPage(
    tags$head(includeScript("www/multiselect.js")),
    tags$script(
        HTML(
            'jQuery(document).ready(function($) {
               $("#multiselect1").multiselect({
                 search: {
                 left: '<input type="text" name="q" class="form-control" placeholder="Search..." />',
                 right: '<input type="text" name="q" class="form-control" placeholder="Search..." />',
                 },
                 fireSearch: function(value) {
                   return value.length >= 1;
                 }
               });
             });
             '
        )
    ),
    MultiselectHTML(c("a", "b", "c", "d", "e"), "multiselect1"),
    uiOutput("mselect")
)

server <- function(input, output, session) {
    output$mselect <- renderUI({
        HTML(paste(
            "multiselect1:",
            paste(input$multiselect1, collapse = ", "),
            "<br>multiselect1_to:",
            paste(input$multiselect1_to, collapse = ", "),
            "<br>q:",
            paste(input$q, collapse = ", ")
        ))
    })
}

shinyApp(ui = ui, server = server)
  

Ответ №1:

Для выбора параметров по умолчанию можно просто добавить selected атрибут к вашему <option> , когда они будут созданы, т.е.

 for (i in 1:length(mylist)) {
    paste_sum <- paste0(paste_sum, "<option selected value=", i, ">", mylist[i], "</option>")
}
  

Для выбора правильных параметров по умолчанию после их перемещения вы можете отредактировать jquery, чтобы добавить selected атрибут к перемещенному параметру, используя:

 $("select option").each(function(){
        $(this).attr("selected","selected");
});
  

Ваш обратный вызов должен иметь новый переход к правильной функциональности. Что-то вроде (взято из документации здесь) :

 tags$script(
    HTML(
        'jQuery(document).ready(function($) {
               $("#multiselect1").multiselect({
                 search: {
                 left: '<input type="text" name="q" class="form-control" placeholder="Search..." />',
                 right: '<input type="text" name="q" class="form-control" placeholder="Search..." />',
                 },
                 fireSearch: function(value) {
                   return value.length >= 1;
                 },
                 moveToRight: function(Multiselect, $options, event, silent, skipStack) {
                    var button = $(event.currentTarget).attr("id");
                    if (button == "multiselect1_rightSelected") {
                        var $left_options = Multiselect.$left.find("> option:selected");
                        Multiselect.$right.eq(0).append($left_options);
                        $("select option").each(function(){$(this).attr("selected","selected");})
                    if ( typeof Multiselect.callbacks.sort == "function" amp;amp; !silent ) {
                        Multiselect.$right.eq(0).find("> option").sort(Multiselect.callbacks.sort).appendTo(Multiselect.$right.eq(0));
                        $("select option").each(function(){$(this).attr("selected","selected");})
                    }
                    } else if (button == "multiselect1_rightAll") {
                        var $left_options = Multiselect.$left.children(":visible");
                        Multiselect.$right.eq(0).append($left_options);
 
                        if ( typeof Multiselect.callbacks.sort == "function" amp;amp; !silent ) {
                            Multiselect.$right.eq(0).find("> option").sort(Multiselect.callbacks.sort).appendTo(Multiselect.$right.eq(0));
                            $("select option").each(function(){$(this).attr("selected","selected");})
                            }
                    }
                    }
                })
             });
             '
    )
)
  

Комментарии:

1. Спасибо за ваш добрый совет. Я не знаком с Java script, но, думаю, мне нужно изучить его, чтобы освоить shiny. Пользовательский интерфейс двух блоков полезен в Shiny, поэтому я изучу код, который вы мне дали.

2. Попробуйте заменить приведенный выше код в разделе tagscript в вашем блестящем приложении для тестирования поведения. Если это работает, пожалуйста, примите это как решенное. Кроме того, возможно, стоит проверить это , если вы не хотите прыгать в кроличью нору JS.