# Copyright 2010-2014 Meik Michalke <meik.michalke@hhu.de>
#
# This file is part of the R package rkwarddev.
#
# rkwarddev is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# rkwarddev is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with rkwarddev. If not, see <http://www.gnu.org/licenses/>.
#' Create XML node "optionset" for RKWard plugins
#'
#' Note that if you want to refer to the optioncolumns in your JavaScript code, the \code{id}
#' you need is a combination of \code{<optionset id>.<optioncolumn id>.<modifier>}. that is,
#' you must always prefix it with the sets' \code{id}. For JavaScript code generating with
#' \code{rkwarddev}, the easiest way to get to results is to use \code{\link[rkwarddev:rk.JS.optionset]{rk.JS.optionset}}.
#' It will automatically place your code fragments into a for loop and iterate through all available
#' rows of the set.
#'
#' If this isn't flexible enough for your needs, you can also use the ID that functions like \code{\link[rkwarddev:id]{id}}
#' return, because the JavaScript variable name will only contain a constant prefix ("ocol") and the column ID.
#'
#' @note The \code{<optionset>} node was introduced with RKWard 0.6.1, please set the dependencies
#' of your component/plugin accordingly.
#'
#' @param content A list of XiMpLe.nodes to be placed inside the \code{<content>} node of this \code{<optionset>}.
#' @param optioncolumn A list of \code{<optioncolumn>} XiMpLe.nodes.
#' @param min_rows Numeric (integer), if specified, the set will be marked invalid, unless it has
#' at least this number of rows. Ignored if set to 0.
#' @param min_rows_if_any Numeric (integer), like min_rows, but will only be tested, if there is at
#' least one row. Ignored if set to 0.
#' @param max_rows Numeric (integer), if specified, the set will be marked invalid, unless it has
#' at most this number of rows. Ignored if set to 0.
#' @param keycolumn Character
#' @param logic A valid \code{<logic>} node.
#' @param optiondisplay Logical value, can be used to automatically add an \code{<optiondisplay>} node on top
#' of the \code{<content>} section. Depending on whether it's \code{TRUE} or \code{FALSE}, its \code{index}
#' argument will be set to \code{"true"} or \code{"false"}, respectively. Set to \code{NULL} to deactivate.
#' @param id.name Character string, a unique ID for this plugin element.
#' If \code{"auto"}, an ID will be generated automatically from the <content> nodes.
#' @return An object of class \code{XiMpLe.node}.
#' @export
#' @seealso
#' \code{\link[rkwarddev:rk.XML.optioncolumn]{rk.XML.optioncolumn}},
#' \code{\link[rkwarddev:rk.XML.optiondisplay]{rk.XML.optiondisplay}},
#' \code{\link[rkwarddev:rk.JS.optionset]{rk.JS.optionset}},
#' and the \href{help:rkwardplugins}{Introduction to Writing Plugins for RKWard}
#' @examples
#' firstname <- rk.XML.input("Given name(s)")
#' lastname <- rk.XML.input("Family name")
#' genderselect <- rk.XML.radio("Gender", options=list(
#' Male = c(val="m"),
#' Female = c(val="f")))
#' (myOptionset <- rk.XML.optionset(
#' content = list(
#' rk.XML.row(
#' firstname,
#' lastname,
#' genderselect)),
#' optioncolumn = list(
#' rk.XML.optioncolumn(firstname, modifier="text"),
#' rk.XML.optioncolumn(lastname, modifier="text"),
#' rk.XML.optioncolumn(genderselect)
#' )
#' ))
rk.XML.optionset <- function(content, optioncolumn, min_rows=0, min_rows_if_any=0, max_rows=0,
keycolumn=NULL, logic=NULL, optiondisplay=TRUE, id.name="auto"){
if(identical(id.name, "auto")){
# try autogenerating some id
attr.list <- list(id=auto.ids(node.soup(content), prefix=ID.prefix("oset"), chars=10))
} else if(is.null(id.name)){
attr.list <- list()
} else {
attr.list <- list(id=id.name)
}
if(min_rows > 0){
attr.list[["min_rows"]] <- min_rows
} else {}
if(min_rows_if_any > 0){
attr.list[["min_rows_if_any"]] <- min_rows_if_any
} else {}
if(max_rows > 0){
attr.list[["max_rows"]] <- max_rows
} else {}
## TODO: do some checking -- and add support to supply XiMpLe nodes
if(!is.null(keycolumn)){
attr.list[["keycolumn"]] <- keycolumn
} else {}
content <- child.list(content)
optioncolumn <- child.list(optioncolumn)
# auto-add optiondisplay
if(!is.null(optiondisplay)){
content <- append(content, rk.XML.optiondisplay(index=optiondisplay), after=0)
} else {}
content.node <- XMLNode("content",
.children=content)
# this list will carry all child nodes of the full set
all.children <- list(content.node)
# append optioncolumns
all.children <- append(all.children, optioncolumn)
if(!is.null(logic)){
if(is.XiMpLe.node(logic) && identical(XMLName(logic), "logic")){
valid.child("logic", children=XMLChildren(logic))
} else {
stop(simpleError("'logic' must be a <logic> node!"))
}
# checks go here
} else {}
# append logic node; must be evaluated last so all objects are already defined
# but for the sake of nice code, we'll put it first
all.children <- append(all.children, logic, after=0)
node <- XMLNode("optionset",
attrs=attr.list,
.children=all.children)
# if present, store option IDs with parent ID
rk.register.options(optioncolumn, parent.node=node)
return(node)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.