% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/form_schema.R
\name{form_schema}
\alias{form_schema}
\title{Show the schema of one form.}
\usage{
form_schema(
  flatten = FALSE,
  odata = FALSE,
  parse = TRUE,
  draft = FALSE,
  pid = get_default_pid(),
  fid = get_default_fid(),
  url = get_default_url(),
  un = get_default_un(),
  pw = get_default_pw(),
  odkc_version = get_default_odkc_version(),
  retries = get_retries(),
  verbose = get_ru_verbose()
)
}
\arguments{
\item{flatten}{Whether to flatten the resulting list of lists (TRUE) or not
(FALSE, default). Only applies to ODK Central version < 0.8.}

\item{odata}{Whether to sanitise the field names to match the way they will
be outputted for OData. While the original field names as given in the
XForms definition may be used as-is for CSV output, OData has some
restrictions related to the domain-qualified identifier syntax it uses.
Only applies to ODK Central version < 0.8.
Default: FALSE.}

\item{parse}{Whether to parse the form schema into a tibble of form field
type and name. This uses \code{\link{form_schema_parse}} internally.
If used together with \code{flatten=TRUE}, \code{\link{form_schema}} will raise
a warning and return the unparsed, flattened form schema.
Only applies to ODK Central version < 0.8.
Default: TRUE.}

\item{draft}{Whether the form is published (FALSE) or a draft (TRUE).
Default: TRUE.}

\item{pid}{The numeric ID of the project, e.g.: 2.

Default: \code{\link{get_default_pid}}.

Set default \code{pid} through \code{ru_setup(pid="...")}.

See \code{vignette("Setup", package = "ruODK")}.}

\item{fid}{The alphanumeric form ID, e.g. "build_Spotlighting-0-8_1559885147".

Default: \code{\link{get_default_fid}}.

Set default \code{fid} through \code{ru_setup(fid="...")}.

See \code{vignette("Setup", package = "ruODK")}.}

\item{url}{The ODK Central base URL without trailing slash.

Default: \code{\link{get_default_url}}.

Set default \code{url} through \code{ru_setup(url="...")}.

See \code{vignette("Setup", package = "ruODK")}.}

\item{un}{The ODK Central username (an email address).
Default: \code{\link{get_default_un}}.
Set default \code{un} through \code{ru_setup(un="...")}.
See \code{vignette("Setup", package = "ruODK")}.}

\item{pw}{The ODK Central password.
Default: \code{\link{get_default_pw}}.
Set default \code{pw} through \code{ru_setup(pw="...")}.
See \code{vignette("Setup", package = "ruODK")}.}

\item{odkc_version}{The ODK Central version as a semantic version string
(year.minor.patch), e.g. "2023.5.1". The version is shown on ODK Central's
version page \verb{/version.txt}. Discard the "v".
\code{ruODK} uses this parameter to adjust for breaking changes in ODK Central.

Default: \code{\link{get_default_odkc_version}} or "2023.5.1" if unset.

Set default \code{get_default_odkc_version} through
\code{ru_setup(odkc_version="2023.5.1")}.

See \code{vignette("Setup", package = "ruODK")}.}

\item{retries}{The number of attempts to retrieve a web resource.

This parameter is given to \code{\link[httr]{RETRY}(times = retries)}.

Default: 3.}

\item{verbose}{Whether to display debug messages or not.

Read \code{vignette("setup", package = "ruODK")} to learn how \code{ruODK}'s
verbosity can be set globally or per function.}
}
\value{
A tibble or nested list (v0.7) containing the form definition.
At the lowest nesting level, each form field consists of a list of two
nodes, \code{name} (the underlying field name) and \code{type} (the XForms field
type, as in "string", "select1", "geopoint", "binary" and so on).
These fields are nested in lists of tuples \code{name} (the XForms screen name),
\code{children} (the fields as described above), \code{type} ("structure" for non-
repeating screens, "repeat" for repeating screens).
A list with \code{name} "meta" may precede the structure, if several metadata
fields are captured (e.g. "instanceId", form start datetimes etc.).
In all cases for ODK Central 0.8, and with default parameters
(\code{parse=TRUE}) for ODK Central 0.7, \code{\link{form_schema}} returns
a tibble with the columns:

\itemize{
\item \code{name} The field name as given in the form schema.
\item \code{type} The field type, e.g. "string", "select1", etc.
\item \code{path} The XForms path of the field,
\item \code{selectMultiple} Whether a field of type "select" is
a select multiple (\code{TRUE}). Any other types are \code{NA}.
\item \code{ruodk_name} The predicted field name as generated by
\code{\link{odata_submission_get}}, prefixed by the path, additionally
cleaned with \code{\link[janitor]{make_clean_names}} to match the
cleaned column names from \code{\link{odata_submission_rectangle}}.
}
}
\description{
\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}}
}
\details{
ODK Central has introduced a new API endpoint in version 0.8 which
returns a parsed and flattened list of fields. This replaces the nested
form schema which is challenging to parse.

While users of newer ODK Central versions (> 0.8) can ignore the legacy
support for ODK Central's earlier form schema API, users of ODK Central
version < 0.8 can set an environment variable \code{ODKC_VERSION} to their
ODKC's version in format \code{<major>.<minor>} e.g. \code{0.7}.
This variable caters for future breaking changes.

Either way, \code{\link{form_schema}} will always return a tibble with
columns \code{name}, \code{type}, \code{path} and \code{ruodk_name}.
}
\examples{
\dontrun{
# See vignette("setup") for setup and authentication options
# ruODK::ru_setup(svc = "....svc", un = "me@email.com", pw = "...")

# With explicit pid and fid
fs_defaults <- form_schema(pid = 1, fid = "build_xformsId")

# With current ODK Central (v0.8)
fs <- form_schema()

# With defaults, ODK Central v0.7
fs_nested <- form_schema(
  flatten = FALSE,
  odata = FALSE,
  parse = FALSE,
  odkc_version = 0.7
)
listviewer::jsonedit(fs_nested)

fs_flattened <- form_schema(
  flatten = TRUE,
  odata = FALSE,
  parse = FALSE,
  odkc_version = 0.7
)
listviewer::jsonedit(fs_flattened)

# form_schema returns a nested list. There's nothing to change about that.
class(fs_nested)
# > "list"

class(fs_flattened)
# > "list"

# This assumes knowledge of that exact form being tested.
# First node: type "structure" (a field group) named "meta".
fs_nested[[1]]$type
# > "structure"

fs_nested[[1]]$name
# > "meta"

# The first node contains children, which means it's an XForms field group.
names(fs_nested[[1]])
# > "name" "children" "type"

# Next node: a "meta" field of type "string" capturing the  "instanceId".
# First child node of "meta": type "string", name "instanceId".
fs_nested[[1]]$children[[1]]$type
# > "string"
fs_nested[[1]]$children[[1]]$name
# > "instanceID"

# In the flattened version, the field's and it's ancestors' names are the
# components of "path".
fs_flattened[[1]]$path
# > "meta". "instanceId"

fs_flattened[[1]]$type
# > "string"

# Last node: a "meta" field capturing the datetime of form completion
fs_flattened[[length(fs_flattened)]]$type
# > "dateTime"
fs_nested[[length(fs_nested)]]$type
# > "dateTime"

# Parsed into a tibble of form field type/name:
# Useful to inform further parsing of submission data (attachments, dates)
fs <- form_schema(parse = TRUE, odkc_version = 0.7)
fs <- form_schema(odkc_version = 0.8)

# Attachments: used by handle_ru_attachments
fs \%>\% dplyr::filter(type == "binary")

# dateTime: used by handle_ru_datetimes
fs \%>\% dplyr::filter(type == "dateTime")

# Point location: used by handle_ru_geopoints
fs \%>\% dplyr::filter(type == "geopoint")
}
}
\seealso{
\url{https://docs.getodk.org/central-api-form-management/#getting-form-schema-fields}

Other form-management: 
\code{\link{form_detail}()},
\code{\link{form_list}()},
\code{\link{form_schema_ext}()},
\code{\link{form_xml}()}
}
\concept{form-management}
