Not including whitespace when detecting text width with `<span>` trick - javascript

I have implemented a jQuery pluggin to correct the width of <input/> elements depending on how much text they have, as shown:
$.fn.correctWidth = function () {
var tempSpan = $('<span>')
.html(this.val())
.css('font-size', this.css('font-size'))
.insertBefore(this);
this.width(tempSpan.width());
tempSpan.remove();
return this;
};
The problem is that, sometimes, the <span> element's width is much larger than the actual text width.
It seems that this occasional problem is because the detected width includes the whitespace between the end of the text and the end of the line.
How can I make sure that the whitespace is not included? Is there an alternative approach?

Try to change
this.width(tempSpan.width());
To
this.width(tempSpan.innerWidth());

You better set also the same font-family(the width of font usually differs).
Furthermore you should use
$('<pre style="display:inline;"/>')
...instead of the span.
Repeated whitespaces will be ignored in a span, but not in a text-input(and not inside pre)

Related

Get the width of word-wrapped text

I have a div whose text content is word wrapped. I'd like to get the post-word-wrapped width of this text using Javascript and/or JQuery. What would be the best way to go about this?
EDIT: To be clear, I'm using the div in a flexbox layout where its flex value is 0 and a max-width is applied. For some reason, the div has applied additional trailing whitespace to it and I'm having trouble getting rid of it.
Get the width of the div, i.e.
var w = myDiv.offsetWidth;
See: https://developer.mozilla.org/en-US/docs/DOM/element.offsetWidth
jQuery:
var textWidth = $('div').width();

How to find absolute or relative position of last letter inside an input field?

Maybe this is a strange question. Please, check Bellow you will understand.
Empty input type text, width=200px :
[____________________________]
Filled input type text, width=200px :
[abcdefg_____________________]
If input left is 0 how to find the absolute or relative position where the g letter is???
When user enters some text I want to display under last letter a simple div...
The text size hacks are OK, but you could alternatively use a visiblity: hidden span that moves your info div. HTML snippet follows:
<div><input type="text" value="hgello!!" onkeydown="document.getElementById('spacer').innerHTML = this.value;" /></div>
<div><span id="spacer" style="visibility: hidden;"></span>Character</div>
This way you can rely on the browser rendering the same font in roughly the same way into a span.
I can only think of one way to reliably do this, and it's quite dirty.
1) Use a content editable div floated left:
2) surround that div with another with a width of 200, border, and onlick sets focus to the editable div
3) put the div you want to show after the last letter after the editable div, also floated left
Result:
http://jsfiddle.net/tybro0103/zMezP/1/
Click on the box and start typing. The green box will move along with the cursor position.
In order to use this as a text field in a form you'll need to make a hidden input field. On form submit set the hidden field's value to editable div's inner html.
There is no built in "textWidth" param, sadly. However, a hack that will work pretty well: you can count the characters, guess at their width, and set your div "left" param equal to the character count * width (and make sure its absolutely positioned). something like:
var characterWidth = 6.8; //have to guess at this until it works...
var targetLocation = document.getElementById('yourInput').value.length * characterWidth;
document.getElementById('yourDiv').style.left = targetLocation + "px";
Run this script on a timer, every half second or so (or animate to the target location with jquery) and you should be in business.
Hope that helps.
As noted - this will only work if the font is monospaced and the user doesn't modify font size at all.
The only way I konw how to do that is to calculate the width of a letter then multiply it by the number of letter in your input.
Or
in a display:none div create a input width the maxlength attribute to the number of character in the current input. Then get the width of it.
set font size to input
make screenshot of input with text and see how much px used for 1 symbol (average)
count symblos * average width of 1 + input left padding = what you want :)
easy solution
I'm not really sure of the question but in my opinion you could do something like:
var len = 0;
$(document).ready(function(){
len = $('#input').val().length;
}
Now you could prepend the no of white spaces equal to the length in your target div.
Inspired by tybro's answer, I came up with this, which solves a problem in your question. If the textbox is a fixed length, what happens if the last letter is not visible at all? What co-ordinate should be reported then? Anyway, this gets around it by expanding the textbox indefinitely.
// markup
<div id="textbox">
<span id="edit" contentEditable></span>
<span id="end"></span>
</div>
<div id="report">x:? , y:?</div>
// css
#textbox {
border: solid black 1px;
min-height: 1em;
white-space: nowrap;
}
// javascript
$(function() {
$('#textbox').click(function() {
$('#edit').focus();
});
$('#edit').keypress(function() {
var endoff = $('#end').offset();
$('#report').html('x:' + endoff.left + ' , y:' + endoff.top);
});
});
The only thing I'm not sure of is when does keypress fire if it's before the content has changed, that's a problem. You could get round it by introducing a timeout or probably theres an even better solution. Unfortunately the keyup event doesn't seem to work on contentEditable things (in Firefox 5 anyway).
Hope this helps.

