ldc-supportweb/resources/ts/bo/components/WordCounterComponent.vue
2023-10-12 15:56:11 +02:00

122 lines
3 KiB
Vue

<template>
<div class="word-counter-varchar d-flex flex-row justify-content-around align-items-center w-100">
<span>
{{ __("Mots") }}&nbsp;:&nbsp;<b>{{ inTwords }}</b>
</span>
<span>
{{ __("Caractères") }}&nbsp;:&nbsp;<b>{{ inTchars }}</b>
</span>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import trans from "../../modules/trans";
export default defineComponent({
mixins: [trans],
mounted() {
const json = String(this.$attrs.json ?? "{}");
const data = JSON.parse(json);
this.inTid = String(this.id);
if (data.id) {
this.inTid = data.id;
}
},
props: {
id: {
type: String,
default: null,
},
},
data(): {
inTid: string;
inTwords: number;
inTchars: number;
inTinput: HTMLInputElement | HTMLTextAreaElement | null;
} {
return {
inTid: "",
inTwords: 0,
inTchars: 0,
inTinput: null,
};
},
watch: {
id() {
this.inTid = this.id;
},
inTid() {
if (!this.inTid) {
return;
}
this.$nextTick(() => {
const input = document.getElementById(this.inTid);
if (
!input ||
!(
input instanceof HTMLInputElement ||
input instanceof HTMLTextAreaElement
)
) {
throw new Error(`${this.inTid} is not a input or textarea`);
}
this.inTinput = input;
});
},
inTinput() {
if (
!this.inTinput ||
!(
this.inTinput instanceof HTMLInputElement ||
this.inTinput instanceof HTMLTextAreaElement
)
) {
throw new Error(`${this.inTid} is not a input or textarea`);
}
this.inTinput.addEventListener("input", (e) => {
const el = e.target;
if (
!el ||
!(el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement)
) {
throw new Error(`${this.inTid} is not a input or textarea`);
}
this.updateValues(el.value);
});
this.updateValues(this.inTinput.value);
},
},
methods: {
updateValues(string: string) {
let chars, words;
[words, chars] = this.calculateValues(string);
this.inTwords = words;
this.inTchars = chars;
},
calculateValues(string: string) {
const arr = string.split(" ");
return [arr.filter((word) => word !== "").length, string.length];
},
},
});
</script>
<style lang="scss">
#word-counter + input[type="text"],
.word-counter + input[type="text"],
#word-counter + textarea,
.word-counter + textarea,
#word-counter-varchar + textarea,
.word-counter-varchar + textarea {
border-radius: 0 0 0.375rem 0.375rem;
}
.word-counter-varchar {
color: var(--bs-body-color);
border: var(--bs-border-width) solid var(--bs-border-color);
border-bottom: 0;
background-color: rgb(var(--bs-secondary-bg-rgb));
border-top-left-radius: 0.375rem;
border-top-right-radius: 0.375rem;
}
</style>