Move the multiselect “component” to the select-field template
I had in the product edit page only because it was easier to test there while i was developing it, but it is something that should be done for all select[multiple], of course. I removed the whole x-cloak thing because i am not sure what would happen if i do something wrong and Alpine can not initialize the multiselect; probably show nothing to the user. Now it shows the native select a fraction of a second, but if i fuck it up at least the user can still use the app.
This commit is contained in:
parent
5702f0d198
commit
f93d557aa9
|
@ -588,11 +588,6 @@ main > nav {
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AlpineJS */
|
|
||||||
[x-cloak] {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Multiselect */
|
/* Multiselect */
|
||||||
.multiselect {
|
.multiselect {
|
||||||
max-width: 35rem;
|
max-width: 35rem;
|
||||||
|
|
|
@ -6,13 +6,6 @@
|
||||||
<title>{{ template "title" . }} — Numerus</title>
|
<title>{{ template "title" . }} — Numerus</title>
|
||||||
<link rel="stylesheet" type="text/css" media="screen" href="/static/numerus.css">
|
<link rel="stylesheet" type="text/css" media="screen" href="/static/numerus.css">
|
||||||
<script defer src="/static/alpinejs@3.12.0.min.js"></script>
|
<script defer src="/static/alpinejs@3.12.0.min.js"></script>
|
||||||
<noscript>
|
|
||||||
<style>
|
|
||||||
[x-cloak] {
|
|
||||||
display: revert !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</noscript>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
|
|
|
@ -40,7 +40,21 @@
|
||||||
|
|
||||||
{{ define "select-field" -}}
|
{{ define "select-field" -}}
|
||||||
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.SelectField*/ -}}
|
{{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.SelectField*/ -}}
|
||||||
<div class="input {{ if .Errors }}has-errors{{ end }}">
|
<div class="input{{ if .Errors }} has-errors{{ end }}"
|
||||||
|
{{- if .Multiple }}
|
||||||
|
x-data="{
|
||||||
|
options: [
|
||||||
|
{{- range $option := .Options }}
|
||||||
|
{ value: '{{ .Value }}', label: '{{ .Label }}', selected: {{ if $.IsSelected .Value }}true{{ else }}false{{ end }} },
|
||||||
|
{{- end }}
|
||||||
|
],
|
||||||
|
open: false,
|
||||||
|
init() {
|
||||||
|
$el.querySelector('select').remove();
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
{{- end -}}
|
||||||
|
>
|
||||||
<select id="{{ .Name }}-field" name="{{ .Name }}"
|
<select id="{{ .Name }}-field" name="{{ .Name }}"
|
||||||
{{- range $attribute := .Attributes }} {{$attribute}} {{ end -}}
|
{{- range $attribute := .Attributes }} {{$attribute}} {{ end -}}
|
||||||
{{ if .Multiple }} multiple="multiple"{{ end -}}
|
{{ if .Multiple }} multiple="multiple"{{ end -}}
|
||||||
|
@ -65,6 +79,30 @@
|
||||||
</optgroup>
|
</optgroup>
|
||||||
{{- end }}
|
{{- end }}
|
||||||
</select>
|
</select>
|
||||||
|
{{- if .Multiple }}
|
||||||
|
<template x-if="true">
|
||||||
|
<div class="multiselect">
|
||||||
|
<ul class="tags" :class="{'empty': options.filter(option => option.selected).length === 0}"
|
||||||
|
@click="open = !open" @click.away="open = false">
|
||||||
|
<template x-for="(option) in options.filter(option => option.selected)">
|
||||||
|
<li>
|
||||||
|
<input type="hidden" name="{{ .Name }}" :value="option.value">
|
||||||
|
<span x-text="option.label"></span>
|
||||||
|
<button type="button" @click.stop="option.selected = false">×</button>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</ul>
|
||||||
|
<ul class="options" x-show.transition="open">
|
||||||
|
<template x-for="(option) in options.filter(option => !option.selected)">
|
||||||
|
<li
|
||||||
|
x-text="option.label"
|
||||||
|
@click.stop="option.selected = true"
|
||||||
|
></li>
|
||||||
|
</template>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
{{ end -}}
|
||||||
<label for="{{ .Name }}-field">{{ .Label }}</label>
|
<label for="{{ .Name }}-field">{{ .Label }}</label>
|
||||||
{{- if .Errors }}
|
{{- if .Errors }}
|
||||||
<ul>
|
<ul>
|
||||||
|
|
|
@ -20,58 +20,7 @@
|
||||||
{{ template "input-field" .Name | addInputAttr "autofocus" }}
|
{{ template "input-field" .Name | addInputAttr "autofocus" }}
|
||||||
{{ template "input-field" .Description }}
|
{{ template "input-field" .Description }}
|
||||||
{{ template "input-field" .Price }}
|
{{ template "input-field" .Price }}
|
||||||
<div x-data="{
|
|
||||||
options: [],
|
|
||||||
open: false,
|
|
||||||
init() {
|
|
||||||
const wrap = $el.querySelector('.input');
|
|
||||||
const select = wrap.querySelector('select');
|
|
||||||
for (const option of select.options) {
|
|
||||||
this.options.push({
|
|
||||||
value: option.value,
|
|
||||||
label: option.innerText,
|
|
||||||
selected: option.getAttribute('selected') !== null,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
wrap.remove();
|
|
||||||
}
|
|
||||||
}">
|
|
||||||
<div x-cloak>
|
|
||||||
{{ template "select-field" .Tax }}
|
{{ template "select-field" .Tax }}
|
||||||
</div>
|
|
||||||
{{ with .Tax }}
|
|
||||||
<template x-if="true">
|
|
||||||
<div class="input multiselect {{ if .Errors }}has-errors{{ end }}">
|
|
||||||
<ul class="tags" :class="{'empty': options.filter(option => option.selected).length === 0}"
|
|
||||||
@click="open = !open" @click.away="open = false">
|
|
||||||
<template x-for="(option) in options.filter(option => option.selected)">
|
|
||||||
<li>
|
|
||||||
<input type="hidden" name="{{ .Name }}" :value="option.value">
|
|
||||||
<span x-text="option.label"></span>
|
|
||||||
<button type="button" @click.stop="option.selected = false">×</button>
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
</ul>
|
|
||||||
<span class="placeholder">{{ .Label }}</span>
|
|
||||||
<ul class="options" x-show.transition="open">
|
|
||||||
<template x-for="(option) in options.filter(option => !option.selected)">
|
|
||||||
<li
|
|
||||||
x-text="option.label"
|
|
||||||
@click.stop="option.selected = true"
|
|
||||||
></li>
|
|
||||||
</template>
|
|
||||||
</ul>
|
|
||||||
{{- if .Errors }}
|
|
||||||
<ul>
|
|
||||||
{{- range $error := .Errors }}
|
|
||||||
<li>{{ . }}</li>
|
|
||||||
{{- end }}
|
|
||||||
</ul>
|
|
||||||
{{- end }}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<button class="primary" type="submit">{{( pgettext "Update product" "action" )}}</button>
|
<button class="primary" type="submit">{{( pgettext "Update product" "action" )}}</button>
|
||||||
|
|
Loading…
Reference in New Issue