This function implements the parsons problem, as exposed by question_parsons(). Most users will only use this function inside a learnr tutorial, so please see the documentation at question_parsons()

parsons_problem(initial, text = c("Drag from here",
  "Construct your solution here"), header = NULL, input_id, group_name,
  problem_type = c("base", "ggplot2", "tidyverse"),
  class = "default-sortable default-parsons",
  options = sortable_options(), orientation = c("horizontal",
  "vertical"))

Arguments

initial

Vector with initial values for problem (to appear in left column). Note: this must be a super-set of all answers.

text

Vector of headings for each column.

header

Text that appears at the top of the bucket list. (This is encoded as an HTML <p> tag, so not strictly speaking a header.)

input_id

Character vector of input_id to pass (individually) to rank_list().

group_name

Passed to SortableJS as the group name. Also the input value set in Shiny. (input[[group_name]])

problem_type

One of base, ggplot2 or tidyverse, indicating the type of problem statement. For tidyverse, the resulting answer will automatically append a %>% at the end of each answer, and for ggplot2 every line will be followed by a +.

class

A css class applied to the rank list. This can be used to define custom styling.

options

Options to be supplied to sortable_js object. See sortable_options for more details

orientation

Either horizontal or vertical, and specifies the layout of the components on the page.

References

https://js-parsons.github.io/

Examples

