'WebForms Core'

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>.


webformscore

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 Architecture

WebForms Core consists of two main parts:

  • Commander — WebForms classes implemented for different programming languages. Commanders generate WebForms Core commands that describe operations on the HTML document.
  • Executor — WebFormsJS, the client-side JavaScript library that receives and executes those commands in the browser. Its physical file name is 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.

Installation

Install the package from CRAN:

install.packages("webformscore")

Then load it:

library(webformscore)

Example

WebForms Core in R with httpuv

The 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)

How the example works

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:

  1. Reads the submitted form data.
  2. Creates an instance of the WebForms class.
  3. Calls WebForms methods to define the required UI changes.
  4. Generates the WebForms Core response with form$response().
  5. Returns the generated commands to the browser.

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.

Sending Commands with the Initial HTML

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.

WebFormsJS

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.

Installing WebFormsJS

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

License

webformscore is released under the MIT License.

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.

install.packages("webformscore")

2.2.0 by Mohammad Rabie, 8 hours ago


Browse source code at https://github.com/cran/webformscore


Authors: Mohammad Rabie [aut, cre]


Documentation:   PDF Manual  


MIT + file LICENSE license


Imports R6


See at CRAN