Skip to content

Commit

Permalink
add more info to readme
Browse files Browse the repository at this point in the history
  • Loading branch information
daattali committed May 11, 2016
1 parent 9b23e18 commit b038193
Show file tree
Hide file tree
Showing 21 changed files with 49 additions and 46 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,114 +32,155 @@ global.R, splitting off big ui/server into files

**[Link to code](./api-ajax)**

Sometimes it's useful to be able to call an R function from JavaScript and use the return value from R back in JavaScript. This sort of communication is usually done with AJAX in JavaScript. This app shows how to implement a simple and ultra lightweight AJAX-like system in Shiny, to be able to call functions in R.

<h3 id="auto-kill-app">Automatically stop a Shiny app when closing the browser tab</h3>

**[Link to code](./auto-kill-app)**

When developing a Shiny app and running the app in the browser (as opposed to inside the RStudio Viewer), it can be annoying that when you close the browser window, the app is still running and you need to manually press "Esc" to kill it. By adding a single line to the server code `session$onSessionEnded(stopApp)`, a Shiny app will automatically stop running whenever the browser tab (or any session) is closed.

<h3 id="busy-indicator">TODO</h3>

**[Link to code](./busy-indicator)**



<h3 id="close-window">Close the window (and stop the app) with a button click</h3>

**[Link to code](./close-window)**

This simple example shows how you can have a button that, when clicked, will close the current browser tab and stop the running Shiny app (you can choose to do only one of these two actions).

<h3 id="error-custom-message">Show user a generic error message when a Shiny error occurs in an output</h3>

**[Link to code](./error-custom-message)**

When a Shiny output encounters an error, the exact error message will be shown to the user in place of the output. This is generally a good feature because it's easier to debug when you know the exact error. But sometimes this is undesireable if you want to keep the specifics of what happened unknown to the user, and you prefer to just show the user a generic "Some error occurred; please contact us" message. This may sound counter intuitive, but you can actually do this with a tiny bit of CSS, as this example shows.

<h3 id="fb-login">Facebook login through JavaScript in Shiny</h3>

**[Link to code](./fb-login)**

This app shows how you can use the [AJAX-like system](./api-ajax) in Shiny to authorize a user using Facebook's JavaScript library and pass the user's information to R for processing.

<h3 id="fb-share-img">Sharing images on Facebook</h3>

**[Link to code](./fb-share-img)**

There are two ways to share images on Facebook: either using an image URL and a popup dialog, or by programatically supplying the Facebook API with a base64 encoded image. This example shows both.

<h3 id="hide-tab">Hide a tab</h3>

**[Link to code](./hide-tab)**

This app demonstrates how `shinyjs` can be used to hide/show a specific tab in a `tabsetPanel`. In order to use this trick, the `tabsetPanel` must have an id. Using this id and the value of the specific tab you want to hide/show, you can call `shinyjs::hide()`/`shinyjs::show()`/`shinyjs::toggle()`.

[![Demo](./hide-tab/hide-tab.gif)](./hide-tab)

<h3 id="loading-screen">Loading screen</h3>

**[Link to code](./loading-screen)**

This simple app shows how to add a "Loading..." screen overlaying the main app while the app's server is initializing. The main idea is to include an overlay element that covers the entire app (using CSS), hide the main app's UI, and at the end of the server function show the UI and hide the overlay.

[![Demo](./loading-screen/loading-screen.gif)](./loading-screen)

<h3 id="multiple-pages">Shiny app with sequence of pages</h3>

**[Link to code](./multiple-pages)**

This app demonstrates how to write a Shiny app that has a sequence of different pages, where the user can navigate to the next/previous page. This can be useful in many scenarios that involve a multi-step process. This behaviour can also be achieved by simply using tabs, but when using tabs the user can freely move from any tab to any other tab, while this approach restricts the user to only move to the previous/next step, and can also control when the user can move on to the next page.

[![Demo](./multiple-pages/multiple-pages.gif)](./multiple-pages)

<h3 id="multiple-scrollspy-advanced">Multiple scrollspy - advanced</h3>

**[Link to code](./multiple-scrollspy-advanced)**

The Bootstrap *scrollspy* plugin does not support multiple scrollspy objects per page.
This Shiny app demonstrates how to support scrollspy on multiple tabs by allowing each tab to have its own independent scrollspy control and using JavaScript to ensure only the scrollspy on the current tab is activated.

<h3 id="multiple-scrollspy-basic">Multiple scrollspy - basic</h3>

**[Link to code](./multiple-scrollspy-basic)**

The Bootstrap *scrollspy* plugin does not support multiple scrollspy objects per page. This Shiny app demonstrates how to support scrollspy on multiple tabs by having one common scrollspy control that gets updated via JavaScript whenever a tab is changed to reflect the contents of the new tab.

<h3 id="navigate-history">Navigation in a Shiny app</h3>

**[Link to code](./navigate-history)**

Sometimes it's nice to be able to support navigation within a Shiny app, especially when there are multiple tabs or some other form of "multiple pages" in a Shiny app. Since Shiny apps are a single page, the browser nagivation buttons (previous/next page) don't work when "navigating" within a Shiny app. You also can't bookmark a certain "page" in a Shiny app - every time you go to an app, you will be shown the initial state of the app. This app shows how to implement basic navigation in Shiny apps.

[![Demo](./navigate-history/navigate-history.gif)](./navigate-history)

<h3 id="plot-spinner">Show a spinning "loading" animation while a plot is recalculating</h3>

**[Link to code](./plot-spinner)**

When a Shiny plot is recalculating, the plot gets grayed out. This app shows how you can add a spinner wheel on top of the plot while it is recalculating, to make it clear to the user that the plot is reloading. There can be many different ways to achieve a similar result using different combinations of HTML/CSS, this example is just the simplest one I came up with.

[![Demo](./plot-spinner/plot-spinner.gif)](./plot-spinner)

<h3 id="proxy-click">Press the Enter key to simulate a button press</h3>

**[Link to code](./proxy-click)**

This is a simple app with a tiny bit of JavaScript that shows you how to cause an Enter key press inside an input to trigger a click on a button.

<h3 id="select-input-large">Select input with more breathing room</h3>

**[Link to code](./select-input-large)**

One common CSS question in Shiny is how to make the select input dropdown menu have some more whitespace. It's actually very easy to do with just two CSS rules, as demonstrated in this example.

[![Demo](./select-input-large/selectize-large.gif)](./select-input-large)

<h3 id="serve-images-files">Serve files (images/text files/etc) instead of webpages from a Shiny app </h3>

**[Link to code](./serve-images-files)**

It is possible to serve an image or another file directly from your Shiny app instead of a webpage. The method shown here is a simple proof-of-concept of how to achieve this functionality. It also supports passing GET parameters to the file-generating logic so that the file can be parameterized.

[![Demo](./serve-images-files/serve-images-files.gif)](./serve-images-files)

<h3 id="server-to-ui-variable">TODO</h3>

**[Link to code](./server-to-ui-variable)**



<h3 id="shinydashboard-sidebar-hide">Hide/show shinydashboard sidebar programatically</h3>

**[Link to code](./shinydashboard-sidebar-hide)**

