Link to home
Start Free TrialLog in
Avatar of CPL593H
CPL593HFlag for Belgium

asked on

Append xhtml tags at arbitrary places in a text.

Hi Experts,

I'd like to be able to enclose snippets of existing text on a webpage at the click of a button. Kind of what jQuery's append does, but more arbitrary. It is my understanding that jQuery can append, say, <strong> tags to a pre-existing text without refreshing the page, but for that, the text has to be marked (i.e. it is possible to add <strong> to a <span>).

What I'd like to achieve is to append <strong> or <span> tags at arbitrary places, based on their offset (offset here means what window.getSelection().getRangeAt(0) can return).

Example:

<p span="line1">I want to ride my bicycle, I want to ride my bike.</p>

The function would be something like addStrong('line1', 15, 25); and it would transform the text like this:

<p span="line1">I want to ride <strong>my bicycle</strong>, I want to ride my bike.</p>

Any idea how to do that, in jQuery or pure Javascript?
ASKER CERTIFIED SOLUTION
Avatar of bui_trung_hieu
bui_trung_hieu
Flag of Viet Nam image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of CPL593H

ASKER

Hi,

Nice start.

First, sorry for my stupid typo. I meant , of course. I fixed it in the example code below, it should be OK now.

I wrote the example code below to show an annoying shortcoming of the script: if you click on the second link and then on the first link, it works. It you reverse the sequence (click on the first link then the second link), it fails. That is because the offsets are changed because of the insertion of a (17 characters). addStrong('line1', 46, 58); would perfectly work after having clicked on the first link. My goal is to be able to add an undefined number of 's and 's, so I can't use the script as is.

Counting the added tags lengths may become quickly hairy, so maybe a regexp ignoring everything between <> (and re-adding later) would do the trick. I don't master JS regexps enough to try it, though. It would give as an added bonus that with a slight modification, we could  also use variable-length tags, such as .

Do you think it's feasible? Or do you see another workaround to this problem?

Thanks!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
      "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
	<title></title>
	<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
	<script type="text/javascript">
	<!--
	// addStrong('line1', 15, 25);
	function addStrong(_oid, _start, _end) {
		//check element existence
		if ($('p#'+_oid).length==0) return;
		//select the element
		var content=$('p#'+_oid).html();
		//set new html
		$('p#'+_oid).html(content.substr(0,_start)+ '<strong>'+content.substr(_start, _end-_start)+ '</strong>'+content.substr(_end,content.length-_end))
	}
//-->
</script>
</head>
<body>
<p id="line1">I want to ride my bicycle, I want to ride my bike.</p>
<p><a href="javascript: addStrong('line1', 2, 14);">make the first "want to ride" bold</a></p>
<p><a href="javascript: addStrong('line1', 29, 41);">make the second "want to ride" bold</a></p>
</body>
</html>

Open in new window

Avatar of CPL593H

ASKER

(EE has the irritating habit of eating my lesser than and greater than signs, so here is the same texts, where the signs have been replaced by inoffensive [].)

Hi,

Nice start.

First, sorry for my stupid typo. I meant [p id="line1"], of course. I fixed it in the example code below, it should be OK now.

I wrote the example code below to show an annoying shortcoming of the script: if you click on the second link and then on the first link, it works. It you reverse the sequence (click on the first link then the second link), it fails. That is because the offsets are changed because of the insertion of a [strong][/strong] (17 characters). addStrong('line1', 46, 58); would perfectly work after having clicked on the first link. My goal is to be able to add an undefined number of [strong]'s and [span]'s, so I can't use the script as is.

Counting the added tags lengths may become quickly hairy, so maybe a regexp ignoring everything between [] (and re-adding later) would do the trick. I don't master JS regexps enough to try it, though. It would give as an added bonus that with a slight modification, we could  also use variable-length tags, such as [span style="color: red"].

Do you think it's feasible? Or do you see another workaround to this problem?

Thanks!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
      "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
	<title></title>
	<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
	<script type="text/javascript">
	<!--
	// addStrong('line1', 15, 25);
	function addStrong(_oid, _start, _end) {
		//check element existence
		if ($('p#'+_oid).length==0) return;
		//select the element
		var content=$('p#'+_oid).html();
		//set new html
		$('p#'+_oid).html(content.substr(0,_start)+ '<strong>'+content.substr(_start, _end-_start)+ '</strong>'+content.substr(_end,content.length-_end))
	}
//-->
</script>
</head>
<body>
<p id="line1">I want to ride my bicycle, I want to ride my bike.</p>
<p><a href="javascript: addStrong('line1', 2, 14);">make the first "want to ride" bold</a></p>
<p><a href="javascript: addStrong('line1', 29, 41);">make the second "want to ride" bold</a></p>
</body>
</html>

Open in new window

Avatar of CPL593H

ASKER

I changed a bit the expected behavior of my application so that it could work with this script (with heavy modifications). Thanks.