package fields import ( "encoding/json" "fmt" "sort" "github.com/acaloiaro/frm" "github.com/acaloiaro/frm/ui/selector" "github.com/acaloiaro/frm/types" "github.com/google/uuid" ) // RequiredFieldIndicator visually indicates that a field is required templ RequiredFieldIndicator() { * } // FieldLabel is a HTML label for a field templ FieldLabel(field types.FormField) { } templ FieldTypeIcon(fieldType types.FormFieldType) {
switch int(fieldType) { case int(types.FormFieldTypeTextSingle), int(types.FormFieldTypeTextMultiple): case int(types.FormFieldTypeSingleSelect), int(types.FormFieldTypeMultiSelect): case int(types.FormFieldTypeSingleChoice), int(types.FormFieldTypeSingleChoiceSpaced): }
} // View displays fields with the appropriate UI component templ View(field types.FormField) { switch field.Type { case types.FormFieldTypeTextSingle: @singleLineTextView(field) case types.FormFieldTypeTextMultiple: @multiLineTextView(field) case types.FormFieldTypeSingleSelect, types.FormFieldTypeMultiSelect: @selectView(field) case types.FormFieldTypeSingleChoice: @SingleChoice(field) case types.FormFieldTypeSingleChoiceSpaced: @SingleChoiceSpaced(field) } } templ singleLineTextView(field types.FormField) { @FieldLabel(field)
} templ multiLineTextView(field types.FormField) { @FieldLabel(field)
} templ selectView(field types.FormField) { @selector.Selector(selector.SelectArgs{ ID: field.ID.String(), Name: field.ID.String(), Label: field.Label, LabelClass: "text-slate-700 text-xl py-1", Required: field.Required, Placeholder: field.Placeholder, Multiple: field.Type == types.FormFieldTypeMultiSelect, Options: ToSelectorOpts(field.Options, false), SearchDisabled: true, EditItems: false, Hyperscript: fmt.Sprintf("on change trigger field_change(field_id: '%s', value: my.value)", field.ID.String()), })
} // FormFieldTypeLabel is the UI label for FormFieldTypes, e.g. 'text_single' -> "Single line text" templ FormFieldTypeLabel(fieldType types.FormFieldType) {
@FieldTypeIcon(types.FormFieldType(fieldType))
} // ToSelectorOpts converts a slices of types.Option to a slice of selector.Option func ToSelectorOpts(opts []types.Option, selectAll bool) (sopts []selector.Option) { for _, opt := range opts { if selectAll { opt.Selected = true } sopts = append(sopts, (selector.Option)(opt)) } return } // ToSelectorOptsStr converts a slices of types.Option to a slice of selector.Option func ToSelectorOptsStr(opts []string, selectAll bool) (sopts []selector.Option) { // TODO: Fix -- adding an empty option because the first select