HTML textarea; scroll vertically to text - javascript

I have an HTML textarea:
<textarea>
Some text
Another text in another line
BOOM
Hello there.
</textarea>
I want to be able to vertically scroll to the word BOOM so that it is visible (it doesn't matter on which line it appears).
Is this possible?

There's actually a way to do this using window.find() and some variation for IE browsers.
Here's what I came up with so far:
var gotoText = function(text) {
function iefind(string) {
var txt = document.body.createTextRange();
if (txt.findText(string)) {
txt.scrollIntoView();
txt.collapse(false);
}
}
if(!window.find) { // ie
iefind(text);
return;
}
// a double window.find() for backwards and forward search
if(!window.find(text, false, true)){
window.find(text, false, false);
}
};

$('textarea').animate({ 'scrollTop': 30 });
of course 30 is working for my own example with my cols and rows. so find the the right value for yourself.
Note to self:
There is no way of calculating the scroll height which a particular word is at however if you set a fixed value as your css line-height then you can see the story from the point of view that of boom is on for example the 4th line then its scroll height value is 4x (x:line-height)
but i can't really right now be bothered to check how good that will work when someone zooms in the browser. but worth a try for you as you have the case.

But how do I know that BOOM is 30 from the top?
Create a <div>, add it to the page and style it with exactly the same font, white-space, dimensions, border, padding and overflow as the <textarea> object. Wrap the ‘BOOM’ in a <span>, and measure the position of the span relative to the position of the div.
(This isn't a lot of fun.)

It's possible with some javascript!
Even if I'm late I hope it can be usefull to someone else!
I published an answer here:
http://blog.blupixelit.eu/scroll-textarea-to-selected-word-using-javascript-jquery/
It works perfectly with jsut one needed rule: Set a line-height n the css of the textarea!
It calculate the position of the word to scroll to just by doing some simple mathematic calculation and it worked perfectly in all my experiments!
Feel free to ask me anything you need about the code!

Related

Scroll With != Offset Width when no Ellipsis

I am trying to figure out whether an element has ellipsis. I am using this stackoverflow answer.
When I test on IE the scrollWidth is always greater than offsetWidth. Even if there are no ellipsis, the scrollWidth is 1px greater than the offsetWidth. Works fine of Chrome, as expected.
Please check this example. This will give you different values on IE and Chrome.
Is this happening due to a bug in IE? Is it a known issue? And is there a work around?
Do you mean a an actual text ellipsis or a css one?
If text it may be better to parse the element's text for three dots at the end. Something like this:
function hasEllipsis(text){
var regex = /\.\.\.$/;
return regex.test(text);
}

Detect overflow fails in Firefox using (this.clientWidth < this.scrollWidth)

We're trying to detect if an element is overflowing using this simple Javascript code:
this.clientWidth < this.scrollWidth
This works perfectly on Chrome/IE but on Firefox it fails in until there's too much overflowing.
The example can be seen here: http://colnect.com/en/coins/countries#-1;yemen
This page show a list of countries. We do vertical centering of the text if it fits in a single line. If it's too long for one line (which is why we want to detect the overflow), we change it so the text appears in two lines.
In this attachment you can see what happens on Firefox (depending on the width of your window). When the overflow isn't "big enough", it's not detected even though CSS has clearly added the ellipsis for it so it IS overflowing. First 4 "countries" shown are correct (the 4th even broke into two lines) but the others are not.
To recreate, simply start resizing your Firefox window slowly until you see where this breaks.
Any ideas? A different way to detect overflow?
Try this:
if you want to keep full name then, just remove text-overflow:ellipsis; from the selected class or id.
if you want to keep name in one line and no ... in last position, then set white-space: nowrap !important;overflow: hidden; in selected class
In my Firefox browser: (with center align and without text-overflow:ellipsis;)
(with center align and with text-overflow:ellipsis;)
you can choice any one.
I've noticed two things with your website. You are using white-space:nowrap and you have a transition: all on the cell class. I changed those to white-space:normal and disabled the transition and it worked fine with the wrapping.
The reason i disabled the transition is that I found that sometimes it takes a moment to change the text and break it to two lines :)
Give it a try and let me know if that works.
...also keep in mind that having an ellipsis for overflown elements may force the ellipsis to appear because it might be larger in width than the last character. I have encountered some times where without ellipsis the whole text could be shown, while using ellipsis removed my last character.
Please try this CodePen sample.
<div id='mydiv'>Some relatively long line of text to test an interesting question about Firefox behavior.</div>
<br><br><br>
<div id='dbgmsg'></div>
#mydiv {
width: 33%;
border: solid 1px gray;
white-space: nowrap;
overflow: hidden;
}
$(document).ready(function insertAds() {
function printWidthes(){
var clientWidth = $('#mydiv').get(0).clientWidth;
var scrollWidth = $('#mydiv').get(0).scrollWidth;
$('#dbgmsg').html("clientWidth = " + clientWidth + "<br>scrollWidth = " + scrollWidth);
}
$(window).resize(function(){
printWidthes();
});
printWidthes();
});
I've tested it on the latest Firefox version (35.0.1) on Window 7 and its behavior is absolutely correct. When the div size is less than the text size by even only one pixel then clientWidth becomes less than scrollWidth.
Try to test it on your computer; probably you have different Firefox version that causes the problem. BTW, did you saw that the numbers are wrong in debugger / print or it's just your guess? May be your site works wrong because any other reason?
I think this may be related to a (now resolved) bug in firefox.
Perhaps a different way of determining the scrollWidth and clientWidt is the answer (as brilliantly stated in why scrollwidth doesnt work) :
Apparently by hiding the element before reading the scrollWidth gives a different value than when visible.
element=document.getElementById("my_div");
var scrollWidth = $(element).css("overflow", "hidden")[0].scrollWidth;
alert('clientWidt h = ' + element.clientWidth + ', scrollWidth = ' + scrollWidth );
$(element).css("overflow", "visible");

