Click to See Complete Forum and Search --> : Need help doing a Find and Replace procedures in JavaScript (I'm using indexOf)


bholly
01-03-2003, 09:18 AM
Hello, I have constructed javascript code that half works. For example if I have this html code:

<table width="3"><tbody><tr><td width="3">hello</td></tr></tbody></table>

My javascript's main goal is to go thru the inputed html code which in my javascript is under the variable strTextData and find certain tags (in this case <td tag) and remove attributes that are not allowed (in this case width=). My code works if there are no tags with the width attribute in them, for example:

<table><tbody><tr><td width="3">hello</td></tr></tbody></table>

(the table tag does not have a width, but if it does, see first example, then my code won't work)

The reason is that I have the code using indexOf, it finds the indexOf <td tag and the indexOf the width= tag and sets them as variables a and c respectivel. If c comes after a then my code will delete the width, but if it comes before, for example like in a different tag like table, where width is allowd then it won't touch it. How do I make it find the width= attribute in the right spot?? without stopping at places where it is allowed?? Here is my code:

// external command for Cleaning (Salman)
if ("jsclean" == strCmdName)
{
var strTextData = eWebEditPro [sEditorName].getSelectedHTML();
alert(strTextData);

/* Tag: TD, Attribute: WIDTH */


if((strTextData.indexOf("<td ")!=-1) && (strTextData.indexOf("width=")!=-1))
{
var a = strTextData.indexOf("<td ");
var c = strTextData.indexOf("width=");

if (a<c)
{
var strTextData=strTextData.replace(/width=/i,"");
}

}

var theEditor = eWebEditPro[sEditorName];
eWebEditPro[sEditorName].pasteHTML(strTextData);

}

}

I appreciate anyone who can help me, thank you!

khalidali63
01-03-2003, 09:24 AM
did u look into DOM html manipulation at all?
or the way you are doing stuff that do not suite you?

Khalid

bholly
01-03-2003, 09:31 AM
I think I can only use javascript, how would I get it to find for example <td tag, then see if theres a width= in that specific tag:

For example

<td width="3">blabla</td>

now we have to keep in mind that width can occur after other attributes, for example:

<td height="3" width="3">blabla</td> and also if there is a width attribute in another tag, I don't want to accidently delete it.. for example..

<td height="3">blabla</td><table width="3">blabla</table>

in this case the width= does occur after the <td tag, but its in another tag where it is allowed.. so therefore the jscript must look between either <td and > tag or <td and </td> tags, whichever is easier.

khalidali63
01-03-2003, 09:35 AM
On the other hand if you must do it the way you are doing it right now,then here is a better approach.

instead of to look for td and width

just follow a strict pattern that td will always follow width with one space in between
<td width="X">

if you do this then use the ndexOf as u already are using to look for

if(indexOf("<td width=")>-1){
// now you can strip the <td append end tag ">"
//use the substring
I hope this points to a solution
}

Khalid

bholly
01-03-2003, 09:40 AM
I wish I could do that, but that will point to another problem, if there are other attributes then the order of the width= maybe displaced, if you look at my example again:

<td width="3">blabla</td>

Using your solution is would indeed work, however, if I get code that has other attributes in the td, for exampe:

<td height="3" width="3">blabla</td>

unfortunately there is no specific order that attributes must remain in tags, so width will not always follow td in this case, do you have any other ideas? Thanks.

khalidali63
01-03-2003, 10:11 AM
In this case will there be multiple td tags in 1 string that is being searched or it always be 1 td per search?
<table><tr><td width></td></tr>
<tr><td></td>
<tr><td width></td></tr>
<tr><td width></td></tr></table>


and so on

Khalid

bholly
01-03-2003, 10:13 AM
It will be multiple td tags, the input will be webpages that already exist, which will have most probably multiple td tags, and I need this javascript to make sure that it cleans the widths from any td tags that are in the code. Thanks.

khalidali63
01-03-2003, 11:03 AM
below is the code,it is not perfect,since ther has not been any effort to optimise it,but it works and does what you want.
Only restriction though,the value for width attribute must be in qoutes"" to be detected

<html>
<head>
<title>Untitled</title>
<script language="JavaScript1.2">
var ctr=0;
function stripTags(){
var strTextData = document.frm.txt.value;
var str = strTextData;
while(str.indexOf("<td")>-1){
var tdpos = str.indexOf("<td");
var nstr = str.substring(tdpos,str.length);
if(nstr.indexOf("width=")>-1){
var wPos = nstr.indexOf("width=");
var s = str.substring(0,tdpos);
var s1 = nstr.substring(0,wPos-1);
var s2 = nstr.substring(wPos+6,nstr.length);
var wlen = getWidthAttributeLoc(s2);
strTextData = s+s1+nstr.substring(wPos+6+wlen,nstr.length);
}
str = str.substring(tdpos+3,str.length);
}
alert( strTextData );
}

function getWidthAttributeLoc(s2){
var ln = s2.length;
var qtCtr = 0;
for (x=0;x<ln;x++){
var cat = s2.charAt(x);
if(cat=="\""){
qtCtr++;
}
if(qtCtr==2){
break;
}
}
return x+1;
}
</script>
</head>

<body>
<form name="frm">
<input type="Text" name="txt"></input>
<input type="Button" name="btn" onclick="stripTags();" value="Strip Tags"></input>
</form>

bholly
01-03-2003, 11:05 AM
Thanks so much, I'll go try out it now :).

bholly
01-03-2003, 11:12 AM
Khalid, I tried the code, but it didn't strip out the width, what part of your code is removing the width= ? Thanks.

bholly
01-03-2003, 11:41 AM
Hi Khalid, very sorry to bother you again, I tried your code, and its great, very much appreciated, however I was worried about one thing: Example:

<table width="3"><tbody><tr><td>blabla</td></tr></tbody></table><table width="3">

What if the <td> tag like in the example above has no width value, your code then jumps ahead and removes the one from the table tag afterwards, which is not allowed, is there anyway to make your code stop searching after it reaches the end td tag </td>? Thanks again.

khalidali63
01-03-2003, 11:52 AM
use this updated version

<html>
<head>
<title>Untitled</title>
<script language="JavaScript1.2">
/*
Author Khalid Ali
Date January 3,2003
Code writtine for bhoolly
the example html I entered in the text field is this
<table width="3" height="12"><tbody><tr><td height=120 width="203">hello</td><td width="150"> second width</td></tr></tbody></table>
you can put as many attributes within td or whatever the width may be
and it does get stripped.
<td width=\"150\"> second width</td>
*/
onload = stripTags;
var ctr=0;
function stripTags(){
var strTextData = document.frm.txt.value;
var str = strTextData;
if(str.length<=1)return;
var s = str.substring(0,str.indexOf("<td"));
strTextData="";
while(str.indexOf("<td")>-1){
var tdst = str.indexOf("<td");
var tdend = str.indexOf("</td>")+5;
var nstr = str.substring(tdst,tdend);
if(nstr.indexOf("width=")>-1){
var wPos = nstr.indexOf("width=");
var s1 = nstr.substring(0,wPos-1);
var s2 = nstr.substring(wPos+6,nstr.length);
var wlen = getWidthAttributeLoc(s2);
strTextData += s1+nstr.substring(wPos+6+wlen,nstr.length);
}else{
strTextData+=nstr;
}
str = str.substring(tdend,str.length);
}
alert( s+strTextData+str );
}

function getWidthAttributeLoc(s2){
var ln = s2.length;
var qtCtr = 0;
for (x=0;x<ln;x++){
var cat = s2.charAt(x);
if(cat=="\""){
qtCtr++;
}
if(qtCtr==2){
break;
}
}
return x+1;
}
</script>
</head>

<body>
<form name="frm">
<input type="Text" name="txt"></input>
<input type="Button" name="btn" onclick="stripTags();" value="Strip Tags"></input>
</form>
</body>
</html>

jeffmott
01-03-2003, 11:59 AM
When it comes to complex text manipulation nothing rivals regular expressions.

var str = "<table width=\"50\"><tbody><tr><td width=\"3\">hello</td></tr></tbody></table>";
str = str.replace(/(<td\s+[^>]*)width\s*=\s*(["'])\s*\d*\s*\2([^>]*>)/gi, "$1$3");

The only bug is that it will not be recognized if there are no quotes surrounding the value at all (double and single quotes are both recognized). I can look into it some more if it is really needed. Otherwise it will find every other legal way of writing it.

bholly
01-03-2003, 12:13 PM
Thanks for your help, I'll try out your code and see if I can get it working.

khalidali63
01-03-2003, 02:25 PM
I have attached solution 2 your problem,
it is as txt file,save it as an HTML file run.
Please let me know if you have any difficulty

Khalid

bholly
01-03-2003, 02:27 PM
Thank Khalid, I've tried it and it works great. Thanks for all your help.

jeffmott
01-03-2003, 05:49 PM
khalidali63
solution 2 your problem

What about...

Enter tag: <TD>
Enter attribute: width
HTML from attributes to be stripped: <table width="50"><tbody><tr><td width="3">hello</td></tr></tbody></table>

Enter tag: <td>
Enter attribute: width
HTML from attributes to be stripped: <table width="50"><tbody><tr><td width='3'>hello</td></tr></tbody></table>

Enter tag: <td>
Enter attributes: width
HTML from attributes to be stripped: <table width="50"><tbody><tr><td width = " 3 ">hello</td></tr></tbody></table>

It also breaks if there are no quotes surrounding the width value, but then again, so does mine. ;)

khalidali63
01-03-2003, 06:29 PM
its only matter of choice,bholly did not say that no qoutes were a problem...
It could ve been fixed in no time..
:D

Khalid

Scriptage
01-03-2003, 07:52 PM
This example does exactly as you want, no errors at all, it recognises attributes that are in quotes or not, however the code is messy:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
<title>Untitled</title>
</head>

<body>

<script>
function removeWidth(strTableData){
var tds=strTableData.split("<td");
var temp=tds[0];
for(var i=1; i<tds.length; i++){
var strTdEnd=tds[i].indexOf(">");
var strAfterData=tds[i].substring(strTdEnd, tds[i].length);
var tdSubstring=tds[i].substring(0, strTdEnd);
if(tdSubstring.indexOf("width=") > -1){
var strBeforeWidth=tdSubstring.split("width=")[0];
strBeforeWidth=strBeforeWidth.replace(/ /,"");
var strAfterWidth=tdSubstring.split("width=")[1].substring(tdSubstring.split("width=")[1].indexOf(" "), tdSubstring.split("width=")[1].length);
if(strAfterWidth.indexOf("=") == -1){
strAfterWidth="";
}
if(strBeforeWidth.length > strAfterWidth.length){
temp=temp+"<td"+strBeforeWidth+strAfterWidth+strAfterData
}else{
temp=temp+"<td "+strBeforeWidth+strAfterWidth+strAfterData
}
}else{
temp+="<td " + tdSubstring+strAfterData
}
temp=temp.replace(/ /," ");
}
return temp;
}
var strMyTable=removeWidth("<table><tr><td height='01' width='01' name='number 1'></td><td width='02' name='number 2'></td><td name='number 3'></td></tr><tr><td width='04' height='04' name='number 4'></td><td height='05' name='number 5'></td></tr></table>");
alert(strMyTable);
</script>

</body>
</html>

Regards
Scriptage

Scriptage
01-07-2003, 09:28 AM
Heres an updated version of the width stripper. It strips the width attribute from the td tags in the string regardless of whether they are quoted or not, it recognises tags with excess whitespace such as: < td> <td > < td > etc. It cleans up most excess whitespace ie:
< td height='50' class='td1' width='270' ></td>
becomes
<td height='50' class='td1'></td>
etc

<script>
var string="<table><tr><td width=10 height='10' ></td><td></td><td height='10' name='batesy' width='10' ></td></tr></table>";

var innerTd=string.split(/<\s*td\s*/ig);
var temp=innerTd[0];
for(i=1; i<innerTd.length; i++){
var space=" ";
var attributes=innerTd[i].substring(0, innerTd[i].indexOf(">"));
attributes=attributes.replace(/\s*width=\S*/ig,'');
attributes=attributes.replace(/\s*/,'');
if(attributes.length==0) space="";
temp+="<td" + space + attributes + ">" + innerTd[i].substring(innerTd[i].indexOf(">")+1, innerTd[i].length);
temp=temp.replace(/\s*>/g,'>');
}
alert(temp);
</script>

regards
Scriptage