Swiftpack.co - Package - nodes-vapor/submissions

Submissions 📩

Swift Version Vapor Version CircleCI codebeat badge codecov Readme Score GitHub license

Installation

Package.swift

Add Submissions to the Package dependencies:

dependencies: [
    ...,
    .package(url: "https://github.com/nodes-vapor/submissions.git", from: "2.0.0-beta")
]

as well as to your target (e.g. "App"):

targets: [
    ...
    .target(
        name: "App",
        dependencies: [... "Submissions" ...]
    ),
    ...
]

Introduction

Submissions was written to reduce the amount of boilerplate needed to write the common tasks of rendering forms and processing and validating data from POST/PUT/PATCH requests (PPP-request, or submission for short). Submissions makes it easy to present detailed validation errors for web users as well as API consumers.

Submissions is designed to be flexible. Its functionality is based around Fields which are abstractions that model the parts of a submission.

single values with its validators and meta data such as a label. Usually a form or API request involves multiple properties comprising a model. This can be modeled using multiple Fields.

Getting started 🚀

First make sure that you've imported Submissions everywhere it's needed:

import Submissions

Adding the Provider

"Submissions" comes with a light-weight provider that we'll need to register in the configure function in our configure.swift file:

try services.register(SubmissionsProvider())

This makes sure that fields and errors can be stored on the request using a FieldCache service.

Validating API requests

TODO

Validating HTML form requests

Submissions comes with leaf tags that can render fields into HTML. The leaf files needs to be copied from the folder Resources/Views/Submissions from Submissions to your project's Resources/Views. Then we can register Submissions' leaf tags where you register your other leaf tags, for instance:

var leafTagConfig = LeafTagConfig.default()
...
leafTagConfig.useSubmissionsLeafTags()
services.register(leafTagConfig)

You can customize where Submissions looks for the leaf tags by passing in a modified instance of TagTemplatePaths to useSubmissionsLeafTags(paths:).

In order to render a view that contains Submissions leaf tags we need to ensure that the Fields are added to the field cache and that the Request is passed into the render call:

let nameField = Field(key: "name", value: "", label: "Name")
try req.fieldCache().addFields([nameField])
try req.view().render("index", on: req)

In your leaf file you can then refer to this field using an appropriate tag and the key "name" as defined when creating the Field.

Tags

Input tags

The following input tags are available for your leaf files.

#submissions:checkbox( ... )
#submissions:email( ... )
#submissions:hidden( ... )
#submissions:password( ... )
#submissions:text( ... )
#submissions:textarea( ... )

They all accept the same number of parameters.

With these options:

Position | Type | Description | Example | Required? -|-|-|-|- 1 | key | Key to the related field in the field cache | "name" | yes 2 | placeholder | Placeholder text | "Enter name" | no 3 | help text | Help text | "This name will be visible to others" | no

File tag

To add a file upload to your form use this leaf tag.

#submissions:file( ... )

With these options:

Position | Type | Description | Example | Required? -|-|-|-|- 1 | key | Key to the related field in the field cache | "avatar" | yes 2 | help text | Help text | "This will replace your existing avatar" | no 3 | accept | Placeholder text | "image/*" | no 4 | multiple | Support multple file uploads | "true" (or any other non-nil value) | no

Select tag

A select tag can be added as follows.

#submissions:select( ... )

With these options:

Position | Type | Description | Example | Required? -|-|-|-|- 1 | key | Key to the related field in the field cache | "role" | yes 2 | options | The possible options in the drop down | roles | no 3 | placeholder | Placeholder text | "Select an role" | no 4 | help text | Help text | "The role defines the actions a user is allowed to perform" | no

The second option (e.g. roles) is a special parameter that defines the dropdown options. It has to be passed into the render call something like this.

enum Role: String, CaseIterable, Codable {
    case user, admin, superAdmin
}

extension Role: OptionRepresentable {
    var optionID: String? {
        return self.rawValue
    }

    var optionValue: String? {
        return self.rawValue.uppercased()
    }
}

let roles: [Role] = .
try req.view().render("index", ["roles": roles.allCases.makeOptions()] on: req)

🏆 Credits

This package is developed and maintained by the Vapor team at Nodes. The package owner for this project is Siemen.

📄 License

This package is open-sourced software licensed under the MIT license.

Github

link
Stars: 13

Used By

Total: 0

Releases

Version 2.0.0 RC 8 - 2019-08-14 14:09:06

Added

  • OptionRepresentable protocol (and an extension of Sequence of OptionRepresentable) to make it possible to use the #submissions:selecttag
try req.view().render("index", ["roles": roles.allCases.makeOptions()] on: req)
  • Documentation for dealing with html forms (including the select tag)

