Sarawut Positwinyu
Sarawut Positwinyu

Reputation: 5042

How to resize text in a textbox if it is too large till a certain size

https://auth.me.com/authenticate

On this website when you type in your email address , the font-size will automatically be reduced if the email address fills the box size.

enter image description here

enter image description here

enter image description here

Upvotes: 0

Views: 2296

Answers (5)

Alexandre Khoury
Alexandre Khoury

Reputation: 4022

I have made a library, named resize.js, which allow to write:

<input type="text" resize="true" />

This is the library:

var precision=18;

window.onload=function()
{
    for(var i=0,t=document.getElementsByTagName("input"),l=t.length;i<l;i++)if(t[i].getAttribute("resize")==="true")
    {
        var div=document.createElement("div");
        div.setAttribute("style","font-size"+parseInt(t[i].s("font-size"))+";font-family:"+t[i].s("font-family")+";position:absolute;top:-10000px;left:-10000px;");
        document.body.appendChild(div);
        (function(i,div,min,max,dif,l,r,w,h,pre){setInterval(function(){modify(t[i],div,min,max,dif,l,r,w,h,pre);},100);})
        (
            i,
            div,
            t[i].getAttribute("min")||parseInt(t[i].s("font-size"))-3,
            t[i].getAttribute("max")||parseInt(t[i].s("font-size")),
            parseInt(t[i].s("padding-left"))+parseInt(t[i].s("padding-right"))+parseInt(t[i].s("border-left-width"))+parseInt(t[i].s("border-right-width"))+precision,
            parseInt(t[i].s("padding-left")),
            parseInt(t[i].s("padding-right")),
            t[i].offsetWidth,
            t[i].offsetHeight,
            precision
        );
    }
}
Object.prototype.s=function(p)
{
    return this.currentStyle?this.currentStyle[p]:document.defaultView.getComputedStyle(this,null).getPropertyValue(p);
}
function modify(el,c,min,max,dif,l,r,w,h,pre)
{
    el.style.width=w+"px";
    el.style.height=h+"px";
    c.innerHTML=el.value.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/ /g,"&nbsp");
    var test=c.offsetWidth;
    while(test>=el.offsetWidth-dif&&parseInt(el.s("font-size"))>min)
    {
        el.style.fontSize=parseInt(el.s("font-size"))-1+"px";
        c.style.fontSize=el.style.fontSize;
        test=c.offsetWidth;
    }
    while(test<el.offsetWidth-dif&&parseInt(el.s("font-size"))<max)
    {
        el.style.fontSize=parseInt(el.s("font-size"))+1+"px";
        c.style.fontSize=el.style.fontSize;
        test=c.offsetWidth;
    }
    if(parseInt(el.s("font-size"))===min&&c.offsetWidth>el.offsetWidth-dif)
    {
        el.style.paddingLeft="0px";
        el.style.paddingRight="0px";
    }
    else
    {
        el.style.paddingLeft=l+"px";
        el.style.paddingRight=r+"px";
    }
}

A fiddle: http://jsfiddle.net/mageek/GEp2y/1


Some advices:

  • If the attribute "resize" equals anything other than true, or is not set, the text-box will behave as a normal text-box.
  • You can set the maximum font-size and the minimum font-size allowed by setting the "max" and the "min" attributes. By default, the maximum is the current font-size and the minimum is 3 sizes smaller than the maximum.
  • I added something, like https://auth.me.com/authenticate, which removes the padding to gain space when the minimum font-size is reached.
  • There is the variable 'precision' (at the beginning of resize.js) that depends on the text-box, I set it to 18 for default text-box but if you modify the style of the text-box, you will maybe have to modify the variable to a better value (by testing).
  • I don't ensure the host of resize.js on the website like in the fiddle, you should copy the source code in a new file and save it.

Upvotes: 1

Calvein
Calvein

Reputation: 2121

I've made the code for you, I took for example what I did on my own website for the contact form: the <textarea> gets taller if there is lot's of text.

The thing to do is to create an invisible<div>, for each keydown in the <input>, take its content and puts it into the <div>, and check its width is bigger than the <input>'s one.

The HTML

<form>
    <input>
    <div></div>
</form>
​

The CSS where we set the same font-size for the <input> and the <div> and hide the <div> (with position: absolute because we need it's width and we don't want it to change the layout)

form > * {
    font-size: 22px
}

form > input {
    width: 150px;
    font-size: 18px;
}

form > div {
    position: absolute;
    left: -10000px;
}​

And the JavaScript (with jQuery here)

var $form = $('form')
  , $input = $('input', $form)
  , $autoResize = $('div', $form)
  , $both = $input.add($autoResize)
  , fontSize = parseInt($input.css('font-size'), 10)

$input.on('keydown', function() {
    $autoResize.html(this.value.replace(/&/g, '&amp;')
                                .replace(/</g, '&lt;')
                                .replace(/>/g, '&gt;')
                                .replace(/ {2,}/g, function(spaces) {
                                    // Change the spaces to $nbsp; except the last one
                                    for (var i = 1, fakeSpaces = '', space; space = spaces[i++];) {
                                        fakeSpaces += '&nbsp;'
                                    }
                                    return fakeSpaces + ' '
                                })
                            )
    // We add 10px to be sure it doesn't stick to the edges
    if ($autoResize.outerWidth() >= $input.outerWidth() - 10) {
        do {
            $both.css('font-size', --fontSize)
        } while ($autoResize.outerWidth() >= $input.outerWidth() && fontSize > 10)
        // 10px is the smallest font-size accepted
        if (fontSize === 10) {
            $input.off('keydown')
        }
    }
})​

Here is the jsFiddle.

Upvotes: 1

fineTuneFork
fineTuneFork

Reputation: 733

Yes,I think what @somebody is in trouble is doing is what they are doing in here.

  • Calculate how many letters will fit into the box - you know the width of the textbox. You know the font-size & padding that is being given here. So you know how many letters can be typed in the textbox before it overflows( not exactly) .

  • Or you can just type random letters & see how many can fit ! :)

  • Well, if you have time, you can as well dive into the events being fired when you keydown on the email address text box. You will learn a lot!

Upvotes: 0

user1432124
user1432124

Reputation:

$("input").keypress(function(){
if(this.value.length>43)//or some other value
{//do stuff here
}
});

Keydown is what you are looking for

Upvotes: 2

FelipeAls
FelipeAls

Reputation: 22161

You must use JavaScript to count how much characters've been typed already (I believe with .change() in jQuery) and change the font-size accordingly.

Upvotes: 0

Related Questions