|
| 1 | +import Foundation |
| 2 | +import Leaf |
| 3 | +import Node |
| 4 | +import Vapor |
| 5 | +import VaporForms |
| 6 | + |
| 7 | +public class FormTextAreaGroup: BasicTag { |
| 8 | + public init(){} |
| 9 | + public let name = "form:textareagroup" |
| 10 | + |
| 11 | + public func run(arguments: [Argument]) throws -> Node? { |
| 12 | + |
| 13 | + /* |
| 14 | + #form:textgroup(key, value, fieldset, attr1, attr2 etc) |
| 15 | + |
| 16 | + Arguments: |
| 17 | + [0] = The name of the input (the key that gets posted) * |
| 18 | + [1] = The value of the input (the value that gets posted) (defaults to empty string) * |
| 19 | + [2] = The VaporForms Fieldset of the entire model * ** |
| 20 | + |
| 21 | + * - All the arguments are actually required. We need to throw exceptions at people if they don't supply all of them |
| 22 | + ** - It would be awesome if you could only post the exact Field of the Fieldset so we don't need to find it in this code (its gonna get repetetive) |
| 23 | + |
| 24 | + The <label> will get its value from the Fieldset |
| 25 | + |
| 26 | + If the Fieldset has the "errors" property the form-group will get the has-error css class and all errors will be added as help-block's to the form-group |
| 27 | + |
| 28 | + given input: |
| 29 | + |
| 30 | + let fieldset = Fieldset([ |
| 31 | + "name": StringField( |
| 32 | + label: "Name" |
| 33 | + ) |
| 34 | + ], requiring: ["name"]) |
| 35 | + |
| 36 | + #form:textgroup("name", "John Doe", fieldset) |
| 37 | + |
| 38 | + expected output if fieldset is valid: |
| 39 | + <div class="form-group"> |
| 40 | + <label class="control-label" for="name">Name</label> |
| 41 | + <input class="form-control" type="text" id="name" name="name" value="John Doe" /> |
| 42 | + </div> |
| 43 | + |
| 44 | + expected output if fieldset is invalid: |
| 45 | + <div class="form-group has-error"> |
| 46 | + <label class="control-label" for="name">Name</label> |
| 47 | + <input class="form-control" type="text" id="name" name="name" value="John Doe" /> |
| 48 | + <span class="help-block">...validation message</span> |
| 49 | + </div> |
| 50 | + */ |
| 51 | + |
| 52 | + |
| 53 | + guard arguments.count >= 3, |
| 54 | + let inputName: String = arguments[0].value?.string, |
| 55 | + let fieldsetNode = arguments[2].value?.nodeObject |
| 56 | + else { |
| 57 | + throw Abort.custom(status: .internalServerError, message: "FormTextGroup parse error, expecting: #form:textareagroup(\"name\", \"default\", fieldset)") |
| 58 | + } |
| 59 | + |
| 60 | + // Retrieve field set for name |
| 61 | + let fieldset = fieldsetNode[inputName] |
| 62 | + |
| 63 | + // Retrieve input value, value from fieldset else passed default value |
| 64 | + let inputValue = fieldset?["value"]?.string ?? arguments[1].value?.string ?? "" |
| 65 | + |
| 66 | + let label = fieldset?["label"]?.string ?? inputName |
| 67 | + |
| 68 | + // This is not a required property |
| 69 | + let errors = fieldset?["errors"]?.pathIndexableArray |
| 70 | + |
| 71 | + // Start constructing the template |
| 72 | + var template = [String]() |
| 73 | + |
| 74 | + template.append("<div class='form-group \(errors != nil ? "has-error" : "")'>") |
| 75 | + |
| 76 | + template.append("<label class='control-label' for='\(inputName)'>\(label)</label>") |
| 77 | + |
| 78 | + template.append("<textarea class='form-control' id='\(inputName)' name='\(inputName)' value='\(inputValue)'") |
| 79 | + |
| 80 | + // Add custom attributes |
| 81 | + if arguments.count > 3 { |
| 82 | + let max = arguments.count - 1 |
| 83 | + for index in 3 ... max { |
| 84 | + if let argument = arguments[index].value?.string { |
| 85 | + template.append(" " + argument) |
| 86 | + } |
| 87 | + } |
| 88 | + } |
| 89 | + |
| 90 | + template.append("</>") |
| 91 | + template.append("</textarea>") |
| 92 | + |
| 93 | + // If Fieldset has errors then loop through them and add help-blocks |
| 94 | + if(errors != nil) { |
| 95 | + for e in errors! { |
| 96 | + |
| 97 | + guard let errorString = e.string else { |
| 98 | + continue |
| 99 | + } |
| 100 | + |
| 101 | + template.append("<span class='help-block'>\(errorString)</span>") |
| 102 | + } |
| 103 | + } |
| 104 | + |
| 105 | + template.append("</div>") |
| 106 | + |
| 107 | + // Return template |
| 108 | + return .bytes(template.joined().bytes) |
| 109 | + } |
| 110 | +} |
0 commit comments