From 61b2d289e11ab442c3ae3037e582f1fcea9323f5 Mon Sep 17 00:00:00 2001 From: Jiena McLellan Date: Mon, 6 Jul 2020 15:11:21 -0400 Subject: [PATCH] first commit --- .Rbuildignore | 3 ++ .gitignore | 1 + DESCRIPTION | 18 ++++++++++ LICENSE | 2 ++ NAMESPACE | 6 ++++ R/faq.R | 60 ++++++++++++++++++++++++++++++++++ README.Rmd | 45 +++++++++++++++++++++++++ README.md | 44 +++++++++++++++++++++++++ faq.Rproj | 21 ++++++++++++ inst/htmlwidgets/faq.js | 60 ++++++++++++++++++++++++++++++++++ inst/htmlwidgets/faq.yaml | 6 ++++ inst/htmlwidgets/lib/style.css | 48 +++++++++++++++++++++++++++ man/faq-shiny.Rd | 30 +++++++++++++++++ man/faq.Rd | 28 ++++++++++++++++ vignettes/Intro-faq.Rmd | 34 +++++++++++++++++++ 15 files changed, 406 insertions(+) create mode 100644 .Rbuildignore create mode 100644 .gitignore create mode 100644 DESCRIPTION create mode 100644 LICENSE create mode 100644 NAMESPACE create mode 100644 R/faq.R create mode 100644 README.Rmd create mode 100644 README.md create mode 100644 faq.Rproj create mode 100644 inst/htmlwidgets/faq.js create mode 100644 inst/htmlwidgets/faq.yaml create mode 100644 inst/htmlwidgets/lib/style.css create mode 100644 man/faq-shiny.Rd create mode 100644 man/faq.Rd create mode 100644 vignettes/Intro-faq.Rmd diff --git a/.Rbuildignore b/.Rbuildignore new file mode 100644 index 0000000..37fa9a4 --- /dev/null +++ b/.Rbuildignore @@ -0,0 +1,3 @@ +^faq\.Rproj$ +^\.Rproj\.user$ +^README\.Rmd$ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cd67eac --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.Rproj.user diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100644 index 0000000..b9e823d --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1,18 @@ +Package: faq +Title: Create faq page +Version: 0.1.0 +Authors@R: + person(given = "Jiena", + family = "McLellan", + role = c("aut", "cre"), + email = "jienagu90@gmail.com", + comment = c(ORCID = "YOUR-ORCID-ID")) +Description: Create Frequently Asked Questions page for Shiny application. +Suggests: knitr, rmarkdown +VignetteBuilder: knitr +License: MIT + file LICENSE +Imports: + htmlwidgets +Encoding: UTF-8 +LazyData: true +RoxygenNote: 7.0.2 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..aed8054 --- /dev/null +++ b/LICENSE @@ -0,0 +1,2 @@ +YEAR: 2020 +COPYRIGHT HOLDER: Jiena Gu McLellan diff --git a/NAMESPACE b/NAMESPACE new file mode 100644 index 0000000..e3a01ca --- /dev/null +++ b/NAMESPACE @@ -0,0 +1,6 @@ +# Generated by roxygen2: do not edit by hand + +export(faq) +export(faqOutput) +export(renderFaq) +import(htmlwidgets) diff --git a/R/faq.R b/R/faq.R new file mode 100644 index 0000000..17985b0 --- /dev/null +++ b/R/faq.R @@ -0,0 +1,60 @@ +#' FAQ page +#' +#' Create FAQ page +#' +#' @param data df with question and answer columns +#' @param width width of this widget +#' @param height height of this widget +#' @param elementId ellement ID of this widget +#' @param title title for this widgets +#' +#' @import htmlwidgets +#' +#' @export +faq <- function(data, width = NULL, height = NULL, elementId = NULL, + title = "Frequently Asked Questions") { + + # forward options using x + x = list( + data = htmlwidgets:::toJSON(data), + title = title + ) + + # create widget + htmlwidgets::createWidget( + name = 'faq', + x, + width = width, + height = height, + package = 'faq', + elementId = elementId + ) +} + +#' Shiny bindings for faq +#' +#' Output and render functions for using faq within Shiny +#' applications and interactive Rmd documents. +#' +#' @param outputId output variable to read from +#' @param width,height Must be a valid CSS unit (like \code{'100\%'}, +#' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a +#' string and have \code{'px'} appended. +#' @param expr An expression that generates a faq +#' @param env The environment in which to evaluate \code{expr}. +#' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This +#' is useful if you want to save an expression in a variable. +#' +#' @name faq-shiny +#' +#' @export +faqOutput <- function(outputId, width = '100%', height = '400px'){ + htmlwidgets::shinyWidgetOutput(outputId, 'faq', width, height, package = 'faq') +} + +#' @rdname faq-shiny +#' @export +renderFaq <- function(expr, env = parent.frame(), quoted = FALSE) { + if (!quoted) { expr <- substitute(expr) } # force quoted + htmlwidgets::shinyRenderWidget(expr, faqOutput, env, quoted = TRUE) +} diff --git a/README.Rmd b/README.Rmd new file mode 100644 index 0000000..ccc10d0 --- /dev/null +++ b/README.Rmd @@ -0,0 +1,45 @@ +--- +output: github_document +always_allow_html: true +--- + + + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + fig.path = "man/figures/README-", + out.width = "100%" +) +``` + +# faq + + + + +This is package is to create a FAQ (Frequently Asked Questions) page for Shiny application with desired data.frame. + + +## Installation + +``` r +install.packages("faq") +``` + +## Introduction + +Simply create a data frame with `question` column and `answer` column. Then put this data frame into `faq()` function, we will get a nice FAQ page. + +```{r ex1} +library(faq) +df <- data.frame( + question = c("Question1", "Question2", "Question3"), + answer = c("answer for question1", + "question2 answer", + "answer3") +) +faq::faq(data = df, elementId = "faq", title = "Frequently Asked Questions") +``` + diff --git a/README.md b/README.md new file mode 100644 index 0000000..b119258 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ + + + +# faq + + + + + +This is package is to create a FAQ (Frequently Asked Questions) page for +Shiny application with desired data.frame. + +## Installation + +``` r +install.packages("faq") +``` + +## Introduction + +Simply create a data frame with `question` column and `answer` column. +Then put this data frame into `faq()` function, we will get a nice FAQ +page. + +``` r +library(faq) +df <- data.frame( + question = c("Question1", "Question2", "Question3"), + answer = c("answer for question1", + "question2 answer", + "answer3") +) +faq::faq(data = df, elementId = "faq", title = "Frequently Asked Questions") +``` + + + +
+ +
+ + + + diff --git a/faq.Rproj b/faq.Rproj new file mode 100644 index 0000000..cba1b6b --- /dev/null +++ b/faq.Rproj @@ -0,0 +1,21 @@ +Version: 1.0 + +RestoreWorkspace: No +SaveWorkspace: No +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX + +AutoAppendNewline: Yes +StripTrailingWhitespace: Yes + +BuildType: Package +PackageUseDevtools: Yes +PackageInstallArgs: --no-multiarch --with-keep.source +PackageRoxygenize: rd,collate,namespace diff --git a/inst/htmlwidgets/faq.js b/inst/htmlwidgets/faq.js new file mode 100644 index 0000000..476b95f --- /dev/null +++ b/inst/htmlwidgets/faq.js @@ -0,0 +1,60 @@ +HTMLWidgets.widget({ + + name: 'faq', + + type: 'output', + + factory: function(el, width, height) { + + return { + + renderValue: function(x) { + + faq(el, x); + + }, + + resize: function(width, height) {} + + }; + } +}); + + +function faq(el, x){ + var jsonData = x.data + +var faq = document.getElementById(el.id); +var title = document.createElement("H1"); +var titletext = document.createTextNode(x.title); +title.appendChild(titletext); +faq.appendChild(title); + +for (var i = 0; i < jsonData.answer.length; i++) { + + let wrapperdiv = document.createElement("div"); + wrapperdiv.classList.add("wrapper"); + let contentdiv = document.createElement("div"); + contentdiv.classList.add("content"); + let ptag = document.createElement("p"); + ptag.innerHTML = jsonData.answer[i]; + contentdiv.appendChild(ptag); + + let questiondiv = document.createElement("button"); + questiondiv.classList.add("collapsible"); + questiondiv.innerHTML = jsonData.question[i]; + + questiondiv.addEventListener("click", function() { + this.classList.toggle("active"); + var content = this.nextElementSibling; + if (content.style.maxHeight){ + content.style.maxHeight = null; + } else { + content.style.maxHeight = content.scrollHeight + "px"; + } + }); + wrapperdiv.appendChild(questiondiv); + wrapperdiv.appendChild(contentdiv); + faq.appendChild(wrapperdiv); +} +} diff --git a/inst/htmlwidgets/faq.yaml b/inst/htmlwidgets/faq.yaml new file mode 100644 index 0000000..38746b4 --- /dev/null +++ b/inst/htmlwidgets/faq.yaml @@ -0,0 +1,6 @@ +dependencies: + - name: faq + version: 0.1.0 + src: htmlwidgets/lib + style: + - style.css diff --git a/inst/htmlwidgets/lib/style.css b/inst/htmlwidgets/lib/style.css new file mode 100644 index 0000000..dc4d75c --- /dev/null +++ b/inst/htmlwidgets/lib/style.css @@ -0,0 +1,48 @@ +.collapsible { + background-color: #F0F0F0; + color: black; + cursor: pointer; + padding: 38px; + width: 100%; + border: 0; + font-weight: bold; + text-align: left; + outline: none; + font-size: 15px; + padding-left: 80px; +} + + +.active, .collapsible:hover { + background-color: #E8E8E8; +} + +.wrapper{ + border-bottom: 2px solid #FFF; +} + + +.collapsible:after { + content: '\002B'; + font-size: 28px; + color: black; + font-weight: bold; + position: relative; + float:left; + margin-left: -50px; + margin-right: 5px; + margin-top: -8px; +} + +.active:after { + content: "\2212"; +} + +.content { + padding-left: 80px; + padding-right:20px; + max-height: 0; + overflow: hidden; + transition: max-height 0.2s ease-out; + background-color: #f0f0f0; +} diff --git a/man/faq-shiny.Rd b/man/faq-shiny.Rd new file mode 100644 index 0000000..264bd3b --- /dev/null +++ b/man/faq-shiny.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/faq.R +\name{faq-shiny} +\alias{faq-shiny} +\alias{faqOutput} +\alias{renderFaq} +\title{Shiny bindings for faq} +\usage{ +faqOutput(outputId, width = "100\%", height = "400px") + +renderFaq(expr, env = parent.frame(), quoted = FALSE) +} +\arguments{ +\item{outputId}{output variable to read from} + +\item{width, height}{Must be a valid CSS unit (like \code{'100\%'}, +\code{'400px'}, \code{'auto'}) or a number, which will be coerced to a +string and have \code{'px'} appended.} + +\item{expr}{An expression that generates a faq} + +\item{env}{The environment in which to evaluate \code{expr}.} + +\item{quoted}{Is \code{expr} a quoted expression (with \code{quote()})? This +is useful if you want to save an expression in a variable.} +} +\description{ +Output and render functions for using faq within Shiny +applications and interactive Rmd documents. +} diff --git a/man/faq.Rd b/man/faq.Rd new file mode 100644 index 0000000..0713056 --- /dev/null +++ b/man/faq.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/faq.R +\name{faq} +\alias{faq} +\title{FAQ page} +\usage{ +faq( + data, + width = NULL, + height = NULL, + elementId = NULL, + title = "Frequently Asked Questions" +) +} +\arguments{ +\item{data}{df with question and answer columns} + +\item{width}{width of this widget} + +\item{height}{height of this widget} + +\item{elementId}{ellement ID of this widget} + +\item{title}{title for this widgets} +} +\description{ +Create FAQ page +} diff --git a/vignettes/Intro-faq.Rmd b/vignettes/Intro-faq.Rmd new file mode 100644 index 0000000..588bc5e --- /dev/null +++ b/vignettes/Intro-faq.Rmd @@ -0,0 +1,34 @@ +--- +title: "Introduction to faq" +author: "Jiena Gu McLellan" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Introduction to faq} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +This is package is to create a FAQ (Frequently Asked Questions) page for Shiny application with desired data.frame. + +## Introduction + +Simply create a data frame with `question` column and `answer` column. Then put this data frame into `faq()` function, we will get a nice FAQ page. + +```{r ex1} +df <- data.frame( + question = c("Question1", "Question2", "Question3"), + answer = c("answer for question1", + "question2 answer", + "answer3") +) +faq(data = df, elementId = "faq", title = "Frequently Asked Questions") +``` +