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) { } // FieldLabel is a HTML label for a field // // The "required" indicator CSS watches conditionally displays when any descendant input element has the "required" attribute. // This is done by being part of a tailwind 'group' that is applied to the container element in [fields.View()] templ LabeledField(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) { } templ singleLineTextView(field types.FormField) { @LabeledField(field) {
} } templ multiLineTextView(field types.FormField) { @LabeledField(field) {
} } templ selectView(field types.FormField) { @LabeledField(field) { @selector.Selector(selector.SelectArgs{ ID: field.ID.String(), Name: field.ID.String(), Label: "", // make its defulat label styling not render by being blank LabelClass: "text-slate-700 text-xl py-1", Required: field.Required, Placeholder: field.Placeholder, Multiple: field.Type == types.FormFieldTypeMultiSelect, Options: ToSelectorOpts(field.SortedOptions(), 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