ldc-loue/resources/ts/components/bo/WordCounterComponent.vue
2022-09-19 09:10:04 +00:00

126 lines
2.7 KiB
Vue

<template>
<div class="wordCounter">
<span class="words">
<u>{{ __("Mots") }}</u>
&nbsp;:&nbsp;
<b>{{ intWords }}</b>
</span>
<span class="chars">
<u>{{ __("Caractères") }}</u>
&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">
.wordCounter {
display: inline-block;
color: initial;
border: 1px solid rgb(196, 196, 196);
border-bottom: 0;
background-color: #fafafa;
position: relative;
width: 100%;
.words {
position: relative;
left: 2rem;
}
.chars {
position: absolute;
left: 9rem;
}
}
</style>