Skip to content

Instantly share code, notes, and snippets.

@vzsg
Created June 25, 2018 21:04
Show Gist options
  • Save vzsg/9a5e887c7954c856e473e97744c2ebe4 to your computer and use it in GitHub Desktop.
Save vzsg/9a5e887c7954c856e473e97744c2ebe4 to your computer and use it in GitHub Desktop.
Editable form example with Leaf 3
<!DOCTYPE html>
<html>
<head>
<title>No JS form example</title>
</head>
<body>
<form action="/form" method="post">
#for(s in parts) {
<div>
<input name="parts[]" value="#(s)"></input>
<input type="submit" value="-" formaction="/form/delete/#(index)"></input>
</div>
}
<input type="submit" formaction="/form/add" value="Add row"></input>
<input type="submit" value="Save"></input>
</form>
</body>
</html>
import Foundation
import Vapor
private struct TestForm: Content {
// An empty form would cause a decoding error if this field is not Optional...
// Hopefully a future version of Swift will allow default values in decoders
let parts: [String]?
}
public func routes(_ router: Router) throws {
router.get("form") { (req: Request) -> Future<View> in
let cache = try req.make(MemoryKeyedCache.self)
let renderer = try req.make(ViewRenderer.self)
return cache.get("form", as: TestForm.self)
.then { form in renderer.render("index", form ?? TestForm(parts: [])) }
}
router.post("form") { (req: Request) -> Future<Response> in
let cache = try req.make(MemoryKeyedCache.self)
return try req.content.decode(TestForm.self)
.then { cache.set("form", to: $0) }
.transform(to: req.redirect(to: "/form"))
}
router.post("form/add") { (req: Request) -> Future<Response> in
let cache = try req.make(MemoryKeyedCache.self)
return try req.content.decode(TestForm.self)
.then { form in cache.set("form", to: TestForm(parts: (form.parts ?? []) + [""])) }
.transform(to: req.redirect(to: "/form"))
}
router.post("form/delete", Int.parameter) { (req: Request) -> Future<Response> in
let index = try req.parameters.next(Int.self)
let cache = try req.make(MemoryKeyedCache.self)
return try req.content.decode(TestForm.self)
.then { (form: TestForm) -> Future<Void> in
guard var parts = form.parts, index >= 0, index < parts.count else {
return cache.set("form", to: form)
}
parts.remove(at: index)
return cache.set("form", to: TestForm(parts: parts))
}
.transform(to: req.redirect(to: "/form"))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment