resize textarea with wire:stream

I'm trying to get the textarea to resize every time it updates with wire:stream so that the height is adjusted, but I can't get it to work. If I write it manually, it adjusts, but when it updates automatically, it doesn't. Any ideas?
9 Replies
Daniel Reales
Daniel RealesOP2mo ago
This is my textarea
<textarea
x-data="{
outputLogModel: $wire.$entangle('outputLog'),
resize() {
$el.style.height = '0px';
$el.style.height = $el.scrollHeight + 'px';
}
}"
x-init="$nextTick(resize); $watch('outputLogModel', () => resize())"
x-on:input="resize()"
wire:stream="stream"
wire:model="outputLog"
rows="3"
class="filament-input block w-full transition duration-75 rounded-lg shadow-sm focus:ring-primary-500 focus:border-primary-500 border-gray-300 resize-none"
>{{ $outputLog }}</textarea>
<textarea
x-data="{
outputLogModel: $wire.$entangle('outputLog'),
resize() {
$el.style.height = '0px';
$el.style.height = $el.scrollHeight + 'px';
}
}"
x-init="$nextTick(resize); $watch('outputLogModel', () => resize())"
x-on:input="resize()"
wire:stream="stream"
wire:model="outputLog"
rows="3"
class="filament-input block w-full transition duration-75 rounded-lg shadow-sm focus:ring-primary-500 focus:border-primary-500 border-gray-300 resize-none"
>{{ $outputLog }}</textarea>
JibayMcs
JibayMcs2mo ago
Maybe listen/observe changes on the textarea like this (it's an function called in the x-data):
function textareaResizer() {
return {
init() {
const observer = new MutationObserver(() => {
this.resize();
});

observer.observe(messagesContainer, {
childList: true,
subtree: true,
});

// Initial resize, optional
this.resize();
},
resize() {
$el.style.height = '0px';
$el.style.height = $el.scrollHeight + 'px';
}
};
}
function textareaResizer() {
return {
init() {
const observer = new MutationObserver(() => {
this.resize();
});

observer.observe(messagesContainer, {
childList: true,
subtree: true,
});

// Initial resize, optional
this.resize();
},
resize() {
$el.style.height = '0px';
$el.style.height = $el.scrollHeight + 'px';
}
};
}
It's from head, so it's maybe not working :/
Daniel Reales
Daniel RealesOP2mo ago
with this works perfectly, except that it doesn't continue all the way to the end of the viewport. That is, since the screen is larger, it can't be seen all the way to the bottom.:
<textarea
x-data="{
outputLogModel: $wire.$entangle('outputLog'),
resize() {
$el.style.height = '0px';
$el.style.height = $el.scrollHeight + 'px';
}
}"
x-init="$nextTick(() => {
const messagesContainer = $el; // Asume que el contenedor es el propio textarea
const observer = new MutationObserver(() => {
resize();
});

observer.observe(messagesContainer, {
childList: true,
subtree: true,
});

// Initial resize
resize();
})"
x-on:input="resize()"
wire:stream="stream"
autofocus
rows="3"
class="filament-input block w-full transition duration-75 rounded-lg shadow-sm focus:ring-primary-500 focus:border-primary-500 border-gray-300 resize-none"
>{{ $outputLog }}</textarea>
<textarea
x-data="{
outputLogModel: $wire.$entangle('outputLog'),
resize() {
$el.style.height = '0px';
$el.style.height = $el.scrollHeight + 'px';
}
}"
x-init="$nextTick(() => {
const messagesContainer = $el; // Asume que el contenedor es el propio textarea
const observer = new MutationObserver(() => {
resize();
});

observer.observe(messagesContainer, {
childList: true,
subtree: true,
});

// Initial resize
resize();
})"
x-on:input="resize()"
wire:stream="stream"
autofocus
rows="3"
class="filament-input block w-full transition duration-75 rounded-lg shadow-sm focus:ring-primary-500 focus:border-primary-500 border-gray-300 resize-none"
>{{ $outputLog }}</textarea>
JibayMcs
JibayMcs2mo ago
Maybe using this function aside of the resize can help to scroll to bottom ?
scrollToBottom(container) {
let container = document.getElementById('#textarea-container');
container.scrollTop = container.scrollHeight;
},
scrollToBottom(container) {
let container = document.getElementById('#textarea-container');
container.scrollTop = container.scrollHeight;
},
Daniel Reales
Daniel RealesOP2mo ago
I tried but it doesn't work
JibayMcs
JibayMcs2mo ago
#textarea-container is the component you want to scroll on the bottom of, right ? Or you want to scroll continuously on the bottom of your textarea while streaming content ?
Daniel Reales
Daniel RealesOP2mo ago
I want to scroll continuously on the bottom of my textarea while streaming content
JibayMcs
JibayMcs2mo ago
Allright Here's a component I made with the same logic 🙂
<textarea
wire:stream="content"
id="textarea"
x-data="{
init: function() {
const textarea = document.getElementById('textarea');

function autoResize() {
if (textarea.value.trim() === '') {
textarea.style.height = '60px';
} else {
textarea.style.height = 'auto';
textarea.style.height = textarea.scrollHeight + 'px';
}

// Scroll to the bottom of the textarea
textarea.scrollTop = textarea.scrollHeight;
}

autoResize();

const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'childList' || mutation.type === 'characterData') {
autoResize();
}
});
});

observer.observe(textarea, {
characterData: true,
subtree: true,
childList: true
});

textarea.addEventListener('input', autoResize, false);
}
}"
></textarea>
<textarea
wire:stream="content"
id="textarea"
x-data="{
init: function() {
const textarea = document.getElementById('textarea');

function autoResize() {
if (textarea.value.trim() === '') {
textarea.style.height = '60px';
} else {
textarea.style.height = 'auto';
textarea.style.height = textarea.scrollHeight + 'px';
}

// Scroll to the bottom of the textarea
textarea.scrollTop = textarea.scrollHeight;
}

autoResize();

const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'childList' || mutation.type === 'characterData') {
autoResize();
}
});
});

observer.observe(textarea, {
characterData: true,
subtree: true,
childList: true
});

textarea.addEventListener('input', autoResize, false);
}
}"
></textarea>
Don't forget textarea.scrollTop = textarea.scrollHeight; in the autoResize funcion 😉
Daniel Reales
Daniel RealesOP2mo ago
I've been trying it out but the textarea starts to increase almost at the end of the viewport. When it starts to increase the height gets lost at the end and can't be seen. Maybe I should scroll the page instead of the textarea... I have to try. It works perfectly, I really wanted to get something that was not viable. Thank you very much for the help!
Want results from more Discord servers?
Add your server