-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathoutstanding-shiny-ui.toc
432 lines (432 loc) · 38 KB
/
outstanding-shiny-ui.toc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
\contentsline {fm}{Foreword}{xix}{chapter*.1}%
\contentsline {fm}{Welcome}{xxi}{chapter*.2}%
\contentsline {chapter}{\numberline {1}Shiny and the Web}{3}{chapter.1}%
\contentsline {section}{\numberline {1.1}Shiny generates HTML code from R}{3}{section.1.1}%
\contentsline {section}{\numberline {1.2}Be a DJ}{4}{section.1.2}%
\contentsline {section}{\numberline {1.3}HTML 101}{5}{section.1.3}%
\contentsline {subsection}{\numberline {1.3.1}HTML basics}{5}{subsection.1.3.1}%
\contentsline {subsection}{\numberline {1.3.2}Tag attributes}{6}{subsection.1.3.2}%
\contentsline {subsection}{\numberline {1.3.3}The simplest HTML skeleton}{7}{subsection.1.3.3}%
\contentsline {subsection}{\numberline {1.3.4}About the Document Object Model (DOM)}{8}{subsection.1.3.4}%
\contentsline {subsubsection}{\numberline {1.3.4.1}Visualizing the DOM with the developer tools}{8}{subsubsection.1.3.4.1}%
\contentsline {subsubsection}{\numberline {1.3.4.2}Web Inspector 101}{9}{subsubsection.1.3.4.2}%
\contentsline {paragraph}{\numberline {1.3.4.2.1}Exercise: Altering the DOM structure}{10}{paragraph.1.3.4.2.1}%
\contentsline {subsection}{\numberline {1.3.5}Preliminary introduction to CSS and JavaScript}{12}{subsection.1.3.5}%
\contentsline {subsubsection}{\numberline {1.3.5.1}HTML and CSS}{14}{subsubsection.1.3.5.1}%
\contentsline {subsubsection}{\numberline {1.3.5.2}HTML and JavaScript}{14}{subsubsection.1.3.5.2}%
\contentsline {section}{\numberline {1.4}Summary}{15}{section.1.4}%
\contentsline {chapter}{\numberline {2}Manipulate HTML tags from R with \{htmltools\}}{17}{chapter.2}%
\contentsline {section}{\numberline {2.1}Writing HTML Tags from R}{17}{section.2.1}%
\contentsline {section}{\numberline {2.2}Notations}{18}{section.2.2}%
\contentsline {section}{\numberline {2.3}Adding new tags}{21}{section.2.3}%
\contentsline {section}{\numberline {2.4}Alternative way to write tags}{21}{section.2.4}%
\contentsline {section}{\numberline {2.5}Playing with tags}{23}{section.2.5}%
\contentsline {subsection}{\numberline {2.5.1}Tags structure}{23}{subsection.2.5.1}%
\contentsline {subsection}{\numberline {2.5.2}Practical examples: shinyRPG}{24}{subsection.2.5.2}%
\contentsline {subsection}{\numberline {2.5.3}Useful functions for tags}{27}{subsection.2.5.3}%
\contentsline {subsubsection}{\numberline {2.5.3.1}Add attributes}{27}{subsubsection.2.5.3.1}%
\contentsline {subsubsection}{\numberline {2.5.3.2}Check if tag has specific attribute}{28}{subsubsection.2.5.3.2}%
\contentsline {subsubsection}{\numberline {2.5.3.3}Get all attributes}{28}{subsubsection.2.5.3.3}%
\contentsline {subsubsection}{\numberline {2.5.3.4}Set child/children}{28}{subsubsection.2.5.3.4}%
\contentsline {subsubsection}{\numberline {2.5.3.5}Add child or children}{29}{subsubsection.2.5.3.5}%
\contentsline {subsubsection}{\numberline {2.5.3.6}Build your own functions}{29}{subsubsection.2.5.3.6}%
\contentsline {subsection}{\numberline {2.5.4}Other functions}{30}{subsection.2.5.4}%
\contentsline {subsection}{\numberline {2.5.5}Conditionally set attributes}{31}{subsection.2.5.5}%
\contentsline {subsection}{\numberline {2.5.6}Using \%\textgreater \%}{31}{subsection.2.5.6}%
\contentsline {subsection}{\numberline {2.5.7}Programmatically create children elements}{32}{subsection.2.5.7}%
\contentsline {section}{\numberline {2.6}Modern \{htmltools\}}{32}{section.2.6}%
\contentsline {subsection}{\numberline {2.6.1}Basics}{34}{subsection.2.6.1}%
\contentsline {subsection}{\numberline {2.6.2}Query tags}{35}{subsection.2.6.2}%
\contentsline {subsection}{\numberline {2.6.3}Modify tags}{36}{subsection.2.6.3}%
\contentsline {subsubsection}{\numberline {2.6.3.1}Playing with attributes}{37}{subsubsection.2.6.3.1}%
\contentsline {subsubsection}{\numberline {2.6.3.2}Altering tag/children/siblings}{38}{subsubsection.2.6.3.2}%
\contentsline {subsection}{\numberline {2.6.4}Chain tag queries}{39}{subsection.2.6.4}%
\contentsline {subsection}{\numberline {2.6.5}Specific cases}{40}{subsection.2.6.5}%
\contentsline {subsection}{\numberline {2.6.6}Practice}{41}{subsection.2.6.6}%
\contentsline {subsection}{\numberline {2.6.7}Alter tag rendering with render hooks}{42}{subsection.2.6.7}%
\contentsline {subsubsection}{\numberline {2.6.7.1}Simple hooks}{42}{subsubsection.2.6.7.1}%
\contentsline {subsubsection}{\numberline {2.6.7.2}Nested hooks}{44}{subsubsection.2.6.7.2}%
\contentsline {chapter}{\numberline {3}Discover Shiny dependencies}{49}{chapter.3}%
\contentsline {section}{\numberline {3.1}Introduction}{49}{section.3.1}%
\contentsline {section}{\numberline {3.2}Bootstrap}{50}{section.3.2}%
\contentsline {section}{\numberline {3.3}jQuery, DOM manipulation}{51}{section.3.3}%
\contentsline {section}{\numberline {3.4}Custom dependencies}{52}{section.3.4}%
\contentsline {section}{\numberline {3.5}Exercise}{52}{section.3.5}%
\contentsline {chapter}{\numberline {4}Handle HTML dependencies with \{htmltools\}}{55}{chapter.4}%
\contentsline {section}{\numberline {4.1}Motivations}{55}{section.4.1}%
\contentsline {section}{\numberline {4.2}Importing HTML dependencies from other packages}{58}{section.4.2}%
\contentsline {section}{\numberline {4.3}Suppress dependencies}{60}{section.4.3}%
\contentsline {section}{\numberline {4.4}Resolve dependencies}{61}{section.4.4}%
\contentsline {section}{\numberline {4.5}Insert Custom script in the head}{62}{section.4.5}%
\contentsline {chapter}{\numberline {5}Web application concepts}{65}{chapter.5}%
\contentsline {section}{\numberline {5.1}The client-server model}{65}{section.5.1}%
\contentsline {section}{\numberline {5.2}About HTTP requests}{66}{section.5.2}%
\contentsline {section}{\numberline {5.3}Structure of an URL}{67}{section.5.3}%
\contentsline {section}{\numberline {5.4}Web app files structure}{67}{section.5.4}%
\contentsline {section}{\numberline {5.5}Serving web apps}{68}{section.5.5}%
\contentsline {section}{\numberline {5.6}About \texttt {\{httpuv\}}}{69}{section.5.6}%
\contentsline {section}{\numberline {5.7}Shiny app lifecycle}{69}{section.5.7}%
\contentsline {subsection}{\numberline {5.7.1}Building the UI}{69}{subsection.5.7.1}%
\contentsline {subsection}{\numberline {5.7.2}Serving HTML with \texttt {\{httpuv\}}}{74}{subsection.5.7.2}%
\contentsline {section}{\numberline {5.8}Summary}{75}{section.5.8}%
\contentsline {chapter}{\numberline {6}CSS for Shiny}{77}{chapter.6}%
\contentsline {section}{\numberline {6.1}How to include CSS?}{77}{section.6.1}%
\contentsline {section}{\numberline {6.2}CSS selectors}{78}{section.6.2}%
\contentsline {subsection}{\numberline {6.2.1}Basics}{78}{subsection.6.2.1}%
\contentsline {subsection}{\numberline {6.2.2}Select by class, id}{79}{subsection.6.2.2}%
\contentsline {subsection}{\numberline {6.2.3}Apply CSS to single elements}{80}{subsection.6.2.3}%
\contentsline {subsection}{\numberline {6.2.4}Advanced selectors}{80}{subsection.6.2.4}%
\contentsline {subsubsection}{\numberline {6.2.4.1}Select nested tags}{80}{subsubsection.6.2.4.1}%
\contentsline {subsubsection}{\numberline {6.2.4.2}Select by attributes}{82}{subsubsection.6.2.4.2}%
\contentsline {subsubsection}{\numberline {6.2.4.3}Other selectors}{83}{subsubsection.6.2.4.3}%
\contentsline {paragraph}{\numberline {6.2.4.3.1}Direct descendants}{83}{paragraph.6.2.4.3.1}%
\contentsline {paragraph}{\numberline {6.2.4.3.2}Pseudo-classes}{85}{paragraph.6.2.4.3.2}%
\contentsline {paragraph}{\numberline {6.2.4.3.3}Pseudo-elements}{85}{paragraph.6.2.4.3.3}%
\contentsline {section}{\numberline {6.3}Best practices}{86}{section.6.3}%
\contentsline {subsection}{\numberline {6.3.1}DRY principle}{86}{subsection.6.3.1}%
\contentsline {subsection}{\numberline {6.3.2}Selector specificity}{87}{subsection.6.3.2}%
\contentsline {subsection}{\numberline {6.3.3}Block element modified (BEM)}{88}{subsection.6.3.3}%
\contentsline {section}{\numberline {6.4}Modify CSS with the HTML inspector}{88}{section.6.4}%
\contentsline {subsection}{\numberline {6.4.1}Add inline properties}{88}{subsection.6.4.1}%
\contentsline {subsection}{\numberline {6.4.2}View local changes}{89}{subsection.6.4.2}%
\contentsline {section}{\numberline {6.5}CSS in action}{90}{section.6.5}%
\contentsline {subsection}{\numberline {6.5.1}Text Styling}{90}{subsection.6.5.1}%
\contentsline {subsubsection}{\numberline {6.5.1.1}Fonts}{90}{subsubsection.6.5.1.1}%
\contentsline {subsubsection}{\numberline {6.5.1.2}Size}{92}{subsubsection.6.5.1.2}%
\contentsline {subsubsection}{\numberline {6.5.1.3}Alignment}{92}{subsubsection.6.5.1.3}%
\contentsline {subsubsection}{\numberline {6.5.1.4}Other styling properties}{92}{subsubsection.6.5.1.4}%
\contentsline {subsection}{\numberline {6.5.2}Colors}{92}{subsection.6.5.2}%
\contentsline {subsubsection}{\numberline {6.5.2.1}Text color}{93}{subsubsection.6.5.2.1}%
\contentsline {subsubsection}{\numberline {6.5.2.2}Background color}{93}{subsubsection.6.5.2.2}%
\contentsline {subsection}{\numberline {6.5.3}Borders and shadows}{93}{subsection.6.5.3}%
\contentsline {subsection}{\numberline {6.5.4}Animations}{96}{subsection.6.5.4}%
\contentsline {subsection}{\numberline {6.5.5}Layout}{98}{subsection.6.5.5}%
\contentsline {subsubsection}{\numberline {6.5.5.1}Style blocks}{98}{subsubsection.6.5.5.1}%
\contentsline {subsubsection}{\numberline {6.5.5.2}Flexbox}{100}{subsubsection.6.5.5.2}%
\contentsline {subsubsection}{\numberline {6.5.5.3}Grid model}{102}{subsubsection.6.5.5.3}%
\contentsline {subsection}{\numberline {6.5.6}Responsive design: media queries}{102}{subsection.6.5.6}%
\contentsline {chapter}{\numberline {7}Tidy your CSS with Sass}{107}{chapter.7}%
\contentsline {section}{\numberline {7.1}Getting started with Sass}{107}{section.7.1}%
\contentsline {subsection}{\numberline {7.1.1}Variables}{108}{subsection.7.1.1}%
\contentsline {subsection}{\numberline {7.1.2}Partials and Modules}{108}{subsection.7.1.2}%
\contentsline {subsection}{\numberline {7.1.3}Mixins and Functions}{109}{subsection.7.1.3}%
\contentsline {subsubsection}{\numberline {7.1.3.1}Mixins}{109}{subsubsection.7.1.3.1}%
\contentsline {subsubsection}{\numberline {7.1.3.2}Functions}{110}{subsubsection.7.1.3.2}%
\contentsline {subsection}{\numberline {7.1.4}Extend/Inheritance}{111}{subsection.7.1.4}%
\contentsline {subsection}{\numberline {7.1.5}Flow controls}{112}{subsection.7.1.5}%
\contentsline {subsubsection}{\numberline {7.1.5.1}if and else}{112}{subsubsection.7.1.5.1}%
\contentsline {subsubsection}{\numberline {7.1.5.2}Loops}{113}{subsubsection.7.1.5.2}%
\contentsline {paragraph}{\numberline {7.1.5.2.1}Each}{113}{paragraph.7.1.5.2.1}%
\contentsline {paragraph}{\numberline {7.1.5.2.2}For}{115}{paragraph.7.1.5.2.2}%
\contentsline {subsection}{\numberline {7.1.6}Nesting code}{115}{subsection.7.1.6}%
\contentsline {section}{\numberline {7.2}\texttt {\{sass\}} best practices}{116}{section.7.2}%
\contentsline {section}{\numberline {7.3}From Sass to CSS}{118}{section.7.3}%
\contentsline {section}{\numberline {7.4}Caching}{118}{section.7.4}%
\contentsline {section}{\numberline {7.5}Sass and Shiny}{119}{section.7.5}%
\contentsline {section}{\numberline {7.6}Examples}{120}{section.7.6}%
\contentsline {subsection}{\numberline {7.6.1}Customize \texttt {\{bs4Dash\}} colors}{120}{subsection.7.6.1}%
\contentsline {subsection}{\numberline {7.6.2}Customize \texttt {\{shinybulma\}}}{122}{subsection.7.6.2}%
\contentsline {chapter}{\numberline {8}Beautify with \texttt {\{fresh\}}}{125}{chapter.8}%
\contentsline {section}{\numberline {8.1}\texttt {\{fresh\}}, the big picture}{125}{section.8.1}%
\contentsline {subsection}{\numberline {8.1.1}Customize \texttt {\{bs4Dash\}}}{126}{subsection.8.1.1}%
\contentsline {subsubsection}{\numberline {8.1.1.1}Statuses and colors}{127}{subsubsection.8.1.1.1}%
\contentsline {subsubsection}{\numberline {8.1.1.2}General Layout}{128}{subsubsection.8.1.1.2}%
\contentsline {subsubsection}{\numberline {8.1.1.3}Navbar}{128}{subsubsection.8.1.1.3}%
\contentsline {subsubsection}{\numberline {8.1.1.4}Text color}{130}{subsubsection.8.1.1.4}%
\contentsline {subsubsection}{\numberline {8.1.1.5}Color contrast}{130}{subsubsection.8.1.1.5}%
\contentsline {subsubsection}{\numberline {8.1.1.6}Sidebar}{131}{subsubsection.8.1.1.6}%
\contentsline {subsection}{\numberline {8.1.2}Customize \texttt {\{shinydashboard\}}}{134}{subsection.8.1.2}%
\contentsline {chapter}{\numberline {9}Become a theming wizard with \{bslib\}}{137}{chapter.9}%
\contentsline {section}{\numberline {9.1}High-level customization}{138}{section.9.1}%
\contentsline {subsection}{\numberline {9.1.1}Create a theme}{138}{subsection.9.1.1}%
\contentsline {subsection}{\numberline {9.1.2}Update a theme}{139}{subsection.9.1.2}%
\contentsline {subsection}{\numberline {9.1.3}Preview a theme}{140}{subsection.9.1.3}%
\contentsline {subsection}{\numberline {9.1.4}Live theming}{140}{subsection.9.1.4}%
\contentsline {section}{\numberline {9.2}Low-level customization}{142}{section.9.2}%
\contentsline {subsection}{\numberline {9.2.1}Add new variables}{142}{subsection.9.2.1}%
\contentsline {subsection}{\numberline {9.2.2}Import external rules}{143}{subsection.9.2.2}%
\contentsline {section}{\numberline {9.3}Dynamic theming}{144}{section.9.3}%
\contentsline {subsection}{\numberline {9.3.1}Basics}{144}{subsection.9.3.1}%
\contentsline {subsection}{\numberline {9.3.2}Custom elements}{146}{subsection.9.3.2}%
\contentsline {subsection}{\numberline {9.3.3}Conditional rendering}{149}{subsection.9.3.3}%
\contentsline {subsubsection}{\numberline {9.3.3.1}Bootstrap badges}{149}{subsubsection.9.3.3.1}%
\contentsline {subsubsection}{\numberline {9.3.3.2}Bootstrap navs}{150}{subsubsection.9.3.3.2}%
\contentsline {subsubsection}{\numberline {9.3.3.3}Guided exercise: Bootstrap accordions}{151}{subsubsection.9.3.3.3}%
\contentsline {section}{\numberline {9.4}Further resources}{157}{section.9.4}%
\contentsline {chapter}{\numberline {10}JavaScript for Shiny}{161}{chapter.10}%
\contentsline {section}{\numberline {10.1}Shiny JavaScript sources}{161}{section.10.1}%
\contentsline {section}{\numberline {10.2}Introduction to JavaScript}{162}{section.10.2}%
\contentsline {section}{\numberline {10.3}Setup}{164}{section.10.3}%
\contentsline {subsection}{\numberline {10.3.1}Node}{164}{subsection.10.3.1}%
\contentsline {subsection}{\numberline {10.3.2}Choose a good IDE}{164}{subsection.10.3.2}%
\contentsline {subsection}{\numberline {10.3.3}First script}{165}{subsection.10.3.3}%
\contentsline {section}{\numberline {10.4}Programming with JS: basis}{166}{section.10.4}%
\contentsline {subsection}{\numberline {10.4.1}JS types}{166}{subsection.10.4.1}%
\contentsline {subsection}{\numberline {10.4.2}Variables}{166}{subsection.10.4.2}%
\contentsline {subsubsection}{\numberline {10.4.2.1}Const}{167}{subsubsection.10.4.2.1}%
\contentsline {subsubsection}{\numberline {10.4.2.2}let}{167}{subsubsection.10.4.2.2}%
\contentsline {subsection}{\numberline {10.4.3}Conditions}{168}{subsection.10.4.3}%
\contentsline {subsection}{\numberline {10.4.4}Objects}{169}{subsection.10.4.4}%
\contentsline {subsubsection}{\numberline {10.4.4.1}Arrays}{169}{subsubsection.10.4.4.1}%
\contentsline {subsubsection}{\numberline {10.4.4.2}Strings}{170}{subsubsection.10.4.4.2}%
\contentsline {subsubsection}{\numberline {10.4.4.3}Math}{171}{subsubsection.10.4.4.3}%
\contentsline {subsection}{\numberline {10.4.5}Iterations}{171}{subsection.10.4.5}%
\contentsline {subsubsection}{\numberline {10.4.5.1}For loops}{171}{subsubsection.10.4.5.1}%
\contentsline {subsubsection}{\numberline {10.4.5.2}Other iterations: while}{172}{subsubsection.10.4.5.2}%
\contentsline {subsection}{\numberline {10.4.6}Functions}{172}{subsection.10.4.6}%
\contentsline {subsubsection}{\numberline {10.4.6.1}Export functions: about modules}{173}{subsubsection.10.4.6.1}%
\contentsline {subsection}{\numberline {10.4.7}JS code compatibility}{173}{subsection.10.4.7}%
\contentsline {subsection}{\numberline {10.4.8}Event listeners}{173}{subsection.10.4.8}%
\contentsline {section}{\numberline {10.5}jQuery}{174}{section.10.5}%
\contentsline {subsection}{\numberline {10.5.1}Introduction}{174}{subsection.10.5.1}%
\contentsline {subsection}{\numberline {10.5.2}Syntax}{174}{subsection.10.5.2}%
\contentsline {subsection}{\numberline {10.5.3}Good practice}{175}{subsection.10.5.3}%
\contentsline {subsection}{\numberline {10.5.4}Useful functions}{176}{subsection.10.5.4}%
\contentsline {subsubsection}{\numberline {10.5.4.1}Travel in the DOM}{176}{subsubsection.10.5.4.1}%
\contentsline {subsubsection}{\numberline {10.5.4.2}Manipulate tags}{176}{subsubsection.10.5.4.2}%
\contentsline {subsection}{\numberline {10.5.5}Chaining jQuery methods}{177}{subsection.10.5.5}%
\contentsline {subsection}{\numberline {10.5.6}Iterations}{177}{subsection.10.5.6}%
\contentsline {subsection}{\numberline {10.5.7}Events}{178}{subsection.10.5.7}%
\contentsline {subsection}{\numberline {10.5.8}Extending objects}{178}{subsection.10.5.8}%
\contentsline {section}{\numberline {10.6}Shiny, JavaScript and the HTML inspector}{179}{section.10.6}%
\contentsline {subsection}{\numberline {10.6.1}The console panel}{179}{subsection.10.6.1}%
\contentsline {subsubsection}{\numberline {10.6.1.1}A real REPL}{179}{subsubsection.10.6.1.1}%
\contentsline {subsubsection}{\numberline {10.6.1.2}Track errors and warnings}{179}{subsubsection.10.6.1.2}%
\contentsline {subsection}{\numberline {10.6.2}Debug Shiny/JS code with the inspector}{180}{subsection.10.6.2}%
\contentsline {subsection}{\numberline {10.6.3}The Shiny JavaScript object}{182}{subsection.10.6.3}%
\contentsline {section}{\numberline {10.7}Exercises}{183}{section.10.7}%
\contentsline {subsection}{\numberline {10.7.1}Exercise 1: define variables}{184}{subsection.10.7.1}%
\contentsline {subsection}{\numberline {10.7.2}Exercise 2: define objects}{184}{subsection.10.7.2}%
\contentsline {subsection}{\numberline {10.7.3}Exercise 3: jQuery}{184}{subsection.10.7.3}%
\contentsline {subsection}{\numberline {10.7.4}Exercise 4: a pure JS action button}{185}{subsection.10.7.4}%
\contentsline {chapter}{\numberline {11}Communicate between R and JS}{187}{chapter.11}%
\contentsline {section}{\numberline {11.1}Introductory example}{187}{section.11.1}%
\contentsline {section}{\numberline {11.2}JSON: exhange data}{187}{section.11.2}%
\contentsline {subsection}{\numberline {11.2.1}Process JSON from R}{188}{subsection.11.2.1}%
\contentsline {subsection}{\numberline {11.2.2}Process JSON from JS}{190}{subsection.11.2.2}%
\contentsline {section}{\numberline {11.3}What is a websocket?}{190}{section.11.3}%
\contentsline {subsection}{\numberline {11.3.1}Example}{193}{subsection.11.3.1}%
\contentsline {subsubsection}{\numberline {11.3.1.1}Create the app}{193}{subsubsection.11.3.1.1}%
\contentsline {paragraph}{\numberline {11.3.1.1.1}Handle the websocket server}{194}{paragraph.11.3.1.1.1}%
\contentsline {paragraph}{\numberline {11.3.1.1.2}Handle the HTTP response}{195}{paragraph.11.3.1.1.2}%
\contentsline {subsubsection}{\numberline {11.3.1.2}Design the page content}{195}{subsubsection.11.3.1.2}%
\contentsline {subsection}{\numberline {11.3.2}Test it!}{197}{subsection.11.3.2}%
\contentsline {section}{\numberline {11.4}Client concurrency}{198}{section.11.4}%
\contentsline {section}{\numberline {11.5}Shiny and websockets}{199}{section.11.5}%
\contentsline {subsection}{\numberline {11.5.1}The Shiny session object}{199}{subsection.11.5.1}%
\contentsline {subsection}{\numberline {11.5.2}Server side}{199}{subsection.11.5.2}%
\contentsline {subsection}{\numberline {11.5.3}Client side}{200}{subsection.11.5.3}%
\contentsline {subsection}{\numberline {11.5.4}Debug websocket with Shiny}{202}{subsection.11.5.4}%
\contentsline {chapter}{\numberline {12}Understand and develop new Shiny inputs}{205}{chapter.12}%
\contentsline {section}{\numberline {12.1}Input bindings}{206}{section.12.1}%
\contentsline {subsection}{\numberline {12.1.1}Input structure}{206}{subsection.12.1.1}%
\contentsline {subsection}{\numberline {12.1.2}Binding Shiny inputs}{207}{subsection.12.1.2}%
\contentsline {subsubsection}{\numberline {12.1.2.1}Find the input}{207}{subsubsection.12.1.2.1}%
\contentsline {subsubsection}{\numberline {12.1.2.2}Initialize inputs}{210}{subsubsection.12.1.2.2}%
\contentsline {subsubsection}{\numberline {12.1.2.3}Get the value}{212}{subsubsection.12.1.2.3}%
\contentsline {subsubsection}{\numberline {12.1.2.4}Set and update}{213}{subsubsection.12.1.2.4}%
\contentsline {subsubsection}{\numberline {12.1.2.5}Subscribe}{216}{subsubsection.12.1.2.5}%
\contentsline {subsubsection}{\numberline {12.1.2.6}Setting rate policies}{219}{subsubsection.12.1.2.6}%
\contentsline {subsubsection}{\numberline {12.1.2.7}Register an input binding}{220}{subsubsection.12.1.2.7}%
\contentsline {subsubsection}{\numberline {12.1.2.8}Other binding methods}{221}{subsubsection.12.1.2.8}%
\contentsline {subsection}{\numberline {12.1.3}Edit an input binding}{221}{subsection.12.1.3}%
\contentsline {subsection}{\numberline {12.1.4}Update a binding from the client}{222}{subsection.12.1.4}%
\contentsline {section}{\numberline {12.2}Secondary inputs}{224}{section.12.2}%
\contentsline {subsection}{\numberline {12.2.1}Boxes on steroids}{224}{subsection.12.2.1}%
\contentsline {subsection}{\numberline {12.2.2}Further optimize boxes}{227}{subsection.12.2.2}%
\contentsline {subsection}{\numberline {12.2.3}Exercise}{233}{subsection.12.2.3}%
\contentsline {section}{\numberline {12.3}Utilities to quickly define new inputs}{235}{section.12.3}%
\contentsline {subsection}{\numberline {12.3.1}Introduction}{235}{subsection.12.3.1}%
\contentsline {subsection}{\numberline {12.3.2}Examples}{235}{subsection.12.3.2}%
\contentsline {section}{\numberline {12.4}Custom data format}{236}{section.12.4}%
\contentsline {subsection}{\numberline {12.4.1}The dirty way}{236}{subsection.12.4.1}%
\contentsline {subsection}{\numberline {12.4.2}The clean way: leverage \texttt {getType}}{237}{subsection.12.4.2}%
\contentsline {chapter}{\numberline {13}Shiny inputs lifecycles}{243}{chapter.13}%
\contentsline {section}{\numberline {13.1}App initialization}{243}{section.13.1}%
\contentsline {section}{\numberline {13.2}Update input}{246}{section.13.2}%
\contentsline {chapter}{\numberline {14}Mastering Shiny's events}{249}{chapter.14}%
\contentsline {section}{\numberline {14.1}Get the last changed input}{249}{section.14.1}%
\contentsline {subsection}{\numberline {14.1.1}Motivations}{249}{subsection.14.1.1}%
\contentsline {subsection}{\numberline {14.1.2}Invoke JS events}{250}{subsection.14.1.2}%
\contentsline {subsection}{\numberline {14.1.3}Practical example}{252}{subsection.14.1.3}%
\contentsline {subsection}{\numberline {14.1.4}About \texttt {\{shinylogs\}}}{252}{subsection.14.1.4}%
\contentsline {section}{\numberline {14.2}Custom overlay screens}{252}{section.14.2}%
\contentsline {subsection}{\numberline {14.2.1}Preloader}{253}{subsection.14.2.1}%
\contentsline {subsection}{\numberline {14.2.2}Load on busy}{253}{subsection.14.2.2}%
\contentsline {chapter}{\numberline {15}Optimize your apps with custom handlers}{255}{chapter.15}%
\contentsline {section}{\numberline {15.1}Introduction}{255}{section.15.1}%
\contentsline {section}{\numberline {15.2}The renderUI case}{255}{section.15.2}%
\contentsline {section}{\numberline {15.3}Other Shiny handlers}{256}{section.15.3}%
\contentsline {subsection}{\numberline {15.3.1}The insertUI case}{256}{subsection.15.3.1}%
\contentsline {subsection}{\numberline {15.3.2}Example}{258}{subsection.15.3.2}%
\contentsline {section}{\numberline {15.4}Custom handlers}{260}{section.15.4}%
\contentsline {subsection}{\numberline {15.4.1}Theory}{260}{subsection.15.4.1}%
\contentsline {subsection}{\numberline {15.4.2}Toward custom UI management functions}{262}{subsection.15.4.2}%
\contentsline {subsubsection}{\numberline {15.4.2.1}An insertMessageItem function}{262}{subsubsection.15.4.2.1}%
\contentsline {subsubsection}{\numberline {15.4.2.2}A chat system for \{shinydashboardPlus\}}{264}{subsubsection.15.4.2.2}%
\contentsline {paragraph}{\numberline {15.4.2.2.1}HTML elements}{264}{paragraph.15.4.2.2.1}%
\contentsline {paragraph}{\numberline {15.4.2.2.2}Handle interactions}{266}{paragraph.15.4.2.2.2}%
\contentsline {chapter}{\numberline {16}Define dependencies}{275}{chapter.16}%
\contentsline {section}{\numberline {16.1}Introduction}{275}{section.16.1}%
\contentsline {section}{\numberline {16.2}Discover the project}{276}{section.16.2}%
\contentsline {section}{\numberline {16.3}Identify mandatory dependencies}{276}{section.16.3}%
\contentsline {section}{\numberline {16.4}Bundle dependencies}{277}{section.16.4}%
\contentsline {chapter}{\numberline {17}Create template elements}{281}{chapter.17}%
\contentsline {section}{\numberline {17.1}Identify template elements}{281}{section.17.1}%
\contentsline {section}{\numberline {17.2}Design the page layout}{282}{section.17.2}%
\contentsline {subsection}{\numberline {17.2.1}The page wrapper}{282}{subsection.17.2.1}%
\contentsline {subsection}{\numberline {17.2.2}The body content}{284}{subsection.17.2.2}%
\contentsline {subsection}{\numberline {17.2.3}The footer}{284}{subsection.17.2.3}%
\contentsline {subsection}{\numberline {17.2.4}The navbar (or header)}{285}{subsection.17.2.4}%
\contentsline {subsubsection}{\numberline {17.2.4.1}Navbar navigation}{288}{subsubsection.17.2.4.1}%
\contentsline {subsubsection}{\numberline {17.2.4.2}Fine-tune tabs behavior}{290}{subsubsection.17.2.4.2}%
\contentsline {subsection}{\numberline {17.2.5}Card containers}{291}{subsection.17.2.5}%
\contentsline {subsubsection}{\numberline {17.2.5.1}Classic card}{291}{subsubsection.17.2.5.1}%
\contentsline {subsection}{\numberline {17.2.6}Ribbons: card components}{293}{subsection.17.2.6}%
\contentsline {subsection}{\numberline {17.2.7}Icons}{295}{subsection.17.2.7}%
\contentsline {section}{\numberline {17.3}Exercises}{295}{section.17.3}%
\contentsline {chapter}{\numberline {18}Develop custom input widgets}{297}{chapter.18}%
\contentsline {section}{\numberline {18.1}Tabler action button}{297}{section.18.1}%
\contentsline {subsection}{\numberline {18.1.1}Reminders about the action button}{297}{subsection.18.1.1}%
\contentsline {subsection}{\numberline {18.1.2}Application to Tabler}{298}{subsection.18.1.2}%
\contentsline {section}{\numberline {18.2}Toggle Switch}{299}{section.18.2}%
\contentsline {section}{\numberline {18.3}Navbar menu input}{301}{section.18.3}%
\contentsline {section}{\numberline {18.4}Exercises}{304}{section.18.4}%
\contentsline {chapter}{\numberline {19}Adding more interactivity}{307}{chapter.19}%
\contentsline {section}{\numberline {19.1}Custom progress bars}{307}{section.19.1}%
\contentsline {section}{\numberline {19.2}User feedback: toasts}{310}{section.19.2}%
\contentsline {subsection}{\numberline {19.2.1}Toast skeleton}{310}{subsection.19.2.1}%
\contentsline {subsection}{\numberline {19.2.2}The toast API}{311}{subsection.19.2.2}%
\contentsline {subsection}{\numberline {19.2.3}R implementation}{311}{subsection.19.2.3}%
\contentsline {subsection}{\numberline {19.2.4}Exercise}{313}{subsection.19.2.4}%
\contentsline {section}{\numberline {19.3}Transform an element in a custom action button}{313}{section.19.3}%
\contentsline {section}{\numberline {19.4}Tab events}{316}{section.19.4}%
\contentsline {subsection}{\numberline {19.4.1}Insert/remove tabs in tabsetpanel}{316}{subsection.19.4.1}%
\contentsline {subsection}{\numberline {19.4.2}Exercise}{320}{subsection.19.4.2}%
\contentsline {chapter}{\numberline {20}Testing and validating template elements}{323}{chapter.20}%
\contentsline {section}{\numberline {20.1}Validate template functions}{323}{section.20.1}%
\contentsline {subsection}{\numberline {20.1.1}Create your own validations}{323}{subsection.20.1.1}%
\contentsline {subsection}{\numberline {20.1.2}Existing utils functions}{326}{subsection.20.1.2}%
\contentsline {subsubsection}{\numberline {20.1.2.1}Validating tags}{326}{subsubsection.20.1.2.1}%
\contentsline {subsubsection}{\numberline {20.1.2.2}Validating CSS units}{326}{subsubsection.20.1.2.2}%
\contentsline {subsection}{\numberline {20.1.3}Example: refine navbar menu items}{327}{subsection.20.1.3}%
\contentsline {subsubsection}{\numberline {20.1.3.1}Avoid wrong jQuery selectors}{327}{subsubsection.20.1.3.1}%
\contentsline {subsubsection}{\numberline {20.1.3.2}Checking for multiple selected items}{328}{subsubsection.20.1.3.2}%
\contentsline {section}{\numberline {20.2}Testing templates elements}{329}{section.20.2}%
\contentsline {subsection}{\numberline {20.2.1}Caveats}{330}{subsection.20.2.1}%
\contentsline {subsection}{\numberline {20.2.2}Testing template behavior}{331}{subsection.20.2.2}%
\contentsline {subsubsection}{\numberline {20.2.2.1}R side}{331}{subsubsection.20.2.2.1}%
\contentsline {subsubsection}{\numberline {20.2.2.2}JS side}{333}{subsubsection.20.2.2.2}%
\contentsline {subsection}{\numberline {20.2.3}Test input bindings}{336}{subsection.20.2.3}%
\contentsline {chapter}{\numberline {21}Automate new template creation with \{charpente\}}{343}{chapter.21}%
\contentsline {section}{\numberline {21.1}Motivations}{343}{section.21.1}%
\contentsline {section}{\numberline {21.2}General idea}{344}{section.21.2}%
\contentsline {section}{\numberline {21.3}A case study: \texttt {\{shinybulma\}}}{344}{section.21.3}%
\contentsline {subsection}{\numberline {21.3.1}Build the HTML dependency}{345}{subsection.21.3.1}%
\contentsline {subsection}{\numberline {21.3.2}Set up the minimal page template}{348}{subsection.21.3.2}%
\contentsline {subsection}{\numberline {21.3.3}Exercise: add bulmaJS}{350}{subsection.21.3.3}%
\contentsline {subsection}{\numberline {21.3.4}Add custom JS}{351}{subsection.21.3.4}%
\contentsline {subsection}{\numberline {21.3.5}Add custom input/output bindings}{352}{subsection.21.3.5}%
\contentsline {subsection}{\numberline {21.3.6}Organize your JS code}{353}{subsection.21.3.6}%
\contentsline {subsection}{\numberline {21.3.7}Combine multiple dependencies}{355}{subsection.21.3.7}%
\contentsline {subsection}{\numberline {21.3.8}Other \texttt {\{charpente\}} helpers}{355}{subsection.21.3.8}%
\contentsline {section}{\numberline {21.4}Other tips}{358}{section.21.4}%
\contentsline {subsection}{\numberline {21.4.1}Validate JavaScript}{358}{subsection.21.4.1}%
\contentsline {subsection}{\numberline {21.4.2}Test JS code}{359}{subsection.21.4.2}%
\contentsline {subsection}{\numberline {21.4.3}Beautify JS code}{360}{subsection.21.4.3}%
\contentsline {chapter}{\numberline {22}Introduction}{363}{chapter.22}%
\contentsline {section}{\numberline {22.1}Case study objectives}{363}{section.22.1}%
\contentsline {section}{\numberline {22.2}About mobile development}{364}{section.22.2}%
\contentsline {section}{\numberline {22.3}Progressive web apps}{364}{section.22.3}%
\contentsline {subsection}{\numberline {22.3.1}Introduction}{364}{subsection.22.3.1}%
\contentsline {subsection}{\numberline {22.3.2}What does ``installable'' mean?}{364}{subsection.22.3.2}%
\contentsline {subsection}{\numberline {22.3.3}How to develop a PWA?}{365}{subsection.22.3.3}%
\contentsline {chapter}{\numberline {23}Reconstruct \texttt {\{shinyMobile\}}}{367}{chapter.23}%
\contentsline {section}{\numberline {23.1}Introduction to Framework7}{367}{section.23.1}%
\contentsline {section}{\numberline {23.2}Initiate the package}{367}{section.23.2}%
\contentsline {section}{\numberline {23.3}Framework7 layouts}{369}{section.23.3}%
\contentsline {section}{\numberline {23.4}App initialization}{373}{section.23.4}%
\contentsline {section}{\numberline {23.5}App configuration}{375}{section.23.5}%
\contentsline {subsection}{\numberline {23.5.1}Global theme}{375}{subsection.23.5.1}%
\contentsline {subsection}{\numberline {23.5.2}Events}{375}{subsection.23.5.2}%
\contentsline {subsection}{\numberline {23.5.3}Components configuration}{376}{subsection.23.5.3}%
\contentsline {subsection}{\numberline {23.5.4}Allow end-user configuration}{377}{subsection.23.5.4}%
\contentsline {subsection}{\numberline {23.5.5}Modify configuration}{379}{subsection.23.5.5}%
\contentsline {subsection}{\numberline {23.5.6}Global data and methods}{379}{subsection.23.5.6}%
\contentsline {subsection}{\numberline {23.5.7}Other elements}{380}{subsection.23.5.7}%
\contentsline {section}{\numberline {23.6}Theming and colors}{382}{section.23.6}%
\contentsline {section}{\numberline {23.7}Modularize JS code}{386}{section.23.7}%
\contentsline {section}{\numberline {23.8}Exercise}{387}{section.23.8}%
\contentsline {chapter}{\numberline {24}\texttt {\{shinyMobile\}} and PWA}{389}{chapter.24}%
\contentsline {section}{\numberline {24.1}Introduction}{389}{section.24.1}%
\contentsline {section}{\numberline {24.2}\texttt {\{charpente\}} and PWA tools}{391}{section.24.2}%
\contentsline {subsection}{\numberline {24.2.1}Create the manifest}{392}{subsection.24.2.1}%
\contentsline {subsection}{\numberline {24.2.2}Google PWA compatibility}{394}{subsection.24.2.2}%
\contentsline {subsection}{\numberline {24.2.3}Service worker and offline page}{395}{subsection.24.2.3}%
\contentsline {subsubsection}{\numberline {24.2.3.1}Installation}{396}{subsubsection.24.2.3.1}%
\contentsline {subsubsection}{\numberline {24.2.3.2}Activation}{397}{subsubsection.24.2.3.2}%
\contentsline {subsubsection}{\numberline {24.2.3.3}Fetch}{397}{subsubsection.24.2.3.3}%
\contentsline {subsubsection}{\numberline {24.2.3.4}Registration}{399}{subsubsection.24.2.3.4}%
\contentsline {subsubsection}{\numberline {24.2.3.5}Offline fallback}{399}{subsubsection.24.2.3.5}%
\contentsline {subsection}{\numberline {24.2.4}Disable PWA for the end user}{400}{subsection.24.2.4}%
\contentsline {section}{\numberline {24.3}Handle the installation}{402}{section.24.3}%
\contentsline {section}{\numberline {24.4}Other resources}{406}{section.24.4}%
\contentsline {chapter}{\numberline {25}Design widgets}{407}{chapter.25}%
\contentsline {section}{\numberline {25.1}Build the UI}{408}{section.25.1}%
\contentsline {section}{\numberline {25.2}Widgets without preexisting UI}{409}{section.25.2}%
\contentsline {section}{\numberline {25.3}Initialize the widget}{409}{section.25.3}%
\contentsline {section}{\numberline {25.4}Update widgets}{412}{section.25.4}%
\contentsline {section}{\numberline {25.5}More complex elements}{417}{section.25.5}%
\contentsline {subsection}{\numberline {25.5.1}Add a tooltip}{417}{subsection.25.5.1}%
\contentsline {subsection}{\numberline {25.5.2}Update a tooltip}{419}{subsection.25.5.2}%
\contentsline {chapter}{\numberline {26}Fine-tune \{shinyMobile\}}{423}{chapter.26}%
\contentsline {section}{\numberline {26.1}Enhance the disconnect screen}{423}{section.26.1}%
\contentsline {chapter}{\numberline {27}Shiny and React with \{reactR\}}{429}{chapter.27}%
\contentsline {section}{\numberline {27.1}Quick introduction to React}{430}{section.27.1}%
\contentsline {subsection}{\numberline {27.1.1}Setup}{430}{subsection.27.1.1}%
\contentsline {subsection}{\numberline {27.1.2}Basics}{431}{subsection.27.1.2}%
\contentsline {subsubsection}{\numberline {27.1.2.1}About JSX}{432}{subsubsection.27.1.2.1}%
\contentsline {subsubsection}{\numberline {27.1.2.2}Combining components}{433}{subsubsection.27.1.2.2}%
\contentsline {subsubsection}{\numberline {27.1.2.3}Component state}{433}{subsubsection.27.1.2.3}%
\contentsline {section}{\numberline {27.2}Introduction to \texttt {\{reactR\}}}{435}{section.27.2}%
\contentsline {subsection}{\numberline {27.2.1}Setup}{435}{subsection.27.2.1}%
\contentsline {subsection}{\numberline {27.2.2}Customize the R logic}{437}{subsection.27.2.2}%
\contentsline {subsection}{\numberline {27.2.3}Implement the JS logic}{438}{subsection.27.2.3}%
\contentsline {subsection}{\numberline {27.2.4}Improve the JS logic}{439}{subsection.27.2.4}%
\contentsline {subsection}{\numberline {27.2.5}Exercise 1}{440}{subsection.27.2.5}%
\contentsline {subsection}{\numberline {27.2.6}Technical considerations}{440}{subsection.27.2.6}%
\contentsline {subsection}{\numberline {27.2.7}Exercise 2}{442}{subsection.27.2.7}%
\contentsline {subsection}{\numberline {27.2.8}Add another input}{442}{subsection.27.2.8}%
\contentsline {subsubsection}{\numberline {27.2.8.1}Button group input}{442}{subsubsection.27.2.8.1}%
\contentsline {subsubsection}{\numberline {27.2.8.2}Modularize JS code}{444}{subsubsection.27.2.8.2}%
\contentsline {section}{\numberline {27.3}Further resources}{445}{section.27.3}%
\contentsline {chapter}{\numberline {28}Shiny and modern web development}{447}{chapter.28}%
\contentsline {section}{\numberline {28.1}Motivations}{447}{section.28.1}%
\contentsline {section}{\numberline {28.2}State of the art}{447}{section.28.2}%
\contentsline {section}{\numberline {28.3}About the project}{449}{section.28.3}%
\contentsline {subsection}{\numberline {28.3.1}Topic}{449}{subsection.28.3.1}%
\contentsline {subsection}{\numberline {28.3.2}Initialize the project}{449}{subsection.28.3.2}%
\contentsline {subsection}{\numberline {28.3.3}UI design}{449}{subsection.28.3.3}%
\contentsline {subsection}{\numberline {28.3.4}R business logic}{450}{subsection.28.3.4}%
\contentsline {subsection}{\numberline {28.3.5}Add Shiny}{453}{subsection.28.3.5}%
\contentsline {subsection}{\numberline {28.3.6}Create the interface}{453}{subsection.28.3.6}%
\contentsline {subsubsection}{\numberline {28.3.6.1}Setup dev JS dependencies}{454}{subsubsection.28.3.6.1}%
\contentsline {subsubsection}{\numberline {28.3.6.2}Basic R UI skeleton}{456}{subsubsection.28.3.6.2}%
\contentsline {subsubsection}{\numberline {28.3.6.3}Create the app layout in JS}{457}{subsubsection.28.3.6.3}%
\contentsline {subsubsection}{\numberline {28.3.6.4}Plot model data with echartsjs}{463}{subsubsection.28.3.6.4}%
\contentsline {subsubsection}{\numberline {28.3.6.5}Exercise: add the phase portrait}{465}{subsubsection.28.3.6.5}%
\contentsline {section}{\numberline {28.4}Final product}{470}{section.28.4}%
\contentsline {chapter}{\numberline {29}What to do next?}{471}{chapter.29}%
\contentsline {section}{\numberline {29.1}Multi-page Shiny apps}{471}{section.29.1}%
\contentsline {section}{\numberline {29.2}Web design best practices for Shiny}{472}{section.29.2}%
\contentsline {section}{\numberline {29.3}Conclusion}{472}{section.29.3}%
\contentsline {chapter}{Appendix}{472}{section.29.3}%
\contentsline {chapter}{\numberline {A}Code outputs}{473}{appendix.A}%
\contentsline {section}{\numberline {A.1}Mastering \{htmltools\}}{473}{section.A.1}%
\contentsline {subsection}{\numberline {A.1.1}Shiny RPG rework}{473}{subsection.A.1.1}%
\contentsline {section}{\numberline {A.2}Case Study 2: Mobile development with Shiny}{473}{section.A.2}%
\contentsline {subsection}{\numberline {A.2.1}Reconstruct \{shinyMobile\}}{473}{subsection.A.2.1}%
\contentsline {section}{\numberline {A.3}R + Shiny + React: welcome \texttt {\{reactR\}}}{476}{section.A.3}%
\contentsline {subsection}{\numberline {A.3.1}Introduction to \texttt {\{reactR\}}}{476}{subsection.A.3.1}%
\contentsline {subsubsection}{\numberline {A.3.1.1}Exercise 2}{476}{subsubsection.A.3.1.1}%
\contentsline {fm}{Bibliography}{477}{appendix*.209}%