Сообщение Sweetalert2 с раскрывающимся списком в R shiny

Как создать версию sweetalert2 сообщения R Shiny с раскрывающимся меню. Я создал довольно много сообщений sweetalert в R Shiny, но для меня это новый тип, и Я застрял на правильном пути, чтобы получить выбор из selectinput внутри сообщения в виде текста, а не числа.

В некоторой степени это работает, но вывод - это номер n-го элемента в списке, а не текстовые строки .....

Исходный пример чистого javascript: пример в разделе select (размещено на внизу этого сообщения.

После созданного мной демонстрационного приложения, которое выводит числа вместо текста, я попробовал следующее: (следуя рабочему решению, которое я создаю в конце на основе этого другого SO вопрос о sweetalerts

myjava <- "shinyjs.swalFromButton = function(params) { 
    var defaultParams = {
title : null,
html : null,
inputOptions: null
};
params = shinyjs.getParams(params, defaultParams);
swal({title : params.title, html : params.html, inputOptions : params.inputOptions,
input: 'select',
inputPlaceholder: 'Select a batchname',
showCancelButton: true,
inputValidator: function(value) {
  return new Promise(function(resolve) {
    if (value === 'Select a batchname') {
      resolve('You need to select a batchname')
    } else {
      resolve()
    }
  })
}
})
.then(function(result){
  if(result.dismiss === swal.DismissReason.cancel) {
  } else {
    Shiny.setInputValue('SweetDropChoice', result.value, {priority: 'event'});
  }
});
};"

Я думаю, что моя проблема в том, что я понятия не имею, как правильно использовать разрешение из примера в моей собственной версии.

Вот приложение для тестирования. Вам нужно будет сменить каталог и загрузить два файла, чтобы sweetalert2 работал здесь: https://www.jsdelivr.com/package/npm/sweetalert2, кнопка загрузки находится справа от заголовка: sweetalert2, а 2 необходимых файла находятся в папке dist папка с именем:

sweetalert2.min.js и sweetalert2.min.css

setwd(PASTE LOCATION WHERE YOU SAVED THE SWEETALERT SCRIPTS)

    library(shiny)
    library(shinyjs)

    myjava <- "shinyjs.swalFromButton = function(params) { 
        var defaultParams = {
    title : null,
    html : null,
    inputOptions: null
    };
    params = shinyjs.getParams(params, defaultParams);
    swal({title : params.title, html : params.html, inputOptions : params.inputOptions,
    input: 'select',
    inputPlaceholder: 'Select a batchname',
    showCancelButton: true})
    .then(function(result){
    if (result.value === 'Select a batchname') {
    resolve('You need to select a batchname:)')
    } else {
    var batchname = result.value
    Shiny.setInputValue('SweetDropChoice', batchname, {priority: 'event'});}
    });
    };"



    ui  <- fluidPage(

      actionButton(inputId = 'messagebutton', label = 'click me'),
      verbatimTextOutput('Choice', placeholder = T),
      shinyjs::useShinyjs(),
      shinyjs::extendShinyjs(text = myjava),
      tags$head(includeScript("sweetalert2.min.js"),
                includeCSS("sweetalert2.min.css")
      )
    )

    server <- function(input, output, session) { 

      values <- reactiveValues(Choice = '?',
                               Choices = rownames(mtcars)[1:6] ## dummy input to use in the sweetalert with dropdown
                               )

      observeEvent(input$messagebutton, { 
        shinyjs::js$swalFromButton( title = paste('<span style ="color:#339FFF;">An alert with a choice'),
                                    html = paste('Pick a name'), 
                                    inputOptions = values$Choices)
      })


      output$Choice <- renderPrint({input$SweetDropChoice})  ## print output of new sweetalert

    }

    shinyApp(ui = ui, server = server)

