PDA

View Full Version : Appending text to an element?



shachi
03-10-2007, 11:43 AM
Hello all,

This sounds pretty easy but in fact it isn't. I am not simply talking about appending text to an element(using the appendChild). This is my situation:

I have the following text(already on the document):



This is some text.


Notice that the "t" is bold(and red), what I want now is to move the <b></b> tag to the left each time the user presses the left arrow key. So if the user
presses the left arrow key once, it would look like this:



This is some text.


So basically I want a "moving" tag.

I hope I was able to clear my point.

Thanks all!!

jscheuer1
03-10-2007, 04:54 PM
I would think this belongs in the javascript section. That said, you could approach this with the DOM or with innerHTML. You would need to capture the onkeydown event. Once you have the relevant event captured in a way appropriate to your layout and intentions, you test the key, if it is the left arrow run a function. I worked this out document wide, using innerHTML:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
#mb b {
color:red;
}
</style>
<script type="text/javascript">
function moveBold(el){
var t=el.innerHTML, c=t.indexOf('<')-1, new_t='';
if(c<0)
c=t.length-1;
t=t.replace(/<[bB]>|<\/[bB]>/g, '');
while(/[ \.,]/.test(t.charAt(c)))
c--;
for (var i_tem = 0; i_tem < t.length; i_tem++)
if([i_tem]==c)
new_t+='<b>'+t.charAt(c)+'<\/b>';
else
new_t+=t.charAt(i_tem);
el.innerHTML=new_t;
if(!/<[bB]>/.test(new_t))
moveBold(el);
}
document.onkeydown=function(e){
var e=e? e : window.event;
if(e.keyCode==37)
moveBold(document.getElementById('mb'));
}
</script>
</head>
<body>
<span id="mb">This is some tex<b>t</b>.</span>
</body>
</html>

That's just a rough idea, the code could be better protected and the event assignment could use the 'play nice' techniques of addEventListerner and attachEvent.

shachi
03-10-2007, 05:10 PM
Awesome, this is perfectly what I wanted, but can you please comment out the codes?(sorry but I suck at js)

jscheuer1
03-10-2007, 05:45 PM
Ok:


function moveBold(el){
//Declare variables, especially determine the postion of the
//bold tag while defining c as the previous char #
var t=el.innerHTML, c=t.indexOf('<')-1, new_t='';
if(c<0) //if no bold tag, start from the end of the text
c=t.length-1;
t=t.replace(/<[bB]>|<\/[bB]>/g, ''); //remove existing bold tag
while(/[ \.,]/.test(t.charAt(c))) //skip spaces periods and commas by -
c--; // decrementing the character number for the char next in line
for (var i_tem = 0; i_tem < t.length; i_tem++) //loop the text one char at a time
if([i_tem]==c) //if the char is next in line -
new_t+='<b>'+t.charAt(c)+'<\/b>'; //enclose it in the new bold tag
else
new_t+=t.charAt(i_tem); //otherwise just use it 'as is'
el.innerHTML=new_t; //set the tag's innerHTML to the new string
if(!/<[bB]>/.test(new_t)) //if no bold tag -
moveBold(el); //do it again
}
document.onkeydown=function(e){ //assign document-wide event for keydown
var e=e? e : window.event; //determines the event object across browsers
if(e.keyCode==37) //check its key code, if it is the left arrow -
moveBold(document.getElementById('mb')); //run the function on the tag
}

Also, since you like it. Here is a version of it without any or (very little) global level exposure, one minor efficiency, and the 'play nice' feature I mentioned before:


<script type="text/javascript">
(function(){
function moveBold(el){
var t=el.innerHTML, c=t.indexOf('<')-1, new_t='';
t=t.replace(/<[bB]>|<\/[bB]>/g, '');
if(c<0)
c=t.length-1;
while(/[ \.,]/.test(t.charAt(c))){
c--;
if(c<0)
c=t.length-1;
}
for (var i_tem = 0; i_tem < t.length; i_tem++)
if([i_tem]==c)
new_t+='<b>'+t.charAt(c)+'<\/b>';
else
new_t+=t.charAt(i_tem);
el.innerHTML=new_t;
}
function grabKey(e){
var e=e? e : window.event;
if(e.keyCode==37)
moveBold(document.getElementById('mb'))
}
if ( typeof document.addEventListener != "undefined" )
document.addEventListener( "keydown", grabKey, false );
else if ( typeof document.attachEvent != "undefined" )
document.attachEvent( "onkeydown", grabKey );
else {
if ( document.onkeydown != null ) {
var oldOnkeydown = document.onkeydown;
document.onkeydown = function ( e ) {
oldOnkeydown( e );
grabKey(e);
};
}
else
document.onkeydown = grabKey;
}
})();
</script>

