2

Is there a way in JavaScript to get the maximum number of characters that can be displayed on an input field given a dynamic width (e.g. width = 100%)?

For example, if the value of an input field is "123456789" and due to width constraint, only "1234567" is displayable/visible, the maximum number of displayable characters is "7".

Example layout:

----------
|01234567|
----------

Current code: (I'm having problem with different font styles. Also, font-spacing is not yet considered. The code from getFontSize is from here.)

function countLetters()
{
    var inputLong = document.getElementById('inputLong');
    var fontSize = getFontSize(inputLong);
    var fieldWidth = getWidth(inputLong);
    console.log('Number of Visible Characters: ' + (fieldWidth / fontSize) );
}

function getFontSize(parentElement)
{
    return Number(getComputedStyle(parentElement, "").fontSize.match(/(\d*(\.\d*)?)px/)[1]);
}

function getWidth(parentElement)
{
    return parentElement.offsetWidth;
}
Community
  • 1
  • 1
Arci
  • 6,647
  • 20
  • 70
  • 98
  • The maximum number of characters depends on what characters appear there, among other things. It might be useful to explain *why* you would want to calculate such a quantity, which is really not even a well-defined concept as such. (Taken literally, the answer is that the number is infinite, since you can present any number of zero-width characters...) – Jukka K. Korpela Aug 05 '13 at 12:50
  • @JukkaK.Korpela: The reason for this is I want to be able to display ellipsis on input field in Android stock browsers. While text-overflow works on Chrome, it does not work on Android stock browser. So I'm left with the JavaScript solution. My plan is apply ellipsis on the visible characters of the input field using JavaScript which is the reason why I need to determine first the number of characters the input field can display. – Arci Aug 06 '13 at 07:35
  • Then I think you would need a loop that removes characters from the end until the remaining string plus the ellipsis fit into the available width. But it would probably be more productive to reconsider the reasons for wanting an input field with such behavior. – Jukka K. Korpela Aug 06 '13 at 08:25

2 Answers2

3

This depends on a lot of parameters: font used, font size, letter-spacing... It's not quite simple to know how many characters can fit in a determined size...

You can avoid these and says "okay, a letter is 8px wide (average) so the length is myInput.value.length * 8. Or you can set a monospace font, where every letter have the same width.

Maxime Lorant
  • 34,607
  • 19
  • 87
  • 97
  • Hi! Thanks for your answer! Can you provide a javascript for the calculation? Also, due to some constraint, I have no control on the size of the font. All sizes should be calculated with assumptions that they are dynamic. – Arci Aug 05 '13 at 09:02
  • If you takes 8px for 1 letter, so you'll have `nbLettersMax = input.offsetWidth / 8`. I forgot to mention the fact that user can change the browser font-size also... which breaks the assumption of 8px wide. – Maxime Lorant Aug 05 '13 at 09:07
  • Thanks, @Maxime, for the idea! I'm currently trying to create formula for it. – Arci Aug 05 '13 at 09:33
  • How do I consider the font-family in the computation? – Arci Aug 05 '13 at 09:51
  • After thoughts, the font-family hasn't effects on the max size of a letter (which is determine by the font-size). The only thing you can know wth the font-family is if the font is monospace (so all letters have the same width, good situation) or not. – Maxime Lorant Aug 05 '13 at 09:58
  • Can you please check my code? When I tried it, it gave me an incorrect result. – Arci Aug 05 '13 at 10:01
  • @MaximeLorant, font family surely affects the maximum width of characters (which is what matters here). The width depends on the choices of the font designer. – Jukka K. Korpela Aug 05 '13 at 12:47
  • The font size is determined by the `font-size` CSS attribute, whatever the font is. – Maxime Lorant Aug 05 '13 at 12:48
2

As Maxime Lorant said, its depends on a lot of parameters. If you would like to get a approximate size, please try this:

MODIFIED

<style type='text/css'>
#your_input{
    font-family:font-family:"Times New Roman",Georgia,Serif;
    font-size:12px;
    letter-spacing:0px;
}
#ruler{
    font-family:font-family:"Times New Roman",Georgia,Serif;    
    font-size:12px;
    letter-spacing:0px;
    position: absolute;
    visibility: hidden;
    height: auto;
    width: auto;
}
</style>
<script language="javascript">
    function calLen() {
        // calculate the approximate length of characters
        var input_width = document.getElementById('your_input').offsetWidth;
        var ruler_width = document.getElementById('ruler').offsetWidth;
        var ruler_text = document.getElementById('ruler').innerHTML;
        var ruler_len = ruler_text.length;
        var input_len = parseInt((input_width/ruler_width)*ruler_len,10);
        alert("approximate length is " + input_len);
    }
</script>

<body>
    <input type="text" id="your_input" value="">
    <div id="ruler">0123456789abcdefghijklmnopqrstuvwxyz</div>
    <a href="javascript:calLen()">calLen</a>
</body>
naota
  • 4,695
  • 1
  • 18
  • 21
  • Uhmmm.. I hope I'm not asking for too much but can you translate this to plain JavaScript? Or can you provide a line by line explanation so I can translate it to plain JavaScript? – Arci Aug 05 '13 at 09:46
  • I made a code using `inputFieldWidth / fontsize` but the value is incorrect when I use different font-families. – Arci Aug 05 '13 at 09:50