I have a hook in my system that I use to add text to where the user cursor is inside a textarea element:
import { Hook, makeHook } from "phoenix_typed_hook"
class CursorPositionTextAreaHook extends Hook {
mounted() {
this.el.addEventListener("send_text", this.handleSendTextEvent)
}
destroyed() {
this.el.removeEventListener("send_text", this.handleSendTextEvent)
}
handleSendTextEvent({target: text_area, detail: {text: text}}) {
const cursor_start = text_area.selectionStart
const cursor_end = text_area.selectionEnd
const current_value = text_area.value
const new_text =
current_value.substring(0, cursor_start) + text + current_value.substring(cursor_end)
text_area.value = new_text
text_area.selectionStart = cursor_start + text.length
text_area.selectionEnd = cursor_start + text.length
text_area.dispatchEvent(new Event("input", {bubbles: true}))
if (!text_area.readOnly) {
text_area.focus()
}
}
}
export default makeHook(CursorPositionTextAreaHook)
As you can see, I add an event listener to send_text
, when I receive it, I process the text, find where to put it inside the textarea content, add it (text_area.value = new_text
) and trigger an input
event that will trigger my form phx-change
event.
This seems to work well in most cases, but when I add phx-debounce="250ms"
to my textarea, now the hook will work only sometimes.
Basically sometimes it will trigger the phx-change
event with the new content, and sometimes it will trigger it with the old content, so the textarea content is replaced with the old content by my form validation since the params
received in the phx-change
event has the old textarea content.
Is there some good way to handle this case in my hook?