## Example of a shiny app if (interactive()) { app <- system.file("shiny-examples/parsons_app.R", package = "parsons") shiny::runApp(app) } ## -- example-parsons ----------------------------------------------------- ## Parson's problem parsons_problem( header = "This is an example of a Parsons problem", text = c("Drag from here", "Construct your solution here"), initial = c( "iris", "mutate(...)", "summarize(...)", "print()" ), input_id = "input_parsons" )
#> <div class="bucket-list-container default-sortable default-parsons"> #> <p>This is an example of a Parsons problem</p> #> <div class="default-sortable default-parsons bucket-list bucket-list-horizontal"> #> <div class="rank-list-container default-sortable default-parsons column_1"> #> <p class="rank-list-title">Drag from here</p> #> <div class="rank-list" id="rank_list_id_1"> #> <div class="rank-list-item"> #> <div class="rank-list-item-internal base">iris</div> #> </div> #> <div class="rank-list-item"> #> <div class="rank-list-item-internal base">mutate(...)</div> #> </div> #> <div class="rank-list-item"> #> <div class="rank-list-item-internal base">summarize(...)</div> #> </div> #> <div class="rank-list-item"> #> <div class="rank-list-item-internal base">print()</div> #> </div> #> </div> #> </div> #> <div id="htmlwidget-ac96cb3ee4656e2e9ec3" style="width:0px;height:0px;" class="sortable html-widget"></div> #> <script type="application/json" data-for="htmlwidget-ac96cb3ee4656e2e9ec3">{"x":{"css_id":"rank_list_id_1","options":{"animation":150,"emptyInsertThreshold":12.5,"group":"parsons_group_1","onLoad":"function() {\n try {\n (function(evt) {\n if (typeof Shiny == \"undefined\") {\n return;\n }\n\n var child_id_or_text_fn = function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);};\n\n var ret = {}, i;\n var css_ids = [\"rank_list_id_1\",\"rank_list_id_2\"];\n var input_ids = [\"input_parsons_1\",\"input_parsons\"];\n\n $.map(css_ids, function(css_id, i) {\n var input_id = input_ids[i];\n var item = $('#' + css_id).get(0);\n if (item && item.children) {\n ret[input_id] = $.map(item.children, child_id_or_text_fn);\n } else {\n ret[input_id] = undefined;\n }\n });\n Shiny.setInputValue(\"parsons_group_1:sortablejs.bucket_list\", ret)\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n\n try {\n (function(evt) {\n if (typeof Shiny !== \"undefined\") {\n Shiny.setInputValue(\"input_parsons_1:sortablejs.rank_list\", $.map( this.el.children, function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);}))\n }\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n\n try {\n (function(evt) {\n var css_ids = [\"rank_list_id_1\"];\n setTimeout(function() {\n css_ids.map(function(id) {\n var el = window.document.getElementById(id);\n if (el) {\n Sortable.utils.toggleClass(el, 'rank-list-empty', el.children.length == 0);\n }\n })\n }, 0);\n }).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n}","onSort":"function() {\n try {\n (function(evt) {\n if (typeof Shiny == \"undefined\") {\n return;\n }\n\n var child_id_or_text_fn = function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);};\n\n var ret = {}, i;\n var css_ids = [\"rank_list_id_1\",\"rank_list_id_2\"];\n var input_ids = [\"input_parsons_1\",\"input_parsons\"];\n\n $.map(css_ids, function(css_id, i) {\n var input_id = input_ids[i];\n var item = $('#' + css_id).get(0);\n if (item && item.children) {\n ret[input_id] = $.map(item.children, child_id_or_text_fn);\n } else {\n ret[input_id] = undefined;\n }\n });\n Shiny.setInputValue(\"parsons_group_1:sortablejs.bucket_list\", ret)\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n\n try {\n (function(evt) {\n if (typeof Shiny !== \"undefined\") {\n Shiny.setInputValue(\"input_parsons_1:sortablejs.rank_list\", $.map( this.el.children, function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);}))\n }\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n}","onMove":"function(evt) {\n var css_ids = [\"rank_list_id_1\",\"rank_list_id_2\"];\n setTimeout(function() {\n css_ids.map(function(id) {\n var el = window.document.getElementById(id);\n if (el) {\n Sortable.utils.toggleClass(el, 'rank-list-empty', el.children.length == 0);\n }\n })\n }, 0);\n }"}},"evals":["options.onLoad","options.onSort","options.onMove"],"jsHooks":[]}</script> #> <div class="rank-list-container default-sortable default-parsons column_2"> #> <p class="rank-list-title">Construct your solution here</p> #> <div class="rank-list" id="rank_list_id_2"></div> #> </div> #> <div id="htmlwidget-e5c8c404fe174e4c81bd" style="width:0px;height:0px;" class="sortable html-widget"></div> #> <script type="application/json" data-for="htmlwidget-e5c8c404fe174e4c81bd">{"x":{"css_id":"rank_list_id_2","options":{"animation":150,"emptyInsertThreshold":12.5,"group":"parsons_group_1","onLoad":"function() {\n try {\n (function(evt) {\n if (typeof Shiny == \"undefined\") {\n return;\n }\n\n var child_id_or_text_fn = function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);};\n\n var ret = {}, i;\n var css_ids = [\"rank_list_id_1\",\"rank_list_id_2\"];\n var input_ids = [\"input_parsons_1\",\"input_parsons\"];\n\n $.map(css_ids, function(css_id, i) {\n var input_id = input_ids[i];\n var item = $('#' + css_id).get(0);\n if (item && item.children) {\n ret[input_id] = $.map(item.children, child_id_or_text_fn);\n } else {\n ret[input_id] = undefined;\n }\n });\n Shiny.setInputValue(\"parsons_group_1:sortablejs.bucket_list\", ret)\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n\n try {\n (function(evt) {\n if (typeof Shiny !== \"undefined\") {\n Shiny.setInputValue(\"input_parsons:sortablejs.rank_list\", $.map( this.el.children, function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);}))\n }\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n\n try {\n (function(evt) {\n var css_ids = [\"rank_list_id_2\"];\n setTimeout(function() {\n css_ids.map(function(id) {\n var el = window.document.getElementById(id);\n if (el) {\n Sortable.utils.toggleClass(el, 'rank-list-empty', el.children.length == 0);\n }\n })\n }, 0);\n }).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n}","onSort":"function() {\n try {\n (function(evt) {\n if (typeof Shiny == \"undefined\") {\n return;\n }\n\n var child_id_or_text_fn = function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);};\n\n var ret = {}, i;\n var css_ids = [\"rank_list_id_1\",\"rank_list_id_2\"];\n var input_ids = [\"input_parsons_1\",\"input_parsons\"];\n\n $.map(css_ids, function(css_id, i) {\n var input_id = input_ids[i];\n var item = $('#' + css_id).get(0);\n if (item && item.children) {\n ret[input_id] = $.map(item.children, child_id_or_text_fn);\n } else {\n ret[input_id] = undefined;\n }\n });\n Shiny.setInputValue(\"parsons_group_1:sortablejs.bucket_list\", ret)\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n\n try {\n (function(evt) {\n if (typeof Shiny !== \"undefined\") {\n Shiny.setInputValue(\"input_parsons:sortablejs.rank_list\", $.map( this.el.children, function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);}))\n }\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n}","onMove":"function(evt) {\n var css_ids = [\"rank_list_id_1\",\"rank_list_id_2\"];\n setTimeout(function() {\n css_ids.map(function(id) {\n var el = window.document.getElementById(id);\n if (el) {\n Sortable.utils.toggleClass(el, 'rank-list-empty', el.children.length == 0);\n }\n })\n }, 0);\n }"}},"evals":["options.onLoad","options.onSort","options.onMove"],"jsHooks":[]}</script> #> </div> #> </div> #> <style>.rank-list-container {min-height: 250px;}</style>
parsons_problem( initial = c( "iris", "mutate(...)", "summarize(...)", "print()" ), input_id = "input_parsons" )
#> <div class="bucket-list-container default-sortable default-parsons"> #> <div class="default-sortable default-parsons bucket-list bucket-list-horizontal"> #> <div class="rank-list-container default-sortable default-parsons column_1"> #> <p class="rank-list-title">Drag from here</p> #> <div class="rank-list" id="rank_list_id_3"> #> <div class="rank-list-item"> #> <div class="rank-list-item-internal base">iris</div> #> </div> #> <div class="rank-list-item"> #> <div class="rank-list-item-internal base">mutate(...)</div> #> </div> #> <div class="rank-list-item"> #> <div class="rank-list-item-internal base">summarize(...)</div> #> </div> #> <div class="rank-list-item"> #> <div class="rank-list-item-internal base">print()</div> #> </div> #> </div> #> </div> #> <div id="htmlwidget-36aa3d2a04d42bbc2145" style="width:0px;height:0px;" class="sortable html-widget"></div> #> <script type="application/json" data-for="htmlwidget-36aa3d2a04d42bbc2145">{"x":{"css_id":"rank_list_id_3","options":{"animation":150,"emptyInsertThreshold":12.5,"group":"parsons_group_2","onLoad":"function() {\n try {\n (function(evt) {\n if (typeof Shiny == \"undefined\") {\n return;\n }\n\n var child_id_or_text_fn = function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);};\n\n var ret = {}, i;\n var css_ids = [\"rank_list_id_3\",\"rank_list_id_4\"];\n var input_ids = [\"input_parsons_1\",\"input_parsons\"];\n\n $.map(css_ids, function(css_id, i) {\n var input_id = input_ids[i];\n var item = $('#' + css_id).get(0);\n if (item && item.children) {\n ret[input_id] = $.map(item.children, child_id_or_text_fn);\n } else {\n ret[input_id] = undefined;\n }\n });\n Shiny.setInputValue(\"parsons_group_2:sortablejs.bucket_list\", ret)\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n\n try {\n (function(evt) {\n if (typeof Shiny !== \"undefined\") {\n Shiny.setInputValue(\"input_parsons_1:sortablejs.rank_list\", $.map( this.el.children, function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);}))\n }\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n\n try {\n (function(evt) {\n var css_ids = [\"rank_list_id_3\"];\n setTimeout(function() {\n css_ids.map(function(id) {\n var el = window.document.getElementById(id);\n if (el) {\n Sortable.utils.toggleClass(el, 'rank-list-empty', el.children.length == 0);\n }\n })\n }, 0);\n }).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n}","onSort":"function() {\n try {\n (function(evt) {\n if (typeof Shiny == \"undefined\") {\n return;\n }\n\n var child_id_or_text_fn = function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);};\n\n var ret = {}, i;\n var css_ids = [\"rank_list_id_3\",\"rank_list_id_4\"];\n var input_ids = [\"input_parsons_1\",\"input_parsons\"];\n\n $.map(css_ids, function(css_id, i) {\n var input_id = input_ids[i];\n var item = $('#' + css_id).get(0);\n if (item && item.children) {\n ret[input_id] = $.map(item.children, child_id_or_text_fn);\n } else {\n ret[input_id] = undefined;\n }\n });\n Shiny.setInputValue(\"parsons_group_2:sortablejs.bucket_list\", ret)\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n\n try {\n (function(evt) {\n if (typeof Shiny !== \"undefined\") {\n Shiny.setInputValue(\"input_parsons_1:sortablejs.rank_list\", $.map( this.el.children, function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);}))\n }\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n}","onMove":"function(evt) {\n var css_ids = [\"rank_list_id_3\",\"rank_list_id_4\"];\n setTimeout(function() {\n css_ids.map(function(id) {\n var el = window.document.getElementById(id);\n if (el) {\n Sortable.utils.toggleClass(el, 'rank-list-empty', el.children.length == 0);\n }\n })\n }, 0);\n }"}},"evals":["options.onLoad","options.onSort","options.onMove"],"jsHooks":[]}</script> #> <div class="rank-list-container default-sortable default-parsons column_2"> #> <p class="rank-list-title">Construct your solution here</p> #> <div class="rank-list" id="rank_list_id_4"></div> #> </div> #> <div id="htmlwidget-febe03efa1a2d8d52a86" style="width:0px;height:0px;" class="sortable html-widget"></div> #> <script type="application/json" data-for="htmlwidget-febe03efa1a2d8d52a86">{"x":{"css_id":"rank_list_id_4","options":{"animation":150,"emptyInsertThreshold":12.5,"group":"parsons_group_2","onLoad":"function() {\n try {\n (function(evt) {\n if (typeof Shiny == \"undefined\") {\n return;\n }\n\n var child_id_or_text_fn = function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);};\n\n var ret = {}, i;\n var css_ids = [\"rank_list_id_3\",\"rank_list_id_4\"];\n var input_ids = [\"input_parsons_1\",\"input_parsons\"];\n\n $.map(css_ids, function(css_id, i) {\n var input_id = input_ids[i];\n var item = $('#' + css_id).get(0);\n if (item && item.children) {\n ret[input_id] = $.map(item.children, child_id_or_text_fn);\n } else {\n ret[input_id] = undefined;\n }\n });\n Shiny.setInputValue(\"parsons_group_2:sortablejs.bucket_list\", ret)\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n\n try {\n (function(evt) {\n if (typeof Shiny !== \"undefined\") {\n Shiny.setInputValue(\"input_parsons:sortablejs.rank_list\", $.map( this.el.children, function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);}))\n }\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n\n try {\n (function(evt) {\n var css_ids = [\"rank_list_id_4\"];\n setTimeout(function() {\n css_ids.map(function(id) {\n var el = window.document.getElementById(id);\n if (el) {\n Sortable.utils.toggleClass(el, 'rank-list-empty', el.children.length == 0);\n }\n })\n }, 0);\n }).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n}","onSort":"function() {\n try {\n (function(evt) {\n if (typeof Shiny == \"undefined\") {\n return;\n }\n\n var child_id_or_text_fn = function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);};\n\n var ret = {}, i;\n var css_ids = [\"rank_list_id_3\",\"rank_list_id_4\"];\n var input_ids = [\"input_parsons_1\",\"input_parsons\"];\n\n $.map(css_ids, function(css_id, i) {\n var input_id = input_ids[i];\n var item = $('#' + css_id).get(0);\n if (item && item.children) {\n ret[input_id] = $.map(item.children, child_id_or_text_fn);\n } else {\n ret[input_id] = undefined;\n }\n });\n Shiny.setInputValue(\"parsons_group_2:sortablejs.bucket_list\", ret)\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n\n try {\n (function(evt) {\n if (typeof Shiny !== \"undefined\") {\n Shiny.setInputValue(\"input_parsons:sortablejs.rank_list\", $.map( this.el.children, function(child) { return $(child).attr('data-rank-id') || $.trim(child.innerText);}))\n }\n}).apply(this, arguments);\n } catch(e) {\n if (window.console && window.console.error) window.console.error(e);\n }\n}","onMove":"function(evt) {\n var css_ids = [\"rank_list_id_3\",\"rank_list_id_4\"];\n setTimeout(function() {\n css_ids.map(function(id) {\n var el = window.document.getElementById(id);\n if (el) {\n Sortable.utils.toggleClass(el, 'rank-list-empty', el.children.length == 0);\n }\n })\n }, 0);\n }"}},"evals":["options.onLoad","options.onSort","options.onMove"],"jsHooks":[]}</script> #> </div> #> </div> #> <style>.rank-list-container {min-height: 250px;}</style>