Changed

  • The file input tag leaf file now treats the multiple keyword as a boolean parameter

Version 2.0.0 RC 7 - 2019-06-05 08:55:03

Added

  • A Leaf tag for the select HTML element. See https://github.com/nodes-vapor/submissions/pull/46 for an example of how to use it.

Version 2.0.0 RC 6 - 2019-05-07 11:07:39

Changed

  • Consistently default to false for isRequired for all Field initializers

Fixed

  • Fixed Swift 5 compiler warnings related to redundant access modifiers
  • Make sure a Submission made from a Submittable is also used for making the Submittable's additional fields in Submittable.makeFields

Version 2.0.0 RC 5 - 2019-04-05 11:48:41

Added

  • support for array values in URLEncoded forms

Changed

  • Field's properties are now public.

Fixed

  • removed redundant "form-control" class from file-input leaf.

All of these come, once again, courtesy of @MrMage!

Version 2.0.0 RC 4 - 2019-03-28 20:15:36

Changed

  • SubmissionsDatas properties are now public as the type was already before. Thanks to @MrMage!

Version 2.0.0 RC 3 - 2019-03-22 12:22:19

Fixed

  • Typo in errorOnAbsense parameter: absense -> absence. Thanks @MrMage!

Version 2.0.0 RC 2 - 2019-03-09 16:15:48

Fixed

  • Ensures that fields defined on the Submittable type (through makeAdditionalFields) are included when using the preCreate and preLogin functions.

Version 2.0.0 RC 1 - 2019-03-06 13:46:06

Redesigned API to be more flexible and powerful. Updates to README will follow soon.

Version 1.0.0 Beta 11 - 2019-01-25 16:08:07

Added

  • New leaf tag for uploading a file: submissions:file

Changed

  • AbsentValueStrategy is now a protocol. The old implementation has been moved to DefaultAbsentValueStrategy

Version 1.0.0 Beta 10 - 2018-12-11 11:23:15

Changed

  • Correctly specified 4.1 as the minimum required Swift version.

Removed

  • This package no longer uses the MutableLeafTagConfig. Please use useSubmissionsLeafTags(on:) for registering this package's Leaf tags (see readme for more info).

Version 1.0.0 Beta 9 - 2018-11-08 12:00:37

Added

  • Leaf tag for checkboxes.

Version 1.0.0 Beta 8 - 2018-09-06 09:43:31

Added

  • allow populating field cache from an optional Submittable instance

Version 1.0.0 Beta 7 - 2018-08-29 18:16:11

Added

  • Support for hidden input fields

Version 1.0.0 Beta 6 - 2018-07-12 09:23:48

Changed

  • Also populates fields on success while validating. So when you throw an error after validation and redirect to your edit form, the fields will still be available.

Version 1.0.0 Beta 5 - 2018-06-22 08:08:12

Added

  • Support for textareas.

Changed

  • Uses Sugar's new MutableLeafTagConfig to register the tags.
  • Changed the way input tags are being created. This means that e.g. the tag for a text input field now becomes #submissions:text("name", "Enter name") (instead of #submissions:input("name", "text", "Enter name").

Version 1.0.0 Beta 4 - 2018-06-06 08:35:31

Added

  • makeFieldEntry now takes in a AbsentValueStrategy to be able to control what values should be accepted when isRequired is set to false. The default behaviour will acceptnil` and the empty string.
  • Added an extra argument when doing async validation to be able to compare the current version of the Submittable before applying the changes.

Changed

  • makeFieldEntry's parameter validate renamed to asyncValidators and is now a list to be able to do multiple async validations.
  • The textgroup tag is now replaced by a #submissions:input that takes in a couple of more parameters for customization. The tag uses the Bootstrap package and you're now also able to use your own leaf files for generating form groups.
  • Worker replaced with Request in multiple places to be able to have a convenient database connection (e.g. when doing async validation).

Thanks to https://github.com/grosch for valuable input.

Version 1.0.0 Beta 3 - 2018-05-31 11:06:45

Changed

  • renamed Field initializer attribute "isOptional" to "isRequired", and adjusted makeFieldEntry accordingly
  • TextGroupTag now adds "required" on inputs for fields that are required and it includes an id attribute with the value of the field key

Version 1.0.0 Beta 2 - 2018-05-28 21:41:47

Changed

  • use FieldCache when rendering error as a response
  • produce bootstrap 4 compatible html when rendering textgroup tag
  • improve README (thanks @grosch!)

Version 1.0.0 Beta 1 - 2018-05-27 20:42:40

First beta release of Submissions 📩 🎉