You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Directly launch the events app in the viewer pane
80
-
runEventsApp(app,launch.browser=rstudio::viewer)
81
+
viewApp(app)
81
82
```
82
83
83
-
Note that a call to `eventsApp()` stores the generated app object (an environment) globally. The calls to buttonHandler, changeHandler and setText reference by default to this globally stored app object. Once the app starts, a copy of the app object will be generated for each user session that is generated by shiny.
84
+
Note that the handlers only are called when indeed an action is performed, e.g. the user selects a different element in a selectInput. In contrast, I often experienced in the usual approach in shiny to observe an input element, the change events are fired more often, e.g. when the element is first created.
84
85
85
-
Such a simple app app could be much easier written with the standard reactivity model of shiny. Yet, shinyEvents can become more useful when you have an app that creates a lot of dynamic UI.
86
+
I put in every handler a <ahref="https://github.com/skranz/restorepoint"target="_blank">restore point</a>, which I personally find very helpful to debug shiny applications.
86
87
87
-
## A simple app with dynamic UI
88
+
## An app with form input
88
89
89
-
Here is a simple app that creates dynamic UI.
90
+
Often I find it helpful to write apps with traditional input forms, where values from input fields are submitted when a button is pressed. Here is an example:
The `simpleButton` function has an argument `form.ids`, which lists the ids of all form elements whose values shall be passed to the buttonHandler in the list variable `formValues`.
124
+
125
+
## A more complex example with dynamic UI and custom HTML
126
+
127
+
The two examples before could also be easily implemented with a traditional shiny app. Here is a more complex example with a dynamically created HTML table with multiple inputs:
128
+
129
+
```r
130
+
library(shinyEvents)
131
+
132
+
# Create a new eventsApp
133
+
app= eventsApp()
134
+
135
+
app$ui= fluidPage(
136
+
simpleButton("btn1","Create Excercises"),
137
+
uiOutput("exUI")
100
138
)
101
139
102
-
# Dynamically create UI with button and add handler for it
# Directly launch the events app in the viewer pane
119
-
runEventsApp(app,launch.browser=rstudio::viewer)
173
+
174
+
175
+
viewApp(app)
120
176
```
121
177
122
-
The button handler for the static button creates and sets a new UI with another button and also generates a handler for the new button.
178
+
When we press `btn1`, we generate some custom HTML table from pure HTML code, not using any specific shiny widget. The dynamically generated simpleButton `btn2` uses the argument `form.sel=".ans-input"`. This is a <ahref="https://www.w3schools.com/cssref/css_selectors.asp">CSS selector</a> and specifies that the values of all inputs with class `ans-input` shall be passed in the variable `formValues` to the buttonHandler of `btn2`.
123
179
124
-
Note:
180
+
Note that the button handler for `btn1` is defined before the app runs, while the button handler for `btn2` is dynamically created during runtime. `shinyEvents` is designed to allow both. There is a difference in so far that all handlers that will be generated before the app starts will be available in every instance of the app. In contrast, handlers that will be added dynamically will only be available for the specific instance of the app, in which the handler was generated.
181
+
182
+
As a general observation, I tend to use more custom HTML and Javascript code the more shiny apps I have programmed. `shinyEvents` has correspondingly evolved to allow simple interfaces to such custom HTML, as the example above illustrates.
183
+
184
+
## Custom Event Handlers
185
+
186
+
For all sorts of <ahref="https://api.jquery.com/category/events/">jQuery Events</a>, you can add a custom event handler with shinyEvents. Here is a custom handler, you can add to the previous example:
setUI("ansUI", p(paste0("You typed ", value, " in row ", row)))
193
+
})
194
+
```
195
+
196
+
The handler is called when a jQuery `keyup` event is triggered on our manually generated input fields specified by the css class `ans-input`. If you look at the HTML code of our input fields, you see that we added a field `data-row`. By default all data fields of the element that triggers an element will be passed to the handler in the list variable `data`. Here we stored the row number and can now access it.
125
197
126
-
- The syntax for creating handlers (and setting values) stays the same for dynamic objects created by an already running app as for static objects that are created before the app has started.
setText("myText",paste0("You chose the list item ", value,". ",
257
-
"A random number: ", sample(1:1000,1)))
258
-
})
259
-
260
-
# Set an initial text
261
-
setText("myText","This is the start text...")
298
+
app$ui= fluidPage(p("Hello World!"))
262
299
263
300
# Important that you add this line
264
301
appReadyToRun(app)
265
302
```
266
-
267
-
Beware:
268
-
269
-
- Don't manually overwrite `app$server`. The server function will be created when creating a new app with `eventsApp()`. It contains code that is neccessary for running the app. If you want to add manual code when initializing the app, call the function `appInitHandler` as illustrated in the previous example. When using R Studio's functionality to run apps, you may have to leave out the argument `app` in the function passed to `appInitHandler`.
0 commit comments