rstudio / sortable

R htmlwidget for Sortable.js
https://rstudio.github.io/sortable/
Other
127 stars 30 forks source link

Rename buckets in bucket list (feature proposition) #84

Closed gregleleu closed 1 year ago

gregleleu commented 2 years ago

Hi, I'd like to be able to rename the rank lists in a bucket list. I had the approach below in mind, does it make sense?

  1. add a update_rank_list_label(inputId, text) in R that sends a message to shiny (sendCustomMessage)
  2. create a script with a Shiny.customMessageHandler which finds the text element and updates it, and find a place where this script would be loaded (in bucket_list I guess?)

We could also add the option in add_rank_list to put a button to the right of the label with its own icon/text and input id, to be clicked to call update_rank_list_label (or any other function) through an observeEvent

yogat3ch commented 1 year ago

This is a hacky workaround for updating the labels on the sortable widget with shinyjs because I'm not entirely sure how to make a fully functional update method, but it may be of use to others.

 # Make new options HTML
      .sortable_items <- htmltools::doRenderTags(purrr::map(axes_order(), ~tags$div(class = "rank-list-item", .x))) |>
        glue::glue_collapse(sep = "\n")
      # Replace the HTML for the sortable widget
      shinyjs::runjs(
        UU::glue_js(
          "$('#*{ns('axes_order')}* .rank-list').html(`*{.sortable_items}*`)"
        )
      )
      # Update the input values for the sortable
      shinyjs::runjs(shinyVirga::js_set_input_val('axes_order', value = jsonlite::toJSON(axes_order())))

Three primary steps where axes_order() is a reactive that returns a vector of character strings that would typically be passed to label

  1. Make the HTML to replace the divs with class rank-list-item in the sortable widget.

    .sortable_items <- htmltools::doRenderTags(purrr::map(axes_order(), ~tags$div(class = "rank-list-item", .x))) |>
        glue::glue_collapse(sep = "\n")
  2. Replace the options for the sortable widget (supplied by the label argument) using shinyjs.

     shinyjs::runjs(
        UU::glue_js(
          "$('#*{ns('axes_order')}* .rank-list').html(`*{.sortable_items}*`)"
        )
      )

    The actual js from the glue_js looks as follows (note the html quoted with `):

    $('#body-robustness-parallel-axes_order .rank-list').html(`<div class="rank-list-item">% trcs robust</div>
    <div class="rank-list-item">% trcs robust cond. 1</div>`)
  3. Update the input values for the sortable widget to match the label options:

    shinyjs::runjs(shinyVirga::js_set_input_val('axes_order', value = jsonlite::toJSON(axes_order())))

    The js produced by the js_set_input_val convenience function looks like this:

    Shiny.setInputValue('body-robustness-parallel-axes_order', ["% trcs robust","% trcs robust cond. 1"], {priority: 'event'});
andrie commented 1 year ago

I think this is a general question on how to code a specific thing in a Shiny app, and not specifically related to the sortable package.

gregleleu commented 1 year ago

@andrie This was actually a proposition to make a PR, but you're apparently not interested

andrie commented 1 year ago

I'm sorry, I misunderstood.

Can you please describe a bit more what the use case is that you have in mind? Why would you want to dynamically rename a bucket list? How is this different than renaming any other element in a shiny app? And why should this functionality be in the sortable package?

gregleleu commented 1 year ago

I worked on an app where we were creating regions and putting items in the regions using sortable to drag and drop the items. However the names of the regions were not fixed, they depended on the items (e.g. "the big region on the left", "the small region around Munich"), hence the need to update the names of the buckets from the app.

You can't just "rename" any element in Shiny, you need to rely on update_* functions by input type. And there isn't one for the bucket labels.

This should be in the sortable package because it would add update capabilities to input types created by the sortable package.

We ended up re-rendering the bucketlist when the labels changed.

andrie commented 1 year ago

I've made a start by allowing updating the text of a rank_list() in #93

andrie commented 1 year ago

This is now merged into the main branch.

Use update_rank_list() and/or update_bucket_list()