jquery droppable list?

999 views
Skip to first unread message

Vincent Nijs

unread,
Oct 29, 2013, 3:44:30 AM10/29/13
to shiny-...@googlegroups.com
I would like to have a way to (1) create a droppable list and (2) get the ordering of the list items back into Shiny. This could be useful for ordering variables in a data.frame of ordering factor levels. jquery has a nice implementation.


I think I could create the html to show in the main panel and add an id to each list item. However, I have no idea how I would get the the id elements back into Shiny. Any suggestions from the jquery guru's?

ZJ

unread,
Oct 29, 2013, 5:19:09 AM10/29/13
to shiny-...@googlegroups.com
$("ul li").map(function(i,el) {return $(el).text()})

Alex Bokov

unread,
Nov 1, 2013, 6:58:11 AM11/1/13
to shiny-...@googlegroups.com
Doesn't that just print the content of the list? How will the information get returned to shinyServer?

I'm glad this question was asked, because not knowing how to handle user-specified variable-ordering is the main reason I limit my app to accepting only one value for certain types of input where the underlying R function could have accepted multiple values.

Vincent Nijs

unread,
Nov 1, 2013, 7:22:30 PM11/1/13
to shiny-...@googlegroups.com
I took a stab at this. A sortable list is generated based on the column names of a dataframe however I don't know how to get the sort information back to shiny. I included ZJ's suggest in the getValue function but there is clear more to it.

getValue: function(el) {
$("ul li").map(function(i,el) {return $(el).text()})
// return el.value;
},

Code at: https://github.com/mostly-harmless/sortable

shiny::runGitHub("sortable","mostly-harmless")

Alex Bokov

unread,
Nov 4, 2013, 9:26:17 AM11/4/13
to shiny-...@googlegroups.com
Wow, that's cool! That's exactly what I was trying to do. Except of course the part where it gets pushed back into the input object somehow so that an observer can see it :-/.

I suspect that when I wrap my head around this part of the Shiny Tutorial I will understand how to implement that last piece. If I'm the first one to get to that point, I will post the code. Unfortunately, it looks like I have a hefty list of bugs to fix in my app before I can new functionality like this so I probably won't be the one who gets to it first.

Vincent Nijs

unread,
Nov 4, 2013, 6:54:31 PM11/4/13
to shiny-...@googlegroups.com
I have read that part of the tutorial but have not been able to figure this out. There was a post (link below) a while ago on a related topic (i.e., an output binding) but I am not sure he needed to get the order back to Shiny. 

I have two custom bindings that work (mostly with lots of help from this list). I will post those as gists soon and perhaps other can posts theirs as examples for others to learn from.

ZJ

unread,
Nov 4, 2013, 10:32:15 PM11/4/13
to shiny-...@googlegroups.com
https://github.com/xiaodaigh/sortable

shiny::runGitHub("sortable","xiaodaigh")

You need to return something from the getValue that gets sent to R, and to return something you need the return keyword. Just massage your desgired outpu into a form that can be received by R.

Vincent Nijs

unread,
Nov 5, 2013, 12:13:34 AM11/5/13
to shiny-...@googlegroups.com
That is great ZJ! Thanks so much. I will work on your component to make it reorder (1) variables in a data.frame and (2) factor levels.

The main changes you made were to the sort.js file. I have a few questions for you if you don't mind:

1. How did you know to use .ui-sortable in find?
2. What do the last three lines of getValue do? Why isn't hi an array of the li values?
3. For (un)subscribe how did you know to use sortupdate.ui-sortable

If you have any links, references, etc. on where to find out about more about these issues could you post them?

Thanks again ZJ!

ZJ

unread,
Nov 5, 2013, 2:25:40 AM11/5/13
to shiny-...@googlegroups.com
1. How did you know to use .ui-sortable in find?
I use Chrome, so I just right click on the sortable elements and clicked "Inspect element" to find something that can unique identify them. I find the tag containing them was <div ... class="ui-sortable") so I know to use .ui-sortable.
2. What do the last three lines of getValue do? Why isn't hi an array of the li values?
This one I don't understand either. I tried returning hi directly but I got errors. So I added some code to construct an array hii from the values of hi and no more error.
3. For (un)subscribe how did you know to use sortupdate.ui-sortable
I realised you were just using the jquery sortable so I looked up the API 

Vincent Nijs

unread,
Nov 5, 2013, 4:48:11 AM11/5/13
to shiny-...@googlegroups.com
Those answers are very useful to me. Thanks again ZJ!

I tweaked the example a bit. See https://github.com/mostly-harmless/sortable


shiny::runGitHub("sortable","mostly-harmless")

Vincent Nijs

unread,
Nov 5, 2013, 5:08:32 PM11/5/13
to shiny-...@googlegroups.com
The sortable list input should allow multiple such lists in a single app. If I have one input called sortable and another called sortable 2 i am not sure how to specify a function that will assign the sortable behavior to both. I have the below now which works but is not very efficient. 

$(function() {
  $( '#sortable' ).sortable({
    placeholder: 'ui-state-highlight'
  });
  $( '#sortable' ).disableSelection();
}); 

$(function() {
  $( '#sortable2' ).sortable({
    placeholder: 'ui-state-highlight'
  });
  $( '#sortable2' ).disableSelection();
}); 

updated code at 

shiny::runGitHub("sortable","mostly-harmless")

Vincent Nijs

unread,
Nov 5, 2013, 11:15:50 PM11/5/13
to shiny-...@googlegroups.com
Thought I might have found a solution with the function below:

returnOrder <- function(inputId, vars) {
  tagList(
    tags$head(tags$script(paste0("$(function() {$( '#",inputId,"' ).sortable({placeholder: 'ui-state-highlight'}); $( '#",inputId,"' ).disableSelection(); });"))),
    tags$head(tags$script(src = 'js/sort.js')),
    HTML(html_list(vars, inputId))
  )
}

However, I still need to have the following in sort.js. Sorting works without suggesting the first line in the code above is working. However, for some reason the array of colnames is not passed back to Shiny unless the next bit is in sort.js.

$(function() {
  $( '#sortable' ).sortable({
    placeholder: 'ui-state-highlight'
  });
  $( '#sortable' ).disableSelection();
}); 

Vincent Nijs

unread,
Nov 6, 2013, 4:43:44 PM11/6/13
to shiny-...@googlegroups.com
I have the binding working from ui.R but not server.R (i.e., in a renderUI). I had a similar problem some time ago with a binding for select2 which I was not able to resolve. Suggestions?

Vincent Nijs

unread,
Nov 7, 2013, 3:56:03 AM11/7/13
to shiny-...@googlegroups.com
It works!!

Patrick Toche

unread,
Jan 28, 2014, 10:23:04 AM1/28/14
to shiny-...@googlegroups.com
very nice!

very small added value: cursor looks:

      tags$head(
        tags$script(src = "js/jquery-ui.min.js"),
        tags$style(type = "text/css", "#sortable li {cursor:move;}")
      )

Vincent Nijs

unread,
Jan 28, 2014, 1:00:30 PM1/28/14
to shiny-...@googlegroups.com
I added cursor:move to the CSS file. Thanks for the suggestion Patrick.

Sourit Manna

unread,
Jan 10, 2017, 3:27:38 PM1/10/17
to Shiny - Web Framework for R
Hi Vincent, How to change the text color from white to black, the background color from grey to white and horizontal placing, not vertical?
Reply all
Reply to author
Forward
0 new messages