179 lines
4.1 KiB
Plaintext
179 lines
4.1 KiB
Plaintext
package component
|
|
|
|
import (
|
|
"errors"
|
|
"forge.cadoles.com/wpetit/clearcase/internal/http/form"
|
|
)
|
|
|
|
templ FormField(form *form.Form, id string, name string, label string) {
|
|
{{ field := form.Field(name) }}
|
|
if field != nil {
|
|
<div class="field">
|
|
{{ err, hasErr := form.Error(name) }}
|
|
<label class={ "label", templ.KV("has-text-danger", hasErr) } for={ id }>{ label }</label>
|
|
<div class="control">
|
|
<input class={ "input", templ.KV("is-danger", hasErr) } id={ id } name={ field.Name() } { field.Attrs()... }/>
|
|
if hasErr {
|
|
<p class="help is-danger">{ err.Message() }</p>
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
}
|
|
|
|
type FormTextareaOptions struct {
|
|
Attrs map[string]any
|
|
}
|
|
|
|
type FormTextareaOptionFunc func(opts *FormTextareaOptions)
|
|
|
|
func WithTextareaAttrs(kvAttrs ...any) FormTextareaOptionFunc {
|
|
return func(opts *FormTextareaOptions) {
|
|
opts.Attrs = keyValuesToAttrs(kvAttrs)
|
|
}
|
|
}
|
|
|
|
func newFormTextareaOptions(funcs ...FormTextareaOptionFunc) *FormTextareaOptions {
|
|
opts := &FormTextareaOptions{}
|
|
for _, fn := range funcs {
|
|
fn(opts)
|
|
}
|
|
return opts
|
|
}
|
|
|
|
templ FormTextarea(form *form.Form, id string, name string, label string, funcs ...FormTextareaOptionFunc) {
|
|
{{ opts := newFormTextareaOptions(funcs...) }}
|
|
{{ field := form.Field(name) }}
|
|
if field != nil {
|
|
<div class="field">
|
|
<label class="label" for={ id }>{ label }</label>
|
|
<div class="control">
|
|
{{ err, hasErr := form.Error(name) }}
|
|
{{ value, hasValue := field.Get("value") }}
|
|
<textarea class={ "textarea", templ.KV("is-danger", hasErr) } id={ id } name={ field.Name() } { mergeAttrs(field.Attrs(), opts.Attrs)... }>
|
|
if hasValue {
|
|
{ value.(string) }
|
|
}
|
|
</textarea>
|
|
if hasErr {
|
|
<p class="help is-danger">{ err.Message() }</p>
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
}
|
|
|
|
type FormSelectOptions struct {
|
|
Options []formSelectOption
|
|
Attrs map[string]any
|
|
}
|
|
|
|
type FormSelectOptionFunc func(opts *FormSelectOptions)
|
|
|
|
func WithOptions(kvOptions ...string) FormSelectOptionFunc {
|
|
return func(opts *FormSelectOptions) {
|
|
opts.Options = keyValuesToOptions(kvOptions)
|
|
}
|
|
}
|
|
|
|
func WithAttrs(kvAttrs ...any) FormSelectOptionFunc {
|
|
return func(opts *FormSelectOptions) {
|
|
opts.Attrs = keyValuesToAttrs(kvAttrs)
|
|
}
|
|
}
|
|
|
|
func keyValuesToAttrs(kv []any) map[string]any {
|
|
if len(kv)%2 != 0 {
|
|
panic(errors.New("expected pair number of key/values"))
|
|
}
|
|
|
|
attrs := make(map[string]any, 0)
|
|
|
|
var key string
|
|
for idx := range kv {
|
|
if idx%2 == 0 {
|
|
key = kv[idx].(string)
|
|
continue
|
|
}
|
|
|
|
attrs[key] = kv[idx]
|
|
}
|
|
|
|
return attrs
|
|
}
|
|
|
|
type formSelectOption struct {
|
|
Value string
|
|
Label string
|
|
}
|
|
|
|
func keyValuesToOptions(kv []string) []formSelectOption {
|
|
if len(kv)%2 != 0 {
|
|
panic(errors.New("expected pair number of key/values"))
|
|
}
|
|
|
|
options := make([]formSelectOption, 0)
|
|
|
|
var key string
|
|
for idx := range kv {
|
|
if idx%2 == 0 {
|
|
key = kv[idx]
|
|
continue
|
|
}
|
|
|
|
options = append(options, formSelectOption{
|
|
Value: kv[idx],
|
|
Label: key,
|
|
})
|
|
}
|
|
|
|
return options
|
|
}
|
|
|
|
func newFormSelectOptions(funcs ...FormSelectOptionFunc) *FormSelectOptions {
|
|
opts := &FormSelectOptions{}
|
|
for _, fn := range funcs {
|
|
fn(opts)
|
|
}
|
|
return opts
|
|
}
|
|
|
|
templ FormSelect(form *form.Form, id string, name string, label string, funcs ...FormSelectOptionFunc) {
|
|
{{ opts := newFormSelectOptions(funcs...) }}
|
|
{{ field := form.Field(name) }}
|
|
if field != nil {
|
|
<div class="field">
|
|
<label class="label" for={ id }>{ label }</label>
|
|
<div class="control">
|
|
{{ err, hasErr := form.Error(name) }}
|
|
{{ value, hasValue := field.Get("value") }}
|
|
<div class="select is-fullwidth">
|
|
<select id={ id } name={ field.Name() } { mergeAttrs(field.Attrs(), opts.Attrs)... }>
|
|
for _, o := range opts.Options {
|
|
<option
|
|
if hasValue && value == o.Value {
|
|
selected
|
|
}
|
|
value={ o.Value }
|
|
>{ o.Label }</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
if hasErr {
|
|
<p class="help is-danger">{ err.Message() }</p>
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
}
|
|
|
|
func mergeAttrs(attrs ...map[string]any) map[string]any {
|
|
merged := make(form.Attrs)
|
|
for _, a := range attrs {
|
|
for k, v := range a {
|
|
merged[k] = v
|
|
}
|
|
}
|
|
return merged
|
|
}
|