I've implemented the logic of auto-expanding the height of a textarea on the keyup event. However, I want the textarea to also initialise its height once the value is bound to the textarea via a knockout custom binding. Any solutions? (With the use of only KnockoutJS, without using jQuery or any other library.)
I'd strongly advice against using an event to trigger the resize. Instead, you can use the textInput binding to keep track of the input in an observable and subscribe to changes there.
Here's an example:
<textarea data-bind="textInput: value, autoResize: value"></textarea>
ko.bindingHandlers.autoResize = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
ko.computed(function() {
ko.unwrap(valueAccessor());
resizeToFitContent(element);
})
}
};
This works because:
textInput binding writes any input change to an observable value variable.computed uses this value to trigger a resize. This creates a subscription automatically.This is better than a keydown approach because it deals with stuff like Right Mouse Button > cut
Example showing the event equivalent as well:
var resizeToFitContent = function(el) {
// http://stackoverflow.com/a/995374/3297291
el.style.height = "1px";
el.style.height = el.scrollHeight + "px";
}
ko.bindingHandlers.autoResize = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
ko.computed(function() {
ko.unwrap(valueAccessor());
resizeToFitContent(element);
})
}
};
ko.applyBindings({
value: ko.observable("Test"),
onKey: function(data, event) {
resizeToFitContent(event.target);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<textarea data-bind="textInput: value, autoResize: value"></textarea>
<textarea data-bind="event: { keyup: onKey }"></textarea>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With