Adding an absolute positioned element causes line break

So I have a "cursor" object created like so:
var cursor=document.createElement('span');
cursor.id="currentCursor";
cursor.innerHTML="|";
cursor.style.fontWeight="bold";
cursor.style.position = 'absolute';
cursor.style.marginLeft="-1px";
Then I add it to the page where someone clicks with this:
var selection = window.getSelection();
var currentRange = selection.getRangeAt(0);
currentRange.insertNode(cursor);
The problem I'm running into is in certain places (mainly end of lines) if the cursor object is added it creates a line break before the object. Using insertNode to move it to another area removes the line break. Also if I set the display to "none", wait for a few seconds and then set it back to "inline" the line break is removed.
This seems like maybe a browser bug in adding absolute elements, but I was wondering if someone had a workaround. I've tried setting the width to 0px but it has no effect.
Update
So if I change the cursor to
cursor.style.position = 'static';
It doesn't have random line breaks. However this causes space to be created around the element. Any way to not allow elements to create space around them?
Update 2
Added a fiddle to show the problem:
http://jsfiddle.net/Mctittles/pSg2D/1/
Original code is a bit large but I slimmed it down to highlight this problem.
If you click at the end of the smiley face and then type it causes line 33 to trigger creating a new text node. After typing a couple letters you'll see the cursor object is forced to the next line. Clicking somewhere else to move it makes the lines merge again.
If you un-comment lines 38 and 40 you'll see what I was talking about with making it initially display:none and changing it later. This time it doesn't cause a line break.
I took out some cross-browser code for fiddler, so this might only work in Chrome
However [position:static] causes space to be created around the element.
No, it doesn’t cause it – there is no actual space created “around it”, it’s just the display width of a character plus spacing in the used font, and that gives the span element itself a width that is more than the | character itself. But when you position the element absolutely, you don’t notice that, because it is taken out of the flow, so it doesn’t push the following characters to the right.
My workaround proposal: Don’t put | into the span as innerHTML, but leave it empty – and then implement the line by giving the element a border-left:1px solid. Remove position:absolute, so that it defaults to static.
Then you might probably not like the height your cursor is getting with that – but that can be fixed as well, by setting display to inline-block, and giving it a height as well.
Here, see how you like ’dem apples: http://jsfiddle.net/pSg2D/9/
You should use CSS instead. Using z-index and maybe even float would (atleast should) fix this.
Edit: Always make sure no other styles make it break line!

Create span around text based on offset

We are trying to fit the content in div inside main div. But half of the line is being cut. How should we avoid this. How should we identify that line and create span around those words and move it slightly up or down.
We were trying with offsetheight, offsetTop etc as we do not want to use scroll bar. Any idea in jquery to handle this.
Code here: jsfiddle
I am playing around with your code... I'm not 100% sure of what you are trying to accomplish.. but check out the revisions I made and let me know if it gets you any closer to what you are trying to do.
I added in the functionality for the next and previous and also modified your surrounding box so there is no padding. You can tweak all this, but maybe this will prevent the need to try to move stuff around via jquery?
DEMO: http://jsfiddle.net/r5eZ7/3/
$(".next").click(function() {
var visiblep = $(".content p:visible");
if (visiblep.next().length == 0)
{
$(".content p:first").show();
}
else
{
visiblep.next().show();
}
visiblep.hide();
});

How to have transparent fonts except for the 'text-caret' in a textarea?

