A stateless server-driven user interface technology for building web interfaces through server-side user interface manipulation. 'WebForms Core' provides a common structure across multiple programming languages. The server-side class acts as a commander that generates commands, while 'WebFormsJS' serves as the client-side executor that applies them. Commands range from atomic operations, such as adding elements and modifying text and attributes, to higher-level operations such as iterative processing and render. See < https://github.com/webforms-core>.
WebForms Core (also referred to as WFC) is a server-oriented technology for manipulating web interfaces through commands.
This package is the R implementation of the WebForms Core Commander, providing the WebForms class used to generate commands for WebFormsJS.
WebForms Core is developed and maintained by Elanat.
WebForms Core consists of two main parts:
web-forms.js.The Commander can run in different environments, including server-side applications, browsers, and WebAssembly, depending on the implementation.
The Executor is loaded into the HTML document and executes the commands generated by the Commander.
Install the package from CRAN:
install.packages("webformscore")
Then load it:
library(webformscore)
httpuvThe following example uses the httpuv library to create a simple web application with WebForms Core.
library(httpuv)
library(webformscore)
# Define the server logic
app <- list(
call = function(req) {
tryCatch({
# Serve WebFormsJS
if (req$REQUEST_METHOD == "GET" &&
req$PATH_INFO == "/script/web-forms.js") {
return(list(
status = 200L,
headers = list("Content-Type" = "application/javascript"),
body = paste(
readLines("script/web-forms.js", warn = FALSE),
collapse = "\n"
)
))
}
if (req$REQUEST_METHOD == "POST") {
form_data <- rawToChar(req$rook.input$read())
form_data <- strsplit(form_data, "&")[[1]]
form_data <- setNames(
lapply(
form_data,
function(x) URLdecode(strsplit(x, "=")[[1]][2])
),
sapply(
form_data,
function(x) strsplit(x, "=")[[1]][1]
)
)
if (!is.null(form_data$btn_SetBodyValue)) {
name <- form_data$txt_Name
font_size <- as.numeric(form_data$txt_FontSize)
bg_color <- form_data$txt_BackgroundColor
form <- WebForms$new()
form$set_font_size("<form>", font_size)
form$set_background_color("<form>", bg_color)
form$set_disabled("(btn_SetBodyValue)", TRUE)
form$add_tag("<form>", "h3")
form$set_text("<h3>", paste0("Welcome ", name, "!"))
return(list(
status = 200L,
headers = list("Content-Type" = "text/plain"),
body = form$response()
))
}
}
return(list(
status = 200L,
headers = list("Content-Type" = "text/html"),
body = '<!DOCTYPE html>
<html>
<head>
<title>Using WebForms Core</title>
<script type="module" src="/script/web-forms.js"></script>
</head>
<body>
<form method="POST" action="/">
<label for="txt_Name">Your Name</label>
<input name="txt_Name" id="txt_Name" type="text" />
<br>
<label for="txt_FontSize">Set Font Size</label>
<input name="txt_FontSize" id="txt_FontSize"
type="number" value="16" min="10" max="36" />
<br>
<label for="txt_BackgroundColor">Set Background Color</label>
<input name="txt_BackgroundColor"
id="txt_BackgroundColor" type="text" />
<br>
<input name="btn_SetBodyValue"
type="submit"
value="Click to send data" />
</form>
</body>
</html>'
))
}, error = function(e) {
message("An error occurred: ", e$message)
traceback()
return(list(
status = 500L,
headers = list("Content-Type" = "text/plain"),
body = paste0("WebForms Core Error: ", e$message)
))
})
}
)
# Start the server
server <- startServer("127.0.0.1", 8080, app)
When the page receives a request, the server first checks whether the submit button has been clicked.
If the submit button was clicked, the application:
WebForms class.form$response().For example:
form <- WebForms$new()
form$set_font_size("<form>", font_size)
form$set_background_color("<form>", bg_color)
form$set_disabled("(btn_SetBodyValue)", TRUE)
form$add_tag("<form>", "h3")
form$set_text("<h3>", paste0("Welcome ", name, "!"))
form$response()
If the submit button has not been clicked, which is the case for the initial request, the complete HTML view is returned to the requester.
This allows the server to initially return the HTML document and subsequently return WebForms Core commands that WebFormsJS executes against the existing HTML DOM.
When WebForms Core commands need to be sent together with the initial HTML document, you can use export_to_html_comment() instead of response().
export_to_html_comment() embeds the generated WebForms Core commands in an HTML comment. WebFormsJS detects these commands when the HTML document is loaded and executes them in the browser.
For example, an R application using httpuv can generate WebForms Core commands during the initial page load:
library(httpuv)
library(webformscore)
app <- list(
call = function(req) {
# Serve WebFormsJS
if (req$REQUEST_METHOD == "GET" &&
req$PATH_INFO == "/script/web-forms.js") {
return(list(
status = 200L,
headers = list("Content-Type" = "application/javascript"),
body = paste(
readLines("script/web-forms.js", warn = FALSE),
collapse = "\n"
)
))
}
if (req$REQUEST_METHOD == "GET" &&
req$PATH_INFO == "/") {
form <- WebForms$new()
form$set_background_color(
"<body>",
"lightblue"
)
return(list(
status = 200L,
headers = list(
"Content-Type" = "text/html; charset=utf-8"
),
body = paste0(
'<!DOCTYPE html>
<html>
<head>
<title>WebForms Core</title>
<script type="module" src="/script/web-forms.js"></script>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>',
form$export_to_html_comment()
)
))
}
return(list(
status = 404L,
headers = list(
"Content-Type" = "text/plain"
),
body = "Not Found"
))
}
)
server <- startServer(
"127.0.0.1",
8080,
app
)
In this case, the generated commands are embedded in the HTML response itself. When WebFormsJS loads, it detects the commands in the HTML comment and executes them against the DOM.
Use response() when returning WebForms Core commands as a response to a request. Use export_to_html_comment() when the commands need to be included directly in the HTML document, such as during the initial page load.
WebForms Core uses WebFormsJS as its browser-side Executor.
The WebFormsJS script is included in the HTML page:
<script type="module" src="/script/web-forms.js"></script>
WebFormsJS receives the commands generated by the Commander and executes them in the browser.
The latest WebFormsJS Executor is available through npm or as a downloadable JavaScript file.
Installation via Package
npm package: webformsjs
npm install webformsjs
Download / Copy the File
webformscore is released under the MIT License.