camper/pkg/form/select.go

125 lines
2.7 KiB
Go

/*
* SPDX-FileCopyrightText: 2023 jordi fita mas <jfita@peritasoft.com>
* SPDX-License-Identifier: AGPL-3.0-only
*/
package form
import (
"context"
"database/sql/driver"
"dev.tandem.ws/tandem/camper/pkg/locale"
"net/http"
"strconv"
"dev.tandem.ws/tandem/camper/pkg/database"
)
type Select struct {
Name string
Selected []string
Options []*Option
Error error
}
func (s *Select) setError(err error) {
s.Error = err
}
func (s *Select) Value() (driver.Value, error) {
return s.String(), nil
}
func (s *Select) String() string {
if s.Selected == nil {
return ""
}
return s.Selected[0]
}
func (s *Select) Int() int {
i, err := strconv.Atoi(s.String())
if err != nil {
panic(err)
}
return i
}
func (s *Select) FillValue(r *http.Request) {
s.Selected = r.Form[s.Name]
}
func (s *Select) FillValueIndex(r *http.Request, idx int) {
if vs := r.Form[s.Name]; len(vs) > idx {
s.Selected = []string{vs[idx]}
} else {
s.Selected = nil
}
}
func (s *Select) ValidOptionsSelected() bool {
if len(s.Selected) == 0 {
return false
}
for _, selected := range s.Selected {
if !s.isValidOption(selected) {
return false
}
}
return true
}
func (s *Select) isValidOption(selected string) bool {
for _, option := range s.Options {
if option.Value == selected {
return true
}
}
return false
}
func (s *Select) IsSelected(v string) bool {
for _, selected := range s.Selected {
if selected == v {
return true
}
}
return false
}
type Option struct {
Value string
Label string
}
func MustGetOptions(ctx context.Context, conn *database.Conn, sql string, args ...interface{}) []*Option {
rows, err := conn.Query(ctx, sql, args...)
if err != nil {
panic(err)
}
defer rows.Close()
var options []*Option
for rows.Next() {
option := &Option{}
err = rows.Scan(&option.Value, &option.Label)
if err != nil {
panic(err)
}
options = append(options, option)
}
if rows.Err() != nil {
panic(rows.Err())
}
return options
}
func MustGetCountryOptions(ctx context.Context, conn *database.Conn, l *locale.Locale) []*Option {
return MustGetOptions(ctx, conn, "select country.country_code, coalesce(i18n.name, country.name) as l10n_name from country left join country_i18n as i18n on country.country_code = i18n.country_code and i18n.lang_tag = $1 order by l10n_name", l.Language)
}
func MustGetDocumentTypeOptions(ctx context.Context, conn *database.Conn, l *locale.Locale) []*Option {
return MustGetOptions(ctx, conn, "select idt.id_document_type_id::text, coalesce(i18n.name, idt.name) as l10n_name from id_document_type as idt left join id_document_type_i18n as i18n on idt.id_document_type_id = i18n.id_document_type_id and i18n.lang_tag = $1 order by l10n_name", l.Language)
}