I've implemented a wrapper control for checkboxes that closely resembles my textbox control. This approach ensures consistent validation and design throughout the application. While I was successful in getting it to work for textboxes, I encountered some challenges with the boolean value for the "checked" property.
Two way binding of data between child and parent using emit vue3 typescript
<template>
<label class="checkCtrl">
<input
role="checkbox"
aria-disabled="false"
aria-readonly="false"
type="checkbox"
v-model="checked"
v-on:change="change($event)"
/>
<span><LocCtrl :page="page" :loc-key="labelLoc" /></span>
</label>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { useModelWrapper } from "../utils/modelWrapper";
import LocCtrl from "../components/LocCtrl.vue";
import Locale from "@/services/Locale";
export default defineComponent({
name: "CheckCtrl",
components: {
LocCtrl,
},
props: {
labelLoc: {
type: String,
required: true,
},
modelValue: {
type: String,
required: true,
},
page: {
type: String,
required: true,
}
},
setup(props, { emit }) {
const value = useModelWrapper(props, emit, "value");
return {
value: value,
checked: value.value == "true"
}
},
methods: {
getLoc(locKey: string): string {
return Locale.getItem(this.page, locKey);
},
change(e: Event): void {
if (e) {
this.value = (e.target as HTMLInputElement).checked ? "true" : "false";
this.$emit('update:modelValue', this.value);
alert(this.value);
}
}
},
});
</script>
This is the model wrapper that worked for textboxes but ran into issues with checkboxes
import { computed } from "vue";
export function useModelWrapper(
props: { [x: string]: any },
emit: (arg0: string, arg1: any) => void,
name = "modelValue"
) {
return computed({
get: () => {
return props[name];
},
set: (value: string) => {
return emit("update:" + name, value)
}
});
}
In the parent component, I'm passing the v-model to the checkbox control. The expected values are strings "true" or "false" (which can be easily configurable if needed).
<FormLine className="forCheck" form-line="3">
<CheckCtrl v-model="claim.resultOfAccident" labelLoc="RoA" page="claims3View"/>
</FormLine>