shachi
03-11-2007, 06:55 AM
jscheuer1: sorry if I am being too demanding but is there a way to move the tag, to the right too(I've been playing with this for ages and still can't figure it out)?

jscheuer1
03-11-2007, 08:04 AM
The two functions, moveBold and moveBold2, could be combined or worked out to use a third function that contains the routines common to both but, it works fine this way:


<script type="text/javascript">
(function(){
function moveBold(el){
var t=el.innerHTML, c=t.indexOf('<')-1, new_t='';
t=t.replace(/<[bB]>|<\/[bB]>/g, '');
if(c<0)
c=t.length-1;
while(/[ \.,]/.test(t.charAt(c))){
c--;
if(c<0)
c=t.length-1;
}
for (var i_tem = 0; i_tem < t.length; i_tem++)
if([i_tem]==c)
new_t+='<b>'+t.charAt(c)+'<\/b>';
else
new_t+=t.charAt(i_tem);
el.innerHTML=new_t;
}
function moveBold2(el){
var t=el.innerHTML, c=t.indexOf('<')+1, new_t='';
t=t.replace(/<[bB]>|<\/[bB]>/g, '');
if(c>t.length-1)
c=0;
while(/[ \.,]/.test(t.charAt(c))){
c++;
if(c>t.length-1)
c=0;
}
for (var i_tem = 0; i_tem < t.length; i_tem++)
if([i_tem]==c)
new_t+='<b>'+t.charAt(c)+'<\/b>';
else
new_t+=t.charAt(i_tem);
el.innerHTML=new_t;
}
function grabKey(e){
var e=e? e : window.event;
if(e.keyCode==37)
moveBold(document.getElementById('mb'))
else if(e.keyCode==39)
moveBold2(document.getElementById('mb'))
}
if ( typeof document.addEventListener != "undefined" )
document.addEventListener( "keydown", grabKey, false );
else if ( typeof document.attachEvent != "undefined" )
document.attachEvent( "onkeydown", grabKey );
else {
if ( document.onkeydown != null ) {
var oldOnkeydown = document.onkeydown;
document.onkeydown = function ( e ) {
oldOnkeydown( e );
grabKey(e);
};
}
else
document.onkeydown = grabKey;
}
})();
</script>

jscheuer1
03-11-2007, 08:51 AM
Yeah, here it is with the two functions combined:


<script type="text/javascript">
(function(){
function moveBold(el,d){
var t=el.innerHTML, c=t.indexOf('<')+d, new_t='';
t=t.replace(/<[bB]>|<\/[bB]>/g, '');
c=c<0? t.length-1 : c>t.length-1? 0 : c;
while(/[ \.,]/.test(t.charAt(c))){
c+=d;
c=c<0? t.length-1 : c>t.length-1? 0 : c;
}
for (var i_tem = 0; i_tem < t.length; i_tem++)
if(i_tem==c)
new_t+='<b>'+t.charAt(c)+'<\/b>';
else
new_t+=t.charAt(i_tem);
el.innerHTML=new_t;
}
function grabKey(e){
var e=e? e : window.event;
if(e.keyCode==37||e.keyCode==39)
moveBold(document.getElementById('mb'),e.keyCode-38)
}
if ( typeof document.addEventListener != "undefined" )
document.addEventListener( "keydown", grabKey, false );
else if ( typeof document.attachEvent != "undefined" )
document.attachEvent( "onkeydown", grabKey );
else {
if ( document.onkeydown != null ) {
var oldOnkeydown = document.onkeydown;
document.onkeydown = function ( e ) {
oldOnkeydown( e );
grabKey(e);
};
}
else
document.onkeydown = grabKey;
}
})();
</script>

shachi
03-12-2007, 02:49 PM
Thanks, a billion!! I'll report you as soon as I get to test these. Thanks again.

shachi
03-14-2007, 07:00 PM
Is there a way to actually stop the bold moving after it get to the first character and the last character? And is it possible to put the <b></b> tag just one character after the last visible character? I mean it needs to be right after the last character typed.



test| |

# | | is the bold tag.


EDIT: The limiting bold tag is fixed. The other problem still persists.

Strangeplant
03-15-2007, 01:58 PM
I've learned quite a lot by reading this code although I have no use for it, myself. Very very good!

