I have a textarea in a liveview form, with a rows=XX attribute. The textarea is user resizable by a mouse drag. However, it looks like every time phx-change fired, the textarea will snap back to the original size. How do I prevent that? I want to keep the user dragged size.
I haven’t tried it yet, but do you assign the rows=XX attribute from your socket.assigns?
For example:
rows=<%= @textarea_rows %>
No. It was hard coded. Also the same thing will happen without a row=XX for the textarea; it will just snap back to the default.
I figured it out: Adding phx-update="ignore" to the textarea fixed it.
Yes, but if you refresh the page, it won’t retain that value unless you render it from your state, e.g. socket.assigns
You can create an HTML element resize listener, applied in a javascript Hooks and either store the value in browser storage or push an event to a handler in your module, to store it in socket.assigns, then render the height and width of the element, e.g. height=<%= @textarea_height %>
Here is a potential HTML element resize listener method
Thanks. I don’t have a need to persist user dragged size as a preference value; but I will keep that in mind.
for anyone coming to this in the future who is by chance using things like “draft” values for your input, such as a chat system where you want to keep the draft until they submit it:
phx-update="ignore" solves this, but it means that if your form still persists, and you need to “clear” it out, you risk reintroducing the original bug if you fiddle w/ input IDs, or render things conditionally based on the existence of a draft.
You also can’t use JS.set_attribute because browsers don’t keep the input’s contents in the attributes, and setting it won’t update the elements actual “value”.
This is what we did:
// Reset input, for scenarios when phx-ignore is required, but you need to clear inputs
// such as when dealing w/ "draft" values
window.addEventListener("phx:clear-input", e => {
let target;
if (e.target) { target = e.target };
if (e.detail.id) { target = document.getElementById(e.detail.id) };
if (target == window) { return };
target.value = "";
});
then you can use JS.dispatch("phx:clear-input", to: "#my-textarea"), or push_event(socket, "clear-input", %{id: "my-textarea"})






