What characters will a TextArea wrap at, other than spaces?

I'm working on the latest version of my plugin, Textarea Line Counter (http://mostthingsweb.com/?p=84). To make it even more accurate, I want to identify regions of text that wrap because they are too large to fit on the line (like a sequence of repeated characters).
I'm assuming that browsers only wrap text at spaces. Are there any other characters that lines can be wrapped at? Thank you,
Looks like it depends on the browser, my Opera wraps also on e.g. + % ? $ / ( [ { } \ ° ! ¿
Safari/Chrome on ¿ ? too
(guess there are lots more)
Nice idea for a plugin. Fighting the accuracy issues is going to be a challenge.
There's not a universal catch all for the way textarea is going to handle a string (other than line breaks at spaces), or using word-wrap.
IE produced a break with . , () {} ?, but not with / * = +
In this example, textarea seems to have that "special" feeling like a td
Based on all your advice, I have created a solution. It is rather large, and in fact I think I will make it into a separate plugin, as well as including it in my Textarea Line Counter. It works like this:
Create a div to act as a container, and set the font to something monospaced (i.e. every character is the same width)
Create a span within the container, and place a single letter.
Take the width measurement of the span (which will be the width of the letter, once margins, padding, and some other CSS attributes are cloned)
Create another div within the container and clone its CSS attributes. Set it's width to be two times the width of the letter found in step 3, and record its height.
To test if a character will cause a wrap, set the text of the div to: A[some character]A. [some character] is a character you are trying to test.
Test the height of the div. If it is larger than the height found in step 4, the text has wrapped.
I'm looking forward to releasing this plugin. Thank you again for all your advice.
some browsers will break inside words if the word is longer than the col width,
otherwise they break on spaces.
I notice some browsers set this by default- you can, too in most bowsers with:
textarea{word-wrap: break-word}
you can be sure it is not set by using textarea{word-wrap: normal}

Get string length in pixels with JavaScript

Let's say I have the string "Hello". This string is obviously five characters in length, but what is its length in pixels? Is there an easy way to determine this length in JavaScript? I have thought of a solution where an extra div would have to be displayed to the user, but this way seems hacky and complicated.
In the bigger picture, I am trying to determine how many spaces would be necessary to fill that length of the string. As you can probably tell from above, I think the best option would be to simply measure the length of the string and a single space character from the user's perspective and calculate how many spaces should replace the text based off of that. This is going to be displayed in an HTML input text, by the way.
Thanks.
You can determine the number of pixels the container of the string. You can do this by creating a hidden element in the DOM, setting the inner HTML to the string and then asking for the width.
I don't think their is a good, easy way to do that, except computing the length of a container. The width depends on the font-size, the font, the letter-spacing, it will be different depending on the browser etc...
I've used this to determine the text length in pixels (jQuery syntax):
var txtLen = $(<selector>).text().length * $(<selector>).css('font-size').slice(0,-2);
where selector is whatever you use to target the specific element. Adjust where needed (if the font-size is not set in px).
For example:
var txtLen = $('table td').text().length * $('table td').css('font-size').slice(0,-2);
Real-life use of this was when I needed to determine whether to show the tooltip on a td with a fixed width - if td is wider than its contents, there is no need to show the tooltip.
Things stated in Robin's answer still apply.

JavaScript: Check width of a <div> object before placing it

Consider:
$("#PlotPlace").append('<div style="position:absolute;left:200px;top:40px;font-size:smaller">Hello world!</div>');
I need to execute that line only if the width of the resultant text would be less than 60px. How can I check the width before placing the object?
Unfortunately, the div will only have a width value once it is rendered into the DOM.
I would append that content to an inconspicuous area of the document, perhaps even absolutely positioned so that no flow disruption occurs, and make sure that it is set to "visibility:hidden". That way it will be inserted into the DOM and be rendered, but be invisible to the viewer.
You can then check the width on it, and move it into position and set it to "visibility:visible" at that point. Otherwise, you can remove it from the document.
Maybe you can append it invisible, then check it's width, and then consider to show or hide.
$("#PlotPlace").append('<div style="position:absolute;left:9001px;top:40px;font-size:smaller">Hello world!</div>');
var div = $('#PlotPlace').children("div");
if(div.width() < 60)
div.css({left:200})
Sounds like something you'd have to hack. I don't believe the JavaScript runtime in any browser has an event you can hook into in between calculating the layout and displaying the element, so you can add it in a way that it can't be seen and doesn't affect the height (doesn't cause additional scrolling), and then show/hide it based on the width at this point. It's hacky and ugly, but because you don't have many event hooks it might be the only way to do it.
You can´t. At least not so easy. The text you insert is written in a specific font, which must be rendered by the browser, then you know the width of the element. By the Way, what exactly do you want to insert, with such a restriction? Wouldn´t it be simpler to cut the text within the output parameters?

Categories

Resources