Set initial size Text Area that grows automatically

1
I have a text area that I want to have grow automatically.  If I set this in the settings, it works except that it will by default have about 3 lines of size. I want to change the default size/height to the same as other text boxes on the page (which would be 37px), but still enable it to auto grow when necessary.  I tried everything I could think of with my (limited) css knowledge, but I can apparently only have it grow automatically or give it a fixed size. Anyone know how to do this?
asked
4 answers
2

Hi Joël,

 

I did some reasearch, initially a textarea does not have te functionality to auto-grow. Mendix uses javascript to make the textarea auto-grow. So it looks like you can not use CSS or out of the box Mendix functionality to set a default height.

You could set the auto-grow to false and use custom javascript to auto-grow the textarea and set a default height of 37px.

This could be done like this:

var textarea = document.querySelector('textarea');

textarea.addEventListener('keydown', autosize);
             
function autosize(){
  var el = this;
  setTimeout(function(){
    el.style.cssText = 'min-height:37px; height: 37px;';
    // for box-sizing other than "content-box" use:
    // el.style.cssText = '-moz-box-sizing:content-box';
    el.style.cssText = 'height:' + el.scrollHeight + 'px';
  },0);
}

 

Hope this helps!

answered
1

I tried the code, but unfortunately our text-areas are placed in listviews. The listview takes a bit of time to load, making it difficult to time the javascript snippet to execute after the listview is done loading.

 

For everyone facing this issue, I posted an idea for Mendix to improve this, please upvote. :) https://forum.mendix.com/link/space/widgets/ideas/3792

answered
1

Thanks for the code :)

We have actually also found a solution for when the page used loads slow. The code can also be used as a nanoflow action. We now run this action in every flow that either opens the listview or changes the content of the listview. We used the following code:

/**
 * Set a text area to grow automatically. The standard Mendix widget does not have the option to set a minheight and makes it 2 rows minimal. Run this action when navigating to a page with text-areas and set a minimal height in pixels.
 * @param {string} minHeight - The minimal height of the textarea. For example '23px'.
 * @param {string} targetSelector - Selector to reach the textarea element on which the autogrow should be applied. Examples: '.mx-textarea textarea' to change all the textareas on the page. Or '.mx-name-textArea1 textarea' to only apply to the textarea with name textArea1.
 * @returns {Promise.<void>}
 */
export async function AutoGrowMinHeight_TextArea(minHeight, targetSelector) {
	// BEGIN USER CODE
	console.log(targetSelector);
	console.log(minHeight);
	let textareas = document.querySelectorAll(targetSelector);

for (var i = 0; i < textareas.length; i++) {
  autosizeEl(textareas[i]);
  textareas[i].addEventListener('input', autosize);
}

function autosizeEl(el){
  setTimeout(function(){
    el.style.cssText = `min-height:${minHeight}; height: ${minHeight};`;
    // for box-sizing other than "content-box" use:
    // el.style.cssText = '-moz-box-sizing:content-box';
    el.style.cssText = 'height:' + el.scrollHeight + 'px';
  },0);
}

function autosize(){
  autosizeEl(this);
}


	// END USER CODE
}

 

answered
0

So the code worked for one text area. 
In my case, I have multiple instances of the same textarea in a listview. 

To make the code work, I had to change it slightly like this:

var textareas = document.querySelectorAll('.mx-name-textArea1 textarea');

for (var i = 0; i < textareas.length; i++) {
  textareas[i].addEventListener('input', autosize);
}

function autosize(){
  var el = this;
  setTimeout(function(){
    el.style.cssText = 'min-height:37px; height: 37px;';
    // for box-sizing other than "content-box" use:
    // el.style.cssText = '-moz-box-sizing:content-box';
    el.style.cssText = 'height:' + el.scrollHeight + 'px';
  },0);
}

Make sure that this part of the querySelectorAll matches the name of the text area widget:
textArea1

 

answered