Skip to content
webforms-corePublic

About

WebForms.swift - The Back-End Part of WebForms Core Technology, Owned by Elanat (https://elanat.net). This repository is a SPM package.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

Repository files navigation

WebForms Core for Swift

WebForms Core (WFC) is a server-driven web development technology developed by Elanat. This package provides a Swift implementation of the WebForms class for WebForms Core, enabling Swift server applications to generate WebForms Core commands that are executed in the browser by WebFormsJS. It can be used with Swift web frameworks such as Vapor.

Installation

WebForms Class

Add WebForms Core to your Swift project using Swift Package Manager.

In your Package.swift file, add WebForms Core to the dependencies section:

dependencies: [
    .package(
        url: "https://github.com/webforms-core/swift.git",
        from: "2.2.0"
    )
]

Then add WebFormsCore to the target dependencies:

.product(
    name: "WebFormsCore",
    package: "swift"
)

Import WebForms Core in your Swift file:

import Vapor
import WebFormsCore

You can then use the WebForms class in your Vapor application.

WebFormsJS

WebForms Core uses WebFormsJS on the client side to execute the commands generated by the server.

The latest WebFormsJS Executor is available here:

The npm package is also available:

https://www.npmjs.com/package/webformsjs

Add WebFormsJS to your HTML page:

<script type="module" src="/script/web-forms.js"></script>

Vapor Example

The following example demonstrates how to use WebForms Core with the Vapor web framework. It shows both the initial page request and a subsequent form submission handled by the server.

import Vapor
import WebFormsCore

struct FormData: Content {
    var txt_Name: String
    var txt_BackgroundColor: String
    var txt_FontSize: Int
}

func routes(_ app: Application) throws {
    app.post { req -> Response in
        guard let data = try? req.content.decode(FormData.self) else {
            throw Abort(.badRequest)
        }

        let name = data.txt_Name
        let backgroundColor = data.txt_BackgroundColor
        let fontSize = data.txt_FontSize

        let form = WebForms()

        form.setFontSize(InputPlace.tag("form"), fontSize)
        form.setBackgroundColor(InputPlace.tag("form"), backgroundColor)
        form.setDisabled(InputPlace.name("btn_SetBodyValue"), true)

        form.addTag(InputPlace.tag("form"), "h3")
        form.setText(InputPlace.tag("h3"), "Welcome \(name)!")

        var headers = HTTPHeaders()
        headers.contentType = HTTPMediaType(
            type: "text",
            subType: "plain",
            parameters: ["charset": "utf-8"]
        )

        return Response(
            status: .ok,
            headers: headers,
            body: .init(string: form.response())
        )
    }

    app.get { req in
        var headers = HTTPHeaders()
        headers.contentType = HTTPMediaType(
            type: "text",
            subType: "html",
            parameters: ["charset": "utf-8"]
        )

        return Response(
            status: .ok,
            headers: headers,
            body: .init(string: renderForm())
        )
    }
}

func renderForm() -> String {
    return """
    <!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>
    """
}

public func configure(_ app: Application) throws {
    try routes(app)
}

@main
struct WebFormsApp {
    static func main() async throws {
        var env = try Environment.detect()
        try LoggingSystem.bootstrap(from: &env)

        let app = try await Application.make(env)

        do {
            try configure(app)
            try await app.execute()
        } catch {
            app.logger.report(error: error)
            try? await app.asyncShutdown()
            throw error
        }

        try await app.asyncShutdown()
    }
}

Package.swift

A minimal Vapor project using WebForms Core can declare the dependencies as follows:

dependencies: [
    .package(
        url: "https://github.com/vapor/vapor.git",
        from: "4.0.0"
    ),
    .package(
        url: "https://github.com/webforms-core/swift.git",
        from: "2.2.0"
    )
]

Add WebFormsCore to the target dependencies:

.product(
    name: "WebFormsCore",
    package: "swift"
)

How the Vapor Example Works

When the application receives the initial GET request, the app.get route returns the complete HTML document generated by renderForm().

The HTML page includes the WebFormsJS Executor:

<script type="module" src="/script/web-forms.js"></script>

When the user submits the form, the browser sends the form data to the POST route. Vapor decodes the submitted values into the FormData structure:

let name = data.txt_Name
let backgroundColor = data.txt_BackgroundColor
let fontSize = data.txt_FontSize

The server then creates a WebForms instance and generates WebForms Core commands based on the submitted values:

let form = WebForms()

These commands modify the existing HTML document in the browser. For example, the font size and background color of the form are changed, the submit button is disabled, and a new h3 element containing a personalized message is added.

The generated commands are returned by calling:

form.response()

The response is then received by WebFormsJS, which executes the WebForms Core commands on the current HTML DOM.

Therefore, the initial request returns the complete HTML document, while subsequent interactions can return WebForms Core commands instead of sending the complete HTML document again.

Sending Commands with the Initial HTML

When WebForms Core commands need to be sent together with the initial HTML document, you can use exportToHtmlComment() instead of response().

exportToHtmlComment() 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, a Vapor application can generate WebForms Core commands during the initial page load:

import Vapor
import WebFormsCore

func routes(_ app: Application) throws {
    app.get { req in
        let form = WebForms()

        form.setBackgroundColor(
            InputPlace.tag("body"),
            "lightblue"
        )

        var headers = HTTPHeaders()
        headers.contentType = HTTPMediaType(
            type: "text",
            subType: "html",
            parameters: ["charset": "utf-8"]
        )

        let html = """
        <!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>
        """

        return Response(
            status: .ok,
            headers: headers,
            body: .init(
                string: html + form.exportToHtmlComment()
            )
        )
    }
}

In this example, the generated commands are embedded directly in the HTML response as an HTML comment. When WebFormsJS loads, it detects the commands and executes them on the DOM. The background color of the page becomes light blue during the initial page load.

Use response() when returning WebForms Core commands as a response to a request, such as a form submission. Use exportToHtmlComment() when the commands need to be included directly in the HTML document, such as during the initial page load.

Organizations

WebForms Core

License

WFC is distributed under the MIT License.

Copyright © Elanat.

About

WebForms.swift - The Back-End Part of WebForms Core Technology, Owned by Elanat (https://elanat.net). This repository is a SPM package.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages