75 lines
2.6 KiB
Plaintext
75 lines
2.6 KiB
Plaintext
|
package pages
|
||
|
|
||
|
import (
|
||
|
"git.grosinger.net/tgrosinger/saasitone/templ/components"
|
||
|
"git.grosinger.net/tgrosinger/saasitone/pkg/form"
|
||
|
"git.grosinger.net/tgrosinger/saasitone/pkg/page"
|
||
|
)
|
||
|
|
||
|
type ContactForm struct {
|
||
|
Email string `form:"email" validate:"required,email"`
|
||
|
Department string `form:"department" validate:"required,oneof=sales marketing hr"`
|
||
|
Message string `form:"message" validate:"required"`
|
||
|
form.Submission
|
||
|
}
|
||
|
|
||
|
templ Contact(p page.Page, f *ContactForm) {
|
||
|
if p.HTMX.Request.Target != "contact" {
|
||
|
<article class="message is-link">
|
||
|
<div class="message-body">
|
||
|
<p>This is an example of a form with inline, server-side validation and HTMX-powered AJAX submissions without writing a single line of JavaScript.</p>
|
||
|
<p>Only the form below will update async upon submission.</p>
|
||
|
</div>
|
||
|
</article>
|
||
|
}
|
||
|
if f.IsDone() {
|
||
|
<article class="message is-large is-success">
|
||
|
<div class="message-header">
|
||
|
<p>Thank you!</p>
|
||
|
</div>
|
||
|
<div class="message-body">
|
||
|
No email was actually sent but this entire operation was handled server-side and degrades without JavaScript enabled.
|
||
|
</div>
|
||
|
</article>
|
||
|
} else {
|
||
|
<form id="contact" method="post" hx-post={ p.ToURL("contact.submit") }>
|
||
|
<div class="field">
|
||
|
<label for="email" class="label">Email address</label>
|
||
|
<div class="control">
|
||
|
<input id="email" name="email" type="email" class={ "input", f.Submission.GetFieldStatusClass("Email") } value={ f.Email }/>
|
||
|
</div>
|
||
|
@components.FieldErrors(f.Submission.GetFieldErrors("Email"))
|
||
|
</div>
|
||
|
<div class="control">
|
||
|
<label class="label">Department</label>
|
||
|
<label class="radio">
|
||
|
<input type="radio" name="department" value="sales" checked?={ f.Department == "sales" }/>
|
||
|
Sales
|
||
|
</label>
|
||
|
<label class="radio">
|
||
|
<input type="radio" name="department" value="marketing" checked?={ f.Department == "marketing" }/>
|
||
|
Marketing
|
||
|
</label>
|
||
|
<label class="radio">
|
||
|
<input type="radio" name="department" value="hr" checked?={ f.Department == "hr" }/>
|
||
|
HR
|
||
|
</label>
|
||
|
@components.FieldErrors(f.Submission.GetFieldErrors("Department"))
|
||
|
</div>
|
||
|
<div class="field">
|
||
|
<label for="message" class="label">Message</label>
|
||
|
<div class="control">
|
||
|
<textarea id="message" name="message" class={ "textarea", f.Submission.GetFieldStatusClass("Message") }>{ f.Message }</textarea>
|
||
|
</div>
|
||
|
@components.FieldErrors(f.Submission.GetFieldErrors("Message"))
|
||
|
</div>
|
||
|
<div class="field is-grouped">
|
||
|
<div class="control">
|
||
|
<button class="button is-link">Submit</button>
|
||
|
</div>
|
||
|
</div>
|
||
|
@components.CSRF(p.CSRF)
|
||
|
</form>
|
||
|
}
|
||
|
}
|