I have a simple textarea and I need to make transparent letters while allowing the text-caret to be visible. When I apply the following rules then I get invisible caret:
textarea {
background: transparent;
opacity: 0;
}
When I type invisible text, I need to see the text-caret move.
EDIT: I need to make editor to edit td cell in table. When I click on a cell I show a textarea and start typing. On a each character letter, I insert a context in a cell. After that, I hide a textarea.
This jsFiddle DEMO uses an online tutorial method that has been slightly modified to create a non-native browser text-caret along with transparent text.
Also, this jsFiddle New Method I created handles that goal differently but isn't IE8 friendly.
Status Update: I've improved the above jsFiddle DEMO with this newer version titled:
jsFiddle New Method that's Newer!!
The above jsFiddle version now allows the inside of the text-area to be clicked and the caret will respect that clicked location. This extra functionality was made possible by a great question and answer here.
Time to throw my $0.02 in.
This is an answer to the question, as I understood it, that works, it's quick and dirty, so feel free to make suggestions. This code is untested, but I did create a working fiddle here: http://jsfiddle.net/66RXc/
<html>
<head>
<title>Testing</title>
<script type="text/javascript">
<!--
function call(val) {
document.getElementById('result').value += val.charAt(val.length - 1);
document.getElementById('result').value =
document.getElementById('result').value.substr(0, val.length);
document.getElementById('test').value =
document.getElementById('test').value.replace(/[^\^]/g, ' ');
}​
-->
</script>
</head>
<body>
<textarea name="textarea" cols="20" rows="5" id="test"
onKeyUp="call(this.value);"></textarea>
<textarea style="display:block" cols="20" rows="5" id="result" disabled>
</textarea>​
</body>
</html>
The way I approached it was every time a character is typed in textarea "test", copy it over to a hidden text box, and replace all the characters in "test" except ^ with spaces. The characters are hidden, and the carat is still there. The full text is still in the other box. You could use display:hidden instead of display:block to hide it.
This isn't exactly the best implementation in the world, just something I did quickly. You have to type kind of slow (~15-20 WPM) for it to work.
Here is a CSS3 solution for making the text, itself, transparent:
Set the color attribute to be color: rgba(0,0,0,0); for the text
The only problem is that the caret goes invisible to. I did a quick search and found out that the caret and its styling are completely at the disposal of the browser. As such, the only option that I can think of for you is to use Javascript to add a simulated caret to the end of what you are typing.
I have an idea of how to do this, but it's messy and I wouldn't exactly call it ideal - I am, however, going to write it in case it helps further someone else's idea:
add a hidden label to the page
make sure it's hidden and not display: none; (so that it has actual width)
set white-space: nowrap; to keep it all on one line)
make sure the text is styled exactly the same as the text in the textarea
add the element <span id="caret">|</span> right before the textarea (I will refer to this as the caret for the rest of the spec)
set its position to position: relative;
increase its z-index to make it overlay
shift it right in order to set it on top of where the ACTUAL caret's initial position would be
make a function to check take in the value of the textarea and check the width of the textarea against the position of the caret (lookup selectionStart if you don't know how to do this)
the problem here is that characters are not always the same length, nor are they always the same length as their counterparts in other fonts
to solve this, as text is entered into the textarea you should have it imitated in the hidden label you created in step 1
imitate only the text from the start of the textarea to the caret's current position
wrap each character (including spaces) in their own span
next you will have to call a function to compare the width of the label with the width of the textarea
if the label is less wide than the textarea, get the width of the last span in the hidden label and shift the caret to the right by that width, then move on to step 4
as this is function will be run as text is entered it will happen one character at a time
be careful here that the caret doesn't go outside the textarea when it's in its last and near last positions
if the label is wider than the textarea:
add the widths of the characters (spans) in the label one at a time until you reach the width of the textarea
shift the position of the caret down by the height of the font and back to the horizontal starting position (as the caret's position is relative, just change its left position back to (0 + offsetToACTUALCaretPosition)
use a flag (e.g. class="break") to mark the last span (character) in the previous row
call the width comparison function again
make sure that you include a condition to check for the flags that you added at the end of each "row" (if any)
if you haven't already, apply any desired CSS styles to the caret span and change the color of the textarea's text to be color: rgba(0,0,0,0);
Caveats:
this will have a lot of overhead for the tiny job it does
you will have to adjust this method to account for padding
you will have to adjust this method to add support for deleting characters and moving the carets to an earlier position (to the left)
if you leave the textarea scrollable, you will have to add support for that (also for similar settings, like static heights causing text to scroll or move off screen/out of the textarea's visible area)
As I said before, I know that this solution is very rough, but it may help someone come up with a better one.
Good luck!
Based on your edit, if you need to just hide a textarea why don't you use jQuery $('#your_id').hide();

Categories

Resources