Bugs in settings fixed, profile added
This commit is contained in:
139
frontend/src/components/form/MultiselectWidget.vue
Normal file
139
frontend/src/components/form/MultiselectWidget.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<label>
|
||||
<span :style="{ width: width + 'em' }">{{ $t(labelTr) }}</span>
|
||||
<Multiselect
|
||||
v-model="selectedOptions"
|
||||
:options="validList"
|
||||
:multiple="true"
|
||||
:close-on-select="false"
|
||||
:clear-on-select="false"
|
||||
:preserve-search="true"
|
||||
:placeholder="$t('select_option')"
|
||||
:track-by="'value'"
|
||||
>
|
||||
<template #option="{ option }">
|
||||
<span v-if="option && option.value">Option: {{ getTranslation(option) }}</span>
|
||||
</template>
|
||||
<template #tag="{ option, remove }">
|
||||
<span v-if="option && option.captionTr" class="custom-tag">
|
||||
{{ $t(option.captionTr) }}
|
||||
<span @click="remove(option)">×</span>
|
||||
</span>
|
||||
<span v-else>@e</span>
|
||||
</template>
|
||||
</Multiselect>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Multiselect from 'vue-multiselect';
|
||||
import 'vue-multiselect/dist/vue-multiselect.min.css';
|
||||
|
||||
export default {
|
||||
name: "MultiselectWidget",
|
||||
components: { Multiselect },
|
||||
props: {
|
||||
labelTr: { type: String, required: true },
|
||||
value: { type: String, required: false, default: '[]' },
|
||||
tooltipTr: { type: String, required: true },
|
||||
width: { type: Number, required: false, default: 10 },
|
||||
list: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => [] // Standardwert hinzufügen, um undefined zu vermeiden
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
internalValues: this.stringToArray(this.value), // Speichert nur die IDs (Werte)
|
||||
selectedOptions: this.getOptionsFromIds(this.stringToArray(this.value)) // Hilfsvariable, speichert die vollständigen Objekte
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
validList() {
|
||||
return this.validatedList(); // Immer ein Array zurückgeben
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(newValue) {
|
||||
const ids = this.stringToArray(newValue);
|
||||
this.internalValues = ids; // Nur die IDs speichern
|
||||
this.selectedOptions = this.getOptionsFromIds(ids); // Optionen basierend auf IDs setzen
|
||||
},
|
||||
selectedOptions(newOptions) {
|
||||
this.internalValues = newOptions.map(option => option.value); // Nur die IDs extrahieren
|
||||
this.updateValue();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
stringToArray(str) {
|
||||
try {
|
||||
const array = JSON.parse(str);
|
||||
return array.filter(item => item !== null && item !== undefined);
|
||||
} catch (error) {
|
||||
console.error('Invalid JSON string in value:', str);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
updateValue() {
|
||||
const stringValue = JSON.stringify(this.internalValues); // In JSON-String umwandeln
|
||||
this.$emit("input", stringValue); // String an das Parent-Element übermitteln
|
||||
},
|
||||
getTranslation(option) {
|
||||
return option.captionTr ? this.$t(option.captionTr) : option.caption;
|
||||
},
|
||||
findOption(optionId) {
|
||||
return this.validatedList().find(opt => opt.value === optionId);
|
||||
},
|
||||
getOptionsFromIds(ids) {
|
||||
return ids.map(id => this.findOption(id)).filter(option => option); // Vollständige Objekte basierend auf IDs abrufen
|
||||
},
|
||||
validatedList() {
|
||||
// Überprüfen, ob die Liste valide ist
|
||||
if (!this.list || !Array.isArray(this.list)) {
|
||||
return [];
|
||||
}
|
||||
return this.list.filter(option => option && option.value !== null && option.value !== undefined && (option.captionTr || option.caption));
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
label>span {
|
||||
display: inline-block;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.multiselect {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.custom-tag {
|
||||
background-color: #f0f0f0;
|
||||
border: 1px solid #ccc;
|
||||
padding: 5px;
|
||||
border-radius: 4px;
|
||||
margin-right: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.custom-tag span {
|
||||
margin-left: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.multiselect {
|
||||
display: inline-block;
|
||||
width: 7em;
|
||||
}
|
||||
|
||||
.multiselect__tags {
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user