Problem with updateSelectInput

2,072 views
Skip to first unread message

Basti Hoffmeister

unread,
Jun 11, 2013, 1:50:59 PM6/11/13
to shiny-...@googlegroups.com
Hey I'm trying to set the selected value of a selectInput based on a url-parameter.

Sadly it fails all the time, saying: Error: attempt to set an attribute on NULL

Here is what i try to do in server.R:
...
  output$out = renderText({
    query <- parseQueryString(session$clientData$url_search)
    updateSelectInput(session=session, inputId="kurs", selected=c("DX1"))
    ""
    })
...

I'm not using the ui.R version but HTML. The corresponding part in the index.html is:

...
<table width="640px">
  <tr>
    <td><label for="kurs">Kurs:</label></td>
    <td>
      <select name="kurs" style="width: 150px">
        <option value="NA">...</option>
        <option value="DX1">Design Expert: Versuchsplanung</option>
      </select>
    </td>
  </tr>
...

I'm using several other inputs (mainly slider + textInput) and for them it's no problem to update the values using updateTextInput ...

I would be thankful for any hint,
Sebastian

Winston Chang

unread,
Jun 11, 2013, 2:33:41 PM6/11/13
to shiny-...@googlegroups.com
Hi - did you write the HTML prior to Shiny 0.6.0? The reason I ask is because there have been some small changes to the HTML generated by some of the *Input functions, in order to make things work more consistently and reliably.

For example, here's how to see the HTML generated from a selectInput:
> cat(format(selectInput('inputid', 'Label', choices = c(a="A", b="B"), selected = "b")))
<label class="control-label" for="inputid">Label</label>
<select id="inputid">
  <option value="A">a</option>
  <option value="B" selected="selected">b</option>
</select>


I suggest modifying your HTML to match this structure, and then see if the updating works.

-Winston




--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Basti Hoffmeister

unread,
Jun 14, 2013, 4:24:20 AM6/14/13
to shiny-...@googlegroups.com
Hi Winston,

I updated my code but it still does not work.

Here is a minimal reproducible example:

INDEX.HTML
<html>  
  <head>  
  <script src="shared/jquery.js" type="text/javascript"></script>
  <script src="shared/shiny.js" type="text/javascript"></script>
  <link rel="stylesheet" type="text/css" href="shared/shiny.css"/> 
  </head>
  <body>
    <pre id="out" class="shiny-text-output"></pre>     
    <label class="control-label" for="myselection">Select smth.</label>
    <select id="myselection">
      <option value="a">Select A</option>
      <option value="b" selected="selected">Select B</option>
    </select>
  </body>

server.R
library(shiny)

shinyServer(function(input, output, session) {

  output$out = renderText({
    query <- parseQueryString(session$clientData$url_search)
    updateSelectInput(session=session, inputId="myselection", selected="a")
    ""
  })
})


Would be great if some1 has a solution for that.

Thanks,
Sebastian

Winston Chang

unread,
Jun 14, 2013, 11:23:30 AM6/14/13
to shiny-...@googlegroups.com
Hm, it looks like that might be a bug - it appears that it also requires sending all the choices. I've filed it at https://github.com/rstudio/shiny/issues/176


You can do something like this:

shinyServer(function(input, output, session) {
  observe({
    updateSelectInput(session = session, inputId = "myselection",
      choices = c("Choice A" = "a", "Choice B" = "b"),
      selected = "Choice B")
  })
})

Basti Hoffmeister

unread,
Jun 17, 2013, 4:54:28 AM6/17/13
to shiny-...@googlegroups.com
Hi Winston, 

thank you for this solution. It works as it should now.

Sebastian

Alex Bokov

unread,
Oct 24, 2013, 10:09:44 AM10/24/13
to shiny-...@googlegroups.com
I have just run into this bug as well. The problem with the suggested workaround is that it relies on having the values for choices accessible to server.R. This introduces unnecessary overhead and redundancy if you don't need to alter the choices, all you need to do is change which choice is selected. This is especially a problem if your selectInput() widgets are static HTML or (were) contained entirely in ui.R.

I notice that at the end of the updateSelectInput() function, there is the following line:

session$sendInputMessage(inputId,message);

inputId is the same as the argument to updateSelectInput() and message is an object with the following structure:

List of 1
 $ options:List of 2
  ..$ :List of 3
  .. ..$ value   : chr "x"
  .. ..$ label   : chr "x"
  .. ..$ selected: logi FALSE
  ..$ :List of 3
  .. ..$ value   : chr "y"
  .. ..$ label   : chr "y"
  .. ..$ selected: logi FALSE

