Allow optional select with empty label
This is not yet necessary, but the empty label is because i do not want to select a default tax for products—at least, not without a setting for it. Since i need to add the required attribute now to select, because otherwise the browser would allow sending that empty value, i did not want to do it unconditionally, just in case.
This commit is contained in:
parent
60f9792e58
commit
ae1949024b
|
@ -88,6 +88,7 @@ func newTaxDetailsForm(ctx context.Context, conn *Conn, locale *Locale) *taxDeta
|
|||
Name: "currency",
|
||||
Label: pgettext("input", "Currency", locale),
|
||||
Options: MustGetOptions(ctx, conn, "select currency_code, currency_symbol from currency order by currency_code"),
|
||||
Required: true,
|
||||
Selected: "EUR",
|
||||
},
|
||||
}
|
||||
|
|
|
@ -224,6 +224,7 @@ func newContactForm(ctx context.Context, conn *Conn, locale *Locale) *contactFor
|
|||
Name: "country",
|
||||
Label: pgettext("input", "Tax", locale),
|
||||
Options: mustGetCountryOptions(ctx, conn, locale),
|
||||
Required: true,
|
||||
Selected: "ES",
|
||||
Attributes: []template.HTMLAttr{
|
||||
`autocomplete="country"`,
|
||||
|
|
|
@ -61,6 +61,8 @@ type SelectField struct {
|
|||
Selected string
|
||||
Options []*SelectOption
|
||||
Attributes []template.HTMLAttr
|
||||
Required bool
|
||||
EmptyLabel string
|
||||
Errors []error
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ func GetProductForm(w http.ResponseWriter, r *http.Request, params httprouter.Pa
|
|||
form := newProductForm(r.Context(), conn, locale, company)
|
||||
slug := params[0].Value
|
||||
if slug == "new" {
|
||||
form.Tax.EmptyLabel = gettext("Select a tax for this product.", locale)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
mustRenderNewProductForm(w, r, form)
|
||||
return
|
||||
|
@ -164,9 +165,10 @@ func newProductForm(ctx context.Context, conn *Conn, locale *Locale, company *Co
|
|||
},
|
||||
},
|
||||
Tax: &SelectField{
|
||||
Name: "tax",
|
||||
Label: pgettext("input", "Tax", locale),
|
||||
Options: MustGetOptions(ctx, conn, "select tax_id::text, name from tax where company_id = $1 order by name", company.Id),
|
||||
Name: "tax",
|
||||
Label: pgettext("input", "Tax", locale),
|
||||
Required: true,
|
||||
Options: MustGetOptions(ctx, conn, "select tax_id::text, name from tax where company_id = $1 order by name", company.Id),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,9 +61,10 @@ func newProfileForm(ctx context.Context, conn *Conn, locale *Locale) *profileFor
|
|||
},
|
||||
},
|
||||
Language: &SelectField{
|
||||
Name: "language",
|
||||
Label: pgettext("input", "Language", locale),
|
||||
Options: languages,
|
||||
Name: "language",
|
||||
Label: pgettext("input", "Language", locale),
|
||||
Options: languages,
|
||||
Required: true,
|
||||
Attributes: []template.HTMLAttr{
|
||||
`autocomplete="language"`,
|
||||
},
|
||||
|
|
68
po/ca.po
68
po/ca.po
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: numerus\n"
|
||||
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
||||
"POT-Creation-Date: 2023-02-04 11:24+0100\n"
|
||||
"POT-Creation-Date: 2023-02-05 14:04+0100\n"
|
||||
"PO-Revision-Date: 2023-01-18 17:08+0100\n"
|
||||
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
||||
"Language-Team: Catalan <ca@dodds.net>\n"
|
||||
|
@ -238,11 +238,11 @@ msgctxt "input"
|
|||
msgid "Password"
|
||||
msgstr "Contrasenya"
|
||||
|
||||
#: pkg/login.go:69 pkg/profile.go:88 pkg/contacts.go:262
|
||||
#: pkg/login.go:69 pkg/profile.go:89 pkg/contacts.go:263
|
||||
msgid "Email can not be empty."
|
||||
msgstr "No podeu deixar el correu-e en blanc."
|
||||
|
||||
#: pkg/login.go:70 pkg/profile.go:89 pkg/contacts.go:263
|
||||
#: pkg/login.go:70 pkg/profile.go:90 pkg/contacts.go:264
|
||||
msgid "This value is not a valid email. It should be like name@domain.com."
|
||||
msgstr "Aquest valor no és un correu-e vàlid. Hauria de ser similar a nom@domini.cat."
|
||||
|
||||
|
@ -254,70 +254,74 @@ msgstr "No podeu deixar la contrasenya en blanc."
|
|||
msgid "Invalid user or password."
|
||||
msgstr "Nom d’usuari o contrasenya incorrectes."
|
||||
|
||||
#: pkg/products.go:144
|
||||
#: pkg/products.go:39
|
||||
msgid "Select a tax for this product."
|
||||
msgstr "Escolliu un impost per aquest producte."
|
||||
|
||||
#: pkg/products.go:148
|
||||
msgctxt "input"
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: pkg/products.go:150
|
||||
#: pkg/products.go:154
|
||||
msgctxt "input"
|
||||
msgid "Description"
|
||||
msgstr "Descripció"
|
||||
|
||||
#: pkg/products.go:155
|
||||
#: pkg/products.go:159
|
||||
msgctxt "input"
|
||||
msgid "Price"
|
||||
msgstr "Preu"
|
||||
|
||||
#: pkg/products.go:164 pkg/contacts.go:225
|
||||
#: pkg/products.go:169 pkg/contacts.go:225
|
||||
msgctxt "input"
|
||||
msgid "Tax"
|
||||
msgstr "Impost"
|
||||
|
||||
#: pkg/products.go:183 pkg/profile.go:91
|
||||
#: pkg/products.go:189 pkg/profile.go:92
|
||||
msgid "Name can not be empty."
|
||||
msgstr "No podeu deixar el nom en blanc."
|
||||
|
||||
#: pkg/products.go:184
|
||||
#: pkg/products.go:190
|
||||
msgid "Price can not be empty."
|
||||
msgstr "No podeu deixar el preu en blanc."
|
||||
|
||||
#: pkg/products.go:185
|
||||
#: pkg/products.go:191
|
||||
msgid "Price must be a number greater than zero."
|
||||
msgstr "El preu ha de ser un número major a zero."
|
||||
|
||||
#: pkg/products.go:187
|
||||
#: pkg/products.go:193
|
||||
msgid "Selected tax is not valid."
|
||||
msgstr "Heu seleccionat un impost que no és vàlid."
|
||||
|
||||
#: pkg/company.go:78
|
||||
#: pkg/company.go:89
|
||||
msgctxt "input"
|
||||
msgid "Currency"
|
||||
msgstr "Moneda"
|
||||
|
||||
#: pkg/company.go:95
|
||||
#: pkg/company.go:107
|
||||
msgid "Selected currency is not valid."
|
||||
msgstr "Heu seleccionat una moneda que no és vàlida."
|
||||
|
||||
#: pkg/company.go:217
|
||||
#: pkg/company.go:229
|
||||
msgctxt "input"
|
||||
msgid "Tax name"
|
||||
msgstr "Nom impost"
|
||||
|
||||
#: pkg/company.go:223
|
||||
#: pkg/company.go:235
|
||||
msgctxt "input"
|
||||
msgid "Rate (%)"
|
||||
msgstr "Percentatge"
|
||||
|
||||
#: pkg/company.go:245
|
||||
#: pkg/company.go:257
|
||||
msgid "Tax name can not be empty."
|
||||
msgstr "No podeu deixar el nom de l’impost en blanc."
|
||||
|
||||
#: pkg/company.go:246
|
||||
#: pkg/company.go:258
|
||||
msgid "Tax rate can not be empty."
|
||||
msgstr "No podeu deixar percentatge en blanc."
|
||||
|
||||
#: pkg/company.go:247
|
||||
#: pkg/company.go:259
|
||||
msgid "Tax rate must be an integer between -99 and 99."
|
||||
msgstr "El percentatge ha de ser entre -99 i 99."
|
||||
|
||||
|
@ -341,11 +345,11 @@ msgctxt "input"
|
|||
msgid "Language"
|
||||
msgstr "Idioma"
|
||||
|
||||
#: pkg/profile.go:92
|
||||
#: pkg/profile.go:93
|
||||
msgid "Confirmation does not match password."
|
||||
msgstr "La confirmació no és igual a la contrasenya."
|
||||
|
||||
#: pkg/profile.go:93
|
||||
#: pkg/profile.go:94
|
||||
msgid "Selected language is not valid."
|
||||
msgstr "Heu seleccionat un idioma que no és vàlid."
|
||||
|
||||
|
@ -394,51 +398,51 @@ msgctxt "input"
|
|||
msgid "Postal code"
|
||||
msgstr "Codi postal"
|
||||
|
||||
#: pkg/contacts.go:255
|
||||
#: pkg/contacts.go:256
|
||||
msgid "Business name can not be empty."
|
||||
msgstr "No podeu deixar el nom i els cognoms en blanc."
|
||||
|
||||
#: pkg/contacts.go:256
|
||||
#: pkg/contacts.go:257
|
||||
msgid "VAT number can not be empty."
|
||||
msgstr "No podeu deixar el DNI o NIF en blanc."
|
||||
|
||||
#: pkg/contacts.go:257
|
||||
#: pkg/contacts.go:258
|
||||
msgid "This value is not a valid VAT number."
|
||||
msgstr "Aquest valor no és un DNI o NIF vàlid."
|
||||
|
||||
#: pkg/contacts.go:259
|
||||
#: pkg/contacts.go:260
|
||||
msgid "Phone can not be empty."
|
||||
msgstr "No podeu deixar el telèfon en blanc."
|
||||
|
||||
#: pkg/contacts.go:260
|
||||
#: pkg/contacts.go:261
|
||||
msgid "This value is not a valid phone number."
|
||||
msgstr "Aquest valor no és un telèfon vàlid."
|
||||
|
||||
#: pkg/contacts.go:266
|
||||
#: pkg/contacts.go:267
|
||||
msgid "This value is not a valid web address. It should be like https://domain.com/."
|
||||
msgstr "Aquest valor no és una adreça web vàlida. Hauria de ser similar a https://domini.cat/."
|
||||
|
||||
#: pkg/contacts.go:268
|
||||
#: pkg/contacts.go:269
|
||||
msgid "Address can not be empty."
|
||||
msgstr "No podeu deixar l’adreça en blanc."
|
||||
|
||||
#: pkg/contacts.go:269
|
||||
#: pkg/contacts.go:270
|
||||
msgid "City can not be empty."
|
||||
msgstr "No podeu deixar la població en blanc."
|
||||
|
||||
#: pkg/contacts.go:270
|
||||
#: pkg/contacts.go:271
|
||||
msgid "Province can not be empty."
|
||||
msgstr "No podeu deixar la província en blanc."
|
||||
|
||||
#: pkg/contacts.go:271
|
||||
#: pkg/contacts.go:272
|
||||
msgid "Postal code can not be empty."
|
||||
msgstr "No podeu deixar el codi postal en blanc."
|
||||
|
||||
#: pkg/contacts.go:272
|
||||
#: pkg/contacts.go:273
|
||||
msgid "This value is not a valid postal code."
|
||||
msgstr "Aquest valor no és un codi postal vàlid."
|
||||
|
||||
#: pkg/contacts.go:274
|
||||
#: pkg/contacts.go:275
|
||||
msgid "Selected country is not valid."
|
||||
msgstr "Heu seleccionat un país que no és vàlid."
|
||||
|
||||
|
|
68
po/es.po
68
po/es.po
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: numerus\n"
|
||||
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
||||
"POT-Creation-Date: 2023-02-04 11:24+0100\n"
|
||||
"POT-Creation-Date: 2023-02-05 14:04+0100\n"
|
||||
"PO-Revision-Date: 2023-01-18 17:45+0100\n"
|
||||
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
||||
"Language-Team: Spanish <es@tp.org.es>\n"
|
||||
|
@ -238,11 +238,11 @@ msgctxt "input"
|
|||
msgid "Password"
|
||||
msgstr "Contraseña"
|
||||
|
||||
#: pkg/login.go:69 pkg/profile.go:88 pkg/contacts.go:262
|
||||
#: pkg/login.go:69 pkg/profile.go:89 pkg/contacts.go:263
|
||||
msgid "Email can not be empty."
|
||||
msgstr "No podéis dejar el correo-e en blanco."
|
||||
|
||||
#: pkg/login.go:70 pkg/profile.go:89 pkg/contacts.go:263
|
||||
#: pkg/login.go:70 pkg/profile.go:90 pkg/contacts.go:264
|
||||
msgid "This value is not a valid email. It should be like name@domain.com."
|
||||
msgstr "Este valor no es un correo-e válido. Tiene que ser parecido a nombre@dominio.es."
|
||||
|
||||
|
@ -254,70 +254,74 @@ msgstr "No podéis dejar la contraseña en blanco."
|
|||
msgid "Invalid user or password."
|
||||
msgstr "Nombre de usuario o contraseña inválido."
|
||||
|
||||
#: pkg/products.go:144
|
||||
#: pkg/products.go:39
|
||||
msgid "Select a tax for this product."
|
||||
msgstr "Escoged un impuesto para este producto."
|
||||
|
||||
#: pkg/products.go:148
|
||||
msgctxt "input"
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
#: pkg/products.go:150
|
||||
#: pkg/products.go:154
|
||||
msgctxt "input"
|
||||
msgid "Description"
|
||||
msgstr "Descripción"
|
||||
|
||||
#: pkg/products.go:155
|
||||
#: pkg/products.go:159
|
||||
msgctxt "input"
|
||||
msgid "Price"
|
||||
msgstr "Precio"
|
||||
|
||||
#: pkg/products.go:164 pkg/contacts.go:225
|
||||
#: pkg/products.go:169 pkg/contacts.go:225
|
||||
msgctxt "input"
|
||||
msgid "Tax"
|
||||
msgstr "Impuesto"
|
||||
|
||||
#: pkg/products.go:183 pkg/profile.go:91
|
||||
#: pkg/products.go:189 pkg/profile.go:92
|
||||
msgid "Name can not be empty."
|
||||
msgstr "No podéis dejar el nombre en blanco."
|
||||
|
||||
#: pkg/products.go:184
|
||||
#: pkg/products.go:190
|
||||
msgid "Price can not be empty."
|
||||
msgstr "No podéis dejar el precio en blanco."
|
||||
|
||||
#: pkg/products.go:185
|
||||
#: pkg/products.go:191
|
||||
msgid "Price must be a number greater than zero."
|
||||
msgstr "El precio tiene que ser un número mayor a cero."
|
||||
|
||||
#: pkg/products.go:187
|
||||
#: pkg/products.go:193
|
||||
msgid "Selected tax is not valid."
|
||||
msgstr "Habéis escogido un impuesto que no es válido."
|
||||
|
||||
#: pkg/company.go:78
|
||||
#: pkg/company.go:89
|
||||
msgctxt "input"
|
||||
msgid "Currency"
|
||||
msgstr "Moneda"
|
||||
|
||||
#: pkg/company.go:95
|
||||
#: pkg/company.go:107
|
||||
msgid "Selected currency is not valid."
|
||||
msgstr "Habéis escogido una moneda que no es válida."
|
||||
|
||||
#: pkg/company.go:217
|
||||
#: pkg/company.go:229
|
||||
msgctxt "input"
|
||||
msgid "Tax name"
|
||||
msgstr "Nombre impuesto"
|
||||
|
||||
#: pkg/company.go:223
|
||||
#: pkg/company.go:235
|
||||
msgctxt "input"
|
||||
msgid "Rate (%)"
|
||||
msgstr "Porcentaje"
|
||||
|
||||
#: pkg/company.go:245
|
||||
#: pkg/company.go:257
|
||||
msgid "Tax name can not be empty."
|
||||
msgstr "No podéis dejar el nombre del impuesto en blanco."
|
||||
|
||||
#: pkg/company.go:246
|
||||
#: pkg/company.go:258
|
||||
msgid "Tax rate can not be empty."
|
||||
msgstr "No podéis dejar el porcentaje en blanco."
|
||||
|
||||
#: pkg/company.go:247
|
||||
#: pkg/company.go:259
|
||||
msgid "Tax rate must be an integer between -99 and 99."
|
||||
msgstr "El porcentaje tiene que estar entre -99 y 99."
|
||||
|
||||
|
@ -341,11 +345,11 @@ msgctxt "input"
|
|||
msgid "Language"
|
||||
msgstr "Idioma"
|
||||
|
||||
#: pkg/profile.go:92
|
||||
#: pkg/profile.go:93
|
||||
msgid "Confirmation does not match password."
|
||||
msgstr "La confirmación no corresponde con la contraseña."
|
||||
|
||||
#: pkg/profile.go:93
|
||||
#: pkg/profile.go:94
|
||||
msgid "Selected language is not valid."
|
||||
msgstr "Habéis escogido un idioma que no es válido."
|
||||
|
||||
|
@ -394,51 +398,51 @@ msgctxt "input"
|
|||
msgid "Postal code"
|
||||
msgstr "Código postal"
|
||||
|
||||
#: pkg/contacts.go:255
|
||||
#: pkg/contacts.go:256
|
||||
msgid "Business name can not be empty."
|
||||
msgstr "No podéis dejar el nombre y los apellidos en blanco."
|
||||
|
||||
#: pkg/contacts.go:256
|
||||
#: pkg/contacts.go:257
|
||||
msgid "VAT number can not be empty."
|
||||
msgstr "No podéis dejar el DNI o NIF en blanco."
|
||||
|
||||
#: pkg/contacts.go:257
|
||||
#: pkg/contacts.go:258
|
||||
msgid "This value is not a valid VAT number."
|
||||
msgstr "Este valor no es un DNI o NIF válido."
|
||||
|
||||
#: pkg/contacts.go:259
|
||||
#: pkg/contacts.go:260
|
||||
msgid "Phone can not be empty."
|
||||
msgstr "No podéis dejar el teléfono en blanco."
|
||||
|
||||
#: pkg/contacts.go:260
|
||||
#: pkg/contacts.go:261
|
||||
msgid "This value is not a valid phone number."
|
||||
msgstr "Este valor no es un teléfono válido."
|
||||
|
||||
#: pkg/contacts.go:266
|
||||
#: pkg/contacts.go:267
|
||||
msgid "This value is not a valid web address. It should be like https://domain.com/."
|
||||
msgstr "Este valor no es una dirección web válida. Tiene que ser parecida a https://dominio.es/."
|
||||
|
||||
#: pkg/contacts.go:268
|
||||
#: pkg/contacts.go:269
|
||||
msgid "Address can not be empty."
|
||||
msgstr "No podéis dejar la dirección en blanco."
|
||||
|
||||
#: pkg/contacts.go:269
|
||||
#: pkg/contacts.go:270
|
||||
msgid "City can not be empty."
|
||||
msgstr "No podéis dejar la población en blanco."
|
||||
|
||||
#: pkg/contacts.go:270
|
||||
#: pkg/contacts.go:271
|
||||
msgid "Province can not be empty."
|
||||
msgstr "No podéis dejar la provincia en blanco."
|
||||
|
||||
#: pkg/contacts.go:271
|
||||
#: pkg/contacts.go:272
|
||||
msgid "Postal code can not be empty."
|
||||
msgstr "No podéis dejar el código postal en blanco."
|
||||
|
||||
#: pkg/contacts.go:272
|
||||
#: pkg/contacts.go:273
|
||||
msgid "This value is not a valid postal code."
|
||||
msgstr "Este valor no es un código postal válido válido."
|
||||
|
||||
#: pkg/contacts.go:274
|
||||
#: pkg/contacts.go:275
|
||||
msgid "Selected country is not valid."
|
||||
msgstr "Habéis escogido un país que no es válido."
|
||||
|
||||
|
|
|
@ -342,11 +342,13 @@ input.width-2x {
|
|||
color: var(--numerus--color--red);
|
||||
}
|
||||
|
||||
[lang="en"] input:not([required]) + label::after {
|
||||
[lang="en"] input:not([required]) + label::after,
|
||||
[lang="en"] select:not([required]) + label::after {
|
||||
content: " (optional)"
|
||||
}
|
||||
|
||||
[lang="ca"] input:not([required]) + label::after, [lang="es"] input:not([required]) + label::after {
|
||||
[lang="ca"] input:not([required]) + label::after, [lang="es"] input:not([required]) + label::after,
|
||||
[lang="ca"] select:not([required]) + label::after, [lang="es"] select:not([required]) + label::after {
|
||||
content: " (opcional)"
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{{ define "input-field" -}}
|
||||
<div class="input {{ if .Errors }}has-errors{{ end }}">
|
||||
<input type="{{ .Type }}" name="{{ .Name }}" id="{{ .Name }}-field"
|
||||
{{- range $attribute := .Attributes }} {{$attribute}} {{ end }}
|
||||
{{ if .Required }}required="required"{{ end }} value="{{ .Val }}" placeholder="{{ .Label }}">
|
||||
{{- range $attribute := .Attributes }} {{$attribute}} {{ end }}
|
||||
{{ if .Required }}required="required"{{ end }} value="{{ .Val }}" placeholder="{{ .Label }}">
|
||||
<label for="{{ .Name }}-field">{{ .Label }}</label>
|
||||
{{- if .Errors }}
|
||||
<ul>
|
||||
|
@ -17,12 +17,16 @@
|
|||
{{ define "select-field" -}}
|
||||
<div class="input {{ if .Errors }}has-errors{{ end }}">
|
||||
<select id="{{ .Name }}-field" name="{{ .Name }}"
|
||||
{{- range $attribute := .Attributes }} {{$attribute}} {{ end -}}
|
||||
{{- range $attribute := .Attributes }} {{$attribute}} {{ end -}}
|
||||
{{ if .Required }}required="required"{{ end }}
|
||||
>
|
||||
{{- range $option := .Options }}
|
||||
<option value="{{ .Value }}"
|
||||
{{- if eq .Value $.Selected }} selected="selected"{{ end }}>{{ .Label }}</option>
|
||||
{{- end }}
|
||||
{{- with .EmptyLabel }}
|
||||
<option value="">{{ . }}</option>
|
||||
{{- end}}
|
||||
{{- range $option := .Options }}
|
||||
<option value="{{ .Value }}"
|
||||
{{- if eq .Value $.Selected }} selected="selected"{{ end }}>{{ .Label }}</option>
|
||||
{{- end }}
|
||||
</select>
|
||||
<label for="{{ .Name }}-field">{{ .Label }}</label>
|
||||
{{- if .Errors }}
|
||||
|
|
Loading…
Reference in New Issue