jscheuer1
03-15-2007, 03:08 PM
Is there a way to actually stop the bold moving after it get to the first character and the last character? And is it possible to put the <b></b> tag just one character after the last visible character? I mean it needs to be right after the last character typed.



test| |

# | | is the bold tag.


EDIT: The limiting bold tag is fixed. The other problem still persists.

Working from my last posted version, I commented out (green, these may be removed) and added (red):


<script type="text/javascript">
(function(){
function moveBold(el,d){
var t=el.innerHTML, c=t.indexOf('<')+d, new_t='';
if(t.indexOf('<')<0){
if(moveBold.limit==d)
return;
c=d==1? 0 : t.length-1;
}
t=t.replace(/<[bB]>|<\/[bB]>/g, '');
if(c<0||c>=t.length){
el.innerHTML=t;
moveBold.limit=d;
return;
}
//c=c<0? t.length-1 : c>t.length-1? 0 : c;
while(/[ \.,]/.test(t.charAt(c))){
c+=d;
if(c<0||c>=t.length){
el.innerHTML=t;
moveBold.limit=d;
return;
}
//c=c<0? t.length-1 : c>t.length-1? 0 : c;
}
for (var i_tem = 0; i_tem < t.length; i_tem++)
if(i_tem==c)
new_t+='<b>'+t.charAt(c)+'<\/b>';
else
new_t+=t.charAt(i_tem);
el.innerHTML=new_t;
}
function grabKey(e){
var e=e? e : window.event;
if(e.keyCode==37||e.keyCode==39)
moveBold(document.getElementById('mb'),e.keyCode-38)
}
if ( typeof document.addEventListener != "undefined" )
document.addEventListener( "keydown", grabKey, false );
else if ( typeof document.attachEvent != "undefined" )
document.attachEvent( "onkeydown", grabKey );
else {
if ( document.onkeydown != null ) {
var oldOnkeydown = document.onkeydown;
document.onkeydown = function ( e ) {
oldOnkeydown( e );
grabKey(e);
};
}
else
document.onkeydown = grabKey;
}
})();
</script>

shachi
03-15-2007, 04:07 PM
jscheuer1: Why is that even though I have a background color for the bold tag, it still disappears on spaces?

jscheuer1
03-15-2007, 04:19 PM
I decided that spaces should be excluded. I also excluded periods and commas. That can be changed as desired. It happens here in this while loop (mechanism red):


while(/[ \.,]/.test(t.charAt(c))){
c+=d;
if(c<0||c>=t.length){
el.innerHTML=t;
moveBold.limit=d;
return;
}
//c=c<0? t.length-1 : c>t.length-1? 0 : c;
}

Particularly:


while(/[ \.,]/.test(t.charAt(c))){
c+=d;

To have spaces included instead of being skipped use:


while(/[\.,]/.test(t.charAt(c))){
c+=d;

That will only exclude periods and commas. If you want no exclusions, you can get rid of the entire loop:


while(/[ \.,]/.test(t.charAt(c))){
c+=d;
if(c<0||c>=t.length){
el.innerHTML=t;
moveBold.limit=d;
return;
}
//c=c<0? t.length-1 : c>t.length-1? 0 : c;
}

shachi
03-15-2007, 04:47 PM
I've already tried that and it still seems to not work(it just doesn't work at the last space).

jscheuer1
03-15-2007, 08:05 PM
I see that this is only a problem in FF, not IE 7 or Opera 9.01. The weird thing in FF is that it sees that a space is there but, just won't count it when all a <b></b> tag contains is a space and it is trailing a span with nothing following it on that line. The generated HTML is reported as:


<span id="mb">. This is some text.<b> </b></span>

But, the background-color is not applied. In fact, if you do this:


<span>. This is some text.<b style="background-color:blue;"> </b></span>

FF will not apply the background. So, I would say it is a bug. However, if you simply let FF know that something else is coming on that line, it will render, ex:


<span id="mb">. This is some tex<b>t</b>. </span>&nbsp;

shachi
03-16-2007, 04:18 PM
Love it!! Thanks again and again and again jscheuer1!!

shachi
03-16-2007, 05:36 PM
I am sorry to bother you again ... but I have another problem.

Whenever I try to go up through a break, it messes up.

For e.g I have the following text:



bla
This is a test.||


# || is the bold tag

When I go to the left, the tag jumps and gets here:



bla||
This is a test.


Instead of going all the way to the left(of the same line) and then up.

And when I try going back to the original line(the lower one), it converts the <br /> tag to &lt;br&amp;gt;

Any ideas how it can be solved?

Thank you again.