A common question regarding `shinydashboard` is how to programatically hide/show the sidebar. This can very easily be done using the [shinyjs](https://github.com/daattali/shinyjs) package, as demonstrated here.

[![Demo](./shinydashboard-sidebar-hide/shinydashboard-sidebar-hide.gif)](./shinydashboard-sidebar-hide)

<h3 id="simple-toggle">Toggle a UI element (alternate between show/hide) with a button</h3>

**[Link to code](./simple-toggle)**

Sometimes you want to toggle a section of the UI every time a button is clicked. This app shows how to achieve very basic toggle functionality using `conditionalPanel()`. If you want anything more advanced, you can use the `toggle()` function from the [shinyjs](https://github.com/daattali/shinyjs) package.

<h3 id="update-input">Update multiple Shiny inputs without knowing input type </h3>

**[Link to code](./update-input)**

Shiny allows you to update an input element only if you know the type of input. Furthermore, Shiny only allows you to update input elements one by one. This Shiny app shows how you can update an input only using its ID and without knowing its type, and how to update multiple inputs together.

<h3 id="upload-file-names">TODO</h3>

**[Link to code](./upload-file-names)**



<h3 id="url-inputs">Prepopulate Shiny inputs when an app loads based on URL parameters</h3>

**[Link to code](./url-inputs)**

This simple app demonstrates how you can fill out certain input fields when a Shiny app loads based on URL parameters.

[![Demo](./url-inputs/url-inputs.gif)](./url-inputs)
2 changes: 1 addition & 1 deletion api-ajax/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Simple AJAX system for Shiny apps (JS -> R -> JS communication)

Sometimes it's useful to be able to call an R function from JavaScript and use the return value from R in JavaScript. This sort of communication is usually done with AJAX in JavaScript. This app shows how to implement a simple and ultra lightweight AJAX-like system in Shiny, to be able to call functions in R.
Sometimes it's useful to be able to call an R function from JavaScript and use the return value from R back in JavaScript. This sort of communication is usually done with AJAX in JavaScript. This app shows how to implement a simple and ultra lightweight AJAX-like system in Shiny, to be able to call functions in R.

Using this system is easy:
1. Include `api.js` in your Shiny app's UI
Expand Down
4 changes: 1 addition & 3 deletions auto-kill-app/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Automatically stop a Shiny app when closing the browser tab

*Dean Attali, July 2015*

When developing a Shiny app and running the app in the browser (as opposed to inside the RStudio Viewer), it can be annoying that when you close the browser window, the app is still running and you need to manually press "Esc" to kill it. By adding a single line to the server code `session$onSessionEnded(stopApp)`, a Shiny app will automatically stop whenever the browser tab (or any session) is closed.
When developing a Shiny app and running the app in the browser (as opposed to inside the RStudio Viewer), it can be annoying that when you close the browser window, the app is still running and you need to manually press "Esc" to kill it. By adding a single line to the server code `session$onSessionEnded(stopApp)`, a Shiny app will automatically stop running whenever the browser tab (or any session) is closed.

Note that this can be useful for local development, but you should be very careful not to deploy this code in a real server because you don't want your real Shiny app to stop every time a user leaves the app.
2 changes: 0 additions & 2 deletions close-window/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Close the window (and stop the app) with a button click

*Dean Attali, July 2015*

This simple example shows how you can have a button that, when clicked, will close the current browser tab and stop the running Shiny app (you can choose to do only one of these two actions).

This example makes use of the [shinyjs](https://github.com/daattali/shinyjs) package to call custom JavaScript functions.
2 changes: 0 additions & 2 deletions error-custom-message/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Show user a generic error message when a Shiny error occurs in an output

*Dean Attali, July 2015*

When a Shiny output encounters an error, the exact error message will be shown to the user in place of the output. This is generally a good feature because it's easier to debug when you know the exact error. But sometimes this is undesireable if you want to keep the specifics of what happened unknown to the user, and you prefer to just show the user a generic "Some error occurred; please contact us" message. This may sound counter intuitive, but you can actually do this with a tiny bit of CSS, as this example shows.
4 changes: 1 addition & 3 deletions fb-login/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Facebook login through JavaScript in Shiny

*Dean Attali, July 2015*

This app shows how you can use the AJAX-like system in Shiny to authorize a user using Facebook's JavaScript library and pass the user's information to R for processing. Because of Facebook's app settings, in order for the app to work properly locally, you need to replace `127.0.0.1` in the URL with `fuf.me` (testing FB apps locally is a big pain and is out of the scope of this example, you might have to do lots of Googling and StackOverflow-ing to get it right).
This app shows how you can use the [AJAX-like system](../api-ajax) in Shiny to authorize a user using Facebook's JavaScript library and pass the user's information to R for processing. Because of Facebook's app settings, in order for the app to work properly locally, you need to replace `127.0.0.1` in the URL with `fuf.me` (testing FB apps locally is a big pain and is out of the scope of this example, you might have to do lots of Googling and StackOverflow-ing to get it right).

Note that this example uses the [AJAX system](../api-ajax) shown in another example.
4 changes: 1 addition & 3 deletions fb-share-img/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Sharing images on Facebook

*Dean Attali, July 2015*

There are two Facebook share buttons: the first one (easier) uses the conventional way of sharing an image on Facebook using an image URL and will ask the user to confirm sharing. The second method shares a base64 encoded image (which means we get get the image data straight from Shiny) and can be done completely programatically, but it's a little bit more hacky.
There are two ways to share images on Facebook, and hence there are two share buttons in the sample app. The first one (easier) uses the conventional way of sharing an image on Facebook using an image URL and will ask the user to confirm sharing. The second method shares a base64 encoded image (which means we get get the image data straight from Shiny) and can be done completely programatically, but it's a little bit more hacky.

A user will be asked to log in to Facebook if they aren't logged in. Note that the Facebook app settings do not allow a URL of `localhost` or `127.0.0.1` to be used, so in order to run this app locally you will need to change the URL to `fuf.me`.
2 changes: 0 additions & 2 deletions hide-tab/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Hide a tab

*Dean Attali, July 2015*

This app demonstrates how `shinyjs` can be used to hide/show a specific tab in a `tabsetPanel`. In order to use this trick, the `tabsetPanel` must have an id. Using this id and the value of the specific tab you want to hide/show, you can call `shinyjs::hide()`/`shinyjs::show()`/`shinyjs::toggle()`.

This example makes use of the [shinyjs](https://github.com/daattali/shinyjs) package to show/hide the tab.
Expand Down
2 changes: 0 additions & 2 deletions loading-screen/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Loading screen

*Dean Attali, July 2015*

This simple app shows how to add a "Loading..." screen overlaying the main app while the app's server is initializing. The main idea is to include an overlay element that covers the entire app (using CSS), hide the main app's UI, and at the end of the server function show the UI and hide the overlay.

This example makes use of the [shinyjs](https://github.com/daattali/shinyjs) package to show/hide elements.
Expand Down
2 changes: 0 additions & 2 deletions multiple-pages/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Shiny app with sequence of pages

*Dean Attali, July 2015*

This app demonstrates how to write a Shiny app that has a sequence of different pages, where the user can navigate to the next/previous page. This can be useful in many scenarios that involve a multi-step process. This behaviour can also be achieved by simply using tabs, but when using tabs the user can freely move from any tab to any other tab, while this approach restricts the user to only move to the previous/next step, and can also control when the user can move on to the next page (by enabling/disabling the navigation buttons using `shinyjs::enable` and `shinyjs::disable`).

This example makes use of the [shinyjs](https://github.com/daattali/shinyjs) package to show/hide the pages and to enable/disable the buttons.
Expand Down
4 changes: 1 addition & 3 deletions multiple-scrollspy-advanced/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Multiple scrollspy - advanced

*Dean Attali, July 2015*

The Bootstrap scrollspy plugin does not support multiple scrollspy objects per page.
The Bootstrap *scrollspy* plugin does not support multiple scrollspy objects per page.
This Shiny app demonstrates how to support scrollspy on multiple tabs by allowing each tab to have its own independent scrollspy control and using JavaScript to ensure only the scrollspy on the current tab is activated. Look at the code to see how this is achieved.

This approach is very flexible and great to use when you want to define custom scrollspy controls on each tab. Initially I thought it'd be easy to simply "destroy" a scrollspy control and initialize a different one, but it seems like destorying scrollspy objects is not possible in Bootstrap 3 (although it sounds like in Bootstrap 4 it will be supported), so a more clever trick has to be used in order to "reset" the active scrollspy control.
Expand Down
4 changes: 1 addition & 3 deletions multiple-scrollspy-basic/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Multiple scrollspy - basic

*Dean Attali, July 2015*

The Bootstrap scrollspy plugin does not support multiple scrollspy objects per page. This Shiny app demonstrates how to support scrollspy on multiple tabs by having one common scrollspy control that gets updated via JavaScript whenever a tab is changed to reflect the contents of the new tab. Look at the code to see how this is achieved.
The Bootstrap *scrollspy* plugin does not support multiple scrollspy objects per page. This Shiny app demonstrates how to support scrollspy on multiple tabs by having one common scrollspy control that gets updated via JavaScript whenever a tab is changed to reflect the contents of the new tab. Look at the code to see how this is achieved.

This approach is useful if you don't want to have to hardcode the scrollspy code since it will automatically generate the scrollspy control for each tab. However, the major disadvantage of this approach is that if you want different pages to have very different looking scrollspy controls, it will be hard to achieve with this method because only one common control is created.

Expand Down
2 changes: 0 additions & 2 deletions navigate-history/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Navigation in a Shiny app

*Dean Attali, July 2015*

Sometimes it's nice to be able to support navigation within a Shiny app, especially when there are multiple tabs or some other form of "multiple pages" in a Shiny app. Since Shiny apps are a single page, the browser nagivation buttons (previous/next page) don't work when "navigating" within a Shiny app. You also can't bookmark a certain "page" in a Shiny app - every time you go to an app, you will be shown the initial state of the app.

This app shows a basic demonstration of how to implement a way to navigate a Shiny app by manually changing the URL when different tabs are loaded, and using the current URL to decide what to show when a new page is loaded. In this app, every time you click on a new tab, the browser will behave as if you navigated to a new page, and you will be able to go back and forward using the browser navigation buttons. Another nice feature is that after navigating to a certain tab, you can copy the URL or bookmark it, and when you open that page again, the Shiny app will restore the state of the app.
Expand Down
Loading

0 comments on commit b038193

Please sign in to comment.