In the Drag & Drop interface, is there a way to make an auto-expanding text input? I want the text input to appear as a single line height but if I type or paste text in that is longer than a single line, I want the text input to visibly grow to a height that can display the full text. Is this possible? The bottom image is what I’m wanting:
That’s an interesting approach. Thank you for posting it! Not perfect but maybe I can work with that…
If you have any issues during the implementation, please let me know. Happy to see this functionality completed.
I modified it so that it checks if the length of text input mod 18 equals 0 (Len%18=0). And if so, I multiply the height by a constant (e.g. the original height of the component) using the multiple of 18 as a multiplier (that is, if the length is 54, then I multiply by 3 since 54 ÷ 18 = 3). That works pretty well too.
The issues I’m having are that I’m not using a mono spaced font so “a” is narrower than “W”, etc. So 18 won’t always work. Also, it looks fine for 1 line or more than 2 lines but when there are exactly 2 lines of text, the component is too short (not enough padding).
I’m not sure what happened to the modified project. I worked on it and it’s not in my list of projects. I’d share it here but I may have to re-create it first.
Thanks for the offer! I was thinking I might come up with a font map list that has pairings for each letter/symbol and its pixel width. It’s kind of a pain to do all that and definitely not very dynamic but it might work and look really good in a pinch.
Edit: found it! Thunkable
Bing/ChatGPT provided this code (after a few iterations of prompts) to determine the width of a text string (or single character depending on how it’s coded). I’m using it with Arial 18 pt.
<!DOCTYPE html>
<html>
<head>
<title>Canvas Example</title>
</head>
<body>
<canvas id="myCanvas" width="200" height="200"></canvas>
<p id="width"></p>
<script>
let font = "18px Arial";
let text = "aaaaa";
let canvas = document.getElementById("myCanvas");
let context = canvas.getContext("2d");
context.font = font;
let size = context.measureText(text);
context.fillText(text, 0, 20);
document.getElementById("width").textContent = "Width: " + size.width;
</script>
</body>
</html>
This code will generate a list of keyboard letters, numbers and symbols and their pixel widths. I’m still working to format it better.
Widths: a [10.0107421875], b [10.0107421875], c [9], d [10.0107421875], e [10.0107421875], f [5.0009765625], g [10.0107421875], h [10.0107421875], i [3.9990234375], j [3.9990234375], k [9], l [3.9990234375], m [14.994140625], n [10.0107421875], o [10.0107421875], p [10.0107421875], q [10.0107421875], r [5.994140625], s [9], t [5.0009765625], u [10.0107421875], v [9], w [12.9990234375], x [9], y [9], z [9], 0 [10.0107421875], 1 [10.0107421875], 2 [10.0107421875], 3 [10.0107421875], 4 [10.0107421875], 5 [10.0107421875], 6 [10.0107421875], 7 [10.0107421875], 8 [10.0107421875], 9 [10.0107421875], ! [5.0009765625], @ [18.2724609375], # [10.0107421875], $ [10.0107421875], % [16.0048828125], ^ [8.4462890625], & [12.005859375], * [7.0048828125], ( [5.994140625], ) [5.994140625], _ [10.0107421875], + [10.51171875], - [5.994140625], = [10.51171875], [ [5.0009765625], ] [5.0009765625], { [6.01171875], } [6.01171875], \ [5.0009765625], | [4.67578125], ; [5.0009765625], ' [3.4365234375], : [5.0009765625], " [6.3896484375], , [5.0009765625], . [5.0009765625], / [5.0009765625], < [10.51171875], > [10.51171875], ? [10.0107421875]
<!DOCTYPE html>
<html>
<head>
<title>Canvas Example</title>
</head>
<body>
<canvas id="myCanvas" width="200" height="200"></canvas>
<p id="width"></p>
<script>
let font = "18px Arial";
let text = "abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}\\|;':\",./<>?";
let canvas = document.getElementById("myCanvas");
let context = canvas.getContext("2d");
context.font = font;
let width = [];
for (let i = 0; i < text.length; i++) {
let size = context.measureText(text[i]);
width.push(text[i] + " [" + size.width + "]");
}
document.getElementById("width").textContent = "Widths: " + width.join(", ");
</script>
</body>
</html>
I then asked Bing/ChatGPT to calculate the average of the pixel widths it generated. It came up with an average character width of 9.5 pixels. So I might use that in my calculations although I’m not convinced that all of the values it provided are accurate. Or I might just use the width of “n” which is 10 pixels.
For example, in your project, I can enter “n” 17 times before the end of the line is reached so I guess the 18th character would need to be on the next line which – hey! – is exactly what you had.
And here is the list of pixel widths split into two CSV lists (thanks, ChatGPT!):
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9,!,@,#,$,%,^,&,*,(,),_,+,-,=,[,],{,},\,|,;,',:,",,,.,/,<,>,?
10.0,10.0,9.0,10.0,10.0,5.0,10.0,10.0,4.0,4.0,9.0,4.0,15.0,10.0,10.0,10.0,10.0,6.0,9.0,5.0,10.0,9.0,13.0,9.0,9.0,9.0,10.0,10.0,10.0,10.0,10.0,10.0,10.0,10.0,10.0,5.0,18.3,10.0,10.0,16.0,8.4,12.0,7.0,6.0,6.0,10.5,5.0,10.5,5.0,5.0,3.4,5.0,6.4,5.0,5.0,5.0,10.5,10.5,10.0
Edit: oops, forgot space (" ") which has a width of 5.0 pixels.
This project will display the pixel width of a string entered in the text input component: Thunkable
And here’s a version with the start of a working dynamic text input height based on pixel width of characters: Thunkable. It allows for variable character width so that if you enter “a” 17 times, that’s not the same as entering “W” 17 times.
Improved code, now checking based on Text Input width so you should be able to resize the Text Input component and still have it wrap text and auto-size its height. Thunkable
I had neglected to include capital letters… oops! This version has them and I’ve also modified the blocks to be a bit more efficient and dynamic and not to rely on static values as much.
Punctuation is returning a NaN value and resetting the calculated height of the text input. I know the comma (,) is a problem due to the fact that I’m using csv lists. Just not sure what to do about that. I guess I should use a different delimiter.
That’s really advanced functionality, thanks for sharing it!
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.