person Mark    schedule 11.02.2019    source источник
comment
result.value - это индекс выбора? В этом случае я бы попробовал заменить его на inputOptions[result.value].   -  person Stéphane Laurent    schedule 11.02.2019
comment
Привет, Стефан, я почти не понимаю, что в последней части моих двух подходов делают / делают не так. Я только что попробовал var batchname = inputOptions [result.value]; в качестве замены, но это не приводит к выходу вообще   -  person Mark    schedule 11.02.2019
comment
Нет, извините, замените на params.inputOptions[result.value]. Также замените if (result.value === 'Select a batchname') на if (result.value === '').   -  person Stéphane Laurent    schedule 11.02.2019
comment
Хорошо, на полпути. Я был ближе, чем казалось. params.inputOptions работает, и теперь я получаю желаемый вывод текста, но оператор if еще не вызывает красную полосу предупреждения в sweetalert   -  person Mark    schedule 11.02.2019
comment
Да, я только что это проверил. Сообщение об ошибке в Chrome: разрешение не определено. Я посмотрю.   -  person Stéphane Laurent    schedule 11.02.2019
comment
Кстати, мне очень любопытно, как вы это проверяете. Я в значительной степени вслепую, запустив приложение и наблюдая, что происходит, когда я нажимаю на что-то   -  person Mark    schedule 11.02.2019
comment
Например, сразу после .then(function(result){ я поставил console.log(result);. И когда я запускаю приложение, я открываю console в Chrome (Ctrl + Shift + i). Затем я могу видеть объект result в консоли при нажатии кнопки ОК. Консоль тоже показывает ошибки.   -  person Stéphane Laurent    schedule 11.02.2019


Ответы (2)


Вот моя версия. Но, насколько я понимаю, он такой же, как и ваш. За исключением того, что я не включил if(result.dismiss === swal.DismissReason.cancel) (я не уверен, что это правильно, кстати, в result нет поля dismiss).

myjava <- "
shinyjs.swalFromButton = function(params) { 
  var defaultParams = {
    title: null,
    html: null,
    inputOptions: null
  };
  params = shinyjs.getParams(params, defaultParams);
  swal({
    title: params.title, 
    html: params.html, 
    inputOptions: params.inputOptions,
    input: 'select',
    inputPlaceholder: 'Select a batchname',
    showCancelButton: true,
    inputValidator: function(value) {
      return new Promise(function(resolve) {
        if (value !== '') {
          resolve();
        } else {
          resolve('You need to select a batch :)');
        }
      });
    }
  })
  .then(function(result){
    var batchname = params.inputOptions[result.value];
    Shiny.setInputValue('SweetDropChoice', batchname, {priority: 'event'});
  });
};"
person Stéphane Laurent    schedule 11.02.2019
comment
ты прав. На самом деле этого не должно быть (часть увольнения). Разница между вами и мной в том, что я просто копирую и пытаюсь, когда дело доходит до javascript, и вы, вероятно, знаете, что делаете. Я понятия не имею, что именно делает return new Promise (function (resolve) {line и зачем нам это нужно - person Mark; 11.02.2019
comment
Наконец, ваш result.dismiss кажется правильным (здесь есть несколько примеров, sweetalert2.github.io). Честно говоря, я не совсем понимаю, что делаю в Javascript. Я использую несколько примеров и консоль для отладки. Например, я не совсем понимаю Promise. - person Stéphane Laurent; 11.02.2019
comment
Что ж, из нас получается отличная команда, чем несмотря на недостаток знаний, ха-ха. Следующая задача, выяснить, как сдвинуть sweetalert чуть левее в моем приложении с помощью css. - person Mark; 11.02.2019
comment
Спасибо за вклад сегодня, Стефан. и расклад; теги $ head (теги $ style (HTML ('.swal2-modal {left: -440px}'))), похоже, делают это - person Mark; 11.02.2019

@ Стефан Как ни странно, у меня теперь работает другая версия ...

myjava <- "shinyjs.swalFromButton = function(params) { 
    var defaultParams = {
title : null,
html : null,
inputOptions: null
};
params = shinyjs.getParams(params, defaultParams);
swal({title : params.title, html : params.html, inputOptions : params.inputOptions,
input: 'select',
inputPlaceholder: 'Select a batchname',
showCancelButton: true,
inputValidator: function(value) {
return new Promise(function(resolve) {
if (value === '') {
resolve('You need to select a batchname')
} else {
resolve()
}
})
}
})
.then(function(result){
if(result.dismiss === swal.DismissReason.cancel) {
} else {
var batchname = params.inputOptions[result.value];
Shiny.setInputValue('SweetDropChoice', batchname, {priority: 'event'});
}
});
};"
person Mark    schedule 11.02.2019
comment
Я собирался опубликовать ответ ... Да, я также включил это inputValidator, и это работает. - person Stéphane Laurent; 11.02.2019
comment
Давай, опубликуй это. Мне любопытно увидеть различия, и вы заслужили очки репутации за то, что доставили меня туда - person Mark; 11.02.2019