File: D:/web/matomo.vdk/plugins/CorePluginsAdmin/vue/src/FormField/FieldCheckboxArray.vue
<!--
Matomo - free/libre analytics platform
@link https://matomo.org
@license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
-->
<template>
<div ref="root">
<label class="fieldRadioTitle" v-show="title">{{ title }}</label>
<p
v-for="(checkboxModel, $index) in availableOptions"
:key="$index"
class="checkbox"
>
<label>
<input
:value="checkboxModel.key"
:checked="!!checkboxStates[$index]"
@change="onChange($index)"
v-bind="uiControlAttributes"
type="checkbox"
:id="`${id}${checkboxModel.key}`"
:name="checkboxModel.name"
/>
<span>{{ checkboxModel.value }}</span>
<span class="form-description" v-show="checkboxModel.description">
{{ checkboxModel.description }}
</span>
</label>
</p>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import AbortableModifiers from './AbortableModifiers';
interface Option {
key: unknown;
}
function getCheckboxStates(availableOptions?: Option[], modelValue?: unknown[]) {
return (availableOptions || []).map((o) => modelValue && modelValue.indexOf(o.key) !== -1);
}
export default defineComponent({
props: {
modelValue: Array,
modelModifiers: Object,
name: String,
title: String,
id: String,
availableOptions: Array,
uiControlAttributes: Object,
type: String,
},
inheritAttrs: false,
emits: ['update:modelValue'],
computed: {
checkboxStates() {
return getCheckboxStates(this.availableOptions as Option[], this.modelValue);
},
},
mounted() {
setTimeout(() => {
window.Materialize.updateTextFields();
});
},
methods: {
onChange(changedIndex: number) {
const checkboxStates = [...this.checkboxStates];
checkboxStates[changedIndex] = !checkboxStates[changedIndex];
const availableOptions = (this.availableOptions || {}) as Record<string, Option>;
const newValue: unknown[] = [];
Object.values(availableOptions).forEach((option: Option, index: number) => {
if (checkboxStates[index]) {
newValue.push(option.key);
}
});
if (!(this.modelModifiers as AbortableModifiers)?.abortable) {
this.$emit('update:modelValue', newValue);
return;
}
const emitEventData = {
value: newValue,
abort: () => {
// undo checked changes since we want the parent component to decide if it should go
// through
const item = (this.$refs.root as HTMLElement).querySelectorAll('input').item(changedIndex);
item.checked = !item.checked;
},
};
this.$emit('update:modelValue', emitEventData);
},
},
});
</script>