...where options is an un-named list that can contain an arbitrary number of these triplets. Experimenting has revealed that if I manually use session$sendInputMessage with a message whose options only include the selections I want to update, the target list gets updated such that those become the only choices. Does this mean that bug #176 actually runs deeper than updateSelectInput and is caused by whatever is listening to sendInputMessage having to rewrite the entire selectInput if any part of it is updated?

Yihui Xie

unread,
Jan 12, 2014, 2:38:53 PM1/12/14
to Alex Bokov, shiny-discuss
Hi,

I think we have solved both the original problem reported by Basti
Hoffmeister and the problem you mentioned (unable to update the
`selected` argument only) through
https://github.com/rstudio/shiny/pull/340 Please test the development
version https://github.com/rstudio/shiny/

Please also note these two items in NEWS:
https://github.com/rstudio/shiny/blob/master/NEWS

* The argument `selected` in checkboxGroupInput(), selectInput(), and
radioButtons() refers to the value(s) instead of the name(s) of the
argument `choices` now. For example, the value of the `selected` argument
in selectInput(..., choices = c('Label 1' = 'x1', 'Label 2' = 'x2'),
selected = 'Label 2') must be updated to 'x2', although names/labels will
be automatically converted to values internally for backward
compatibility. The same change applies to updateCheckboxGroupInput(),
updateSelectInput(), and updateRadioButtons() as well. (#340)

* Now it is possible to only update the value of a checkbox group, select input,
or radio buttons using the `selected` argument without providing the
`choices` argument in updateCheckboxGroupInput(), updateSelectInput(), and
updateRadioButtons(), respectively. (#340)


Regards,
Yihui

Nicholas Crookston

unread,
Jun 12, 2014, 6:58:45 PM6/12/14
to shiny-...@googlegroups.com, alex....@gmail.com
Hi everyone: 

The way the html code is generated seems reversed to me. It seems like I'm must not understand what you mean by "value". I'm also not sure my point is exactly related to this thread, but please reply nonetheless.

Before I get started, these examples were run using shiny_0.9.1.9015

What I want is to display several long strings in a multiple selection 
box. When a specific element is selected, I want the "name" of the 
selected list element(s) returned in output object, not the 
"displayed strings".

For example, consider this named list: 
[Note that the names could be a row numbers in a (perhaps large) table; 
I'd rather not have to do string matches on all the elements to find which 
row(s) were selected):

theChoices <- 
  list(c1 = "Long string describing choice 1",
       c2 = "Long string describing choice 2", 
       c3 = "Long string describing choice 3")

selectInput(inputId="test",label="testLabel",
            choices=theChoices,selectize=FALSE)
            
This html code is created:

<label class="control-label" for="test">testLabel</label>
  <select id="test">
    <option value="Long string describing choice 1" selected>c1</option>
    <option value="Long string describing choice 2">c2</option>
    <option value="Long string describing choice 3">c3</option></select>

The UI does not display the long strings (what one would want), 
it displays the names of the list elements, that is c1, c2, and c3.

It seems to me that when a named list is used, the html code should look like
this:

<label class="control-label" for="test">testLabel</label>
  <select id="test">
    <option value="c1" selected>Long string describing choice 1</option>
    <option value="c2">Long string describing choice 2</option>
    <option value="c3">Long string describing choice 3</option></select>
    
In this case, the long strings are displayed, and when one of the items
is selected by the user, the "values" are returned (ie, c1, c2,...), 
not the long string. 

To get what I want, I've had to duplicate my otherwise well organized lists, 
reversing the names and the values, like this:

reverseNamed <- names(theChoices)
names(reverseNamed) <- theChoices

selectInput(inputId="test3",label="test3Label",
            choices=reverseNamed,selectize=FALSE)

Which yields:

<label class="control-label" for="test3">test3Label</label>
<select id="test3">
  <option value="c1" selected>Long string describing choice 1</option>
  <option value="c2">Long string describing choice 2</option>
  <option value="c3">Long string describing choice 3</option></select> 

=========== 
Is this a bug or am I missing something important that everyone
else "gets with ease!". If the behavior is changed in shiny, I'll be
happy to modify my code to match.

Thanks, Nick Crookston

Joe Cheng

unread,
Jun 12, 2014, 7:34:04 PM6/12/14
to Nicholas Crookston, shiny-...@googlegroups.com, Alex Bokov
You should define theChoices like this:

theChoices <- 
  list("Long string describing choice 1" = "c1",
       "Long string describing choice 2" = "c2", 
       "Long string describing choice 3" = "c3")



--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages