Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

This works in IE, not in Firefox...any ideas? 1

Status
Not open for further replies.

PushCode

Programmer
Dec 17, 2003
573
0
0
US
I have the following js that works correctly in IE, but not in firefox. It's just intended to hide a couple of form fields.

Using the Firefox error console, I see that the error generated is: "control is undefined" and it points to this line: control.parentNode.parentNode.style.display="none";

Adding if (control) before this line eliminates the error, but of course the fields don't get hidden either, so no dice. Any thoughts? Here's the full script:
Code:
_spBodyOnLoadFunctionNames.push("hideFields");

function findacontrol(FieldName) {
   var arr = document.getElementsByTagName("!");//get all comments
   for (var i=0;i < arr.length; i++ )
   {
      // now match the field name
      if (arr[i].innerHTML.indexOf(FieldName) > 0) {
         return arr[i];
      }
   }
}

function hideFields() {
   // uncomment the next line if you are troubleshooting
   // debugger;
   var control;
   // Add the two lines below for each control to be hidden
   control = findacontrol("State");
   control.parentNode.parentNode.style.display="none";
   control = findacontrol("PR Number");
   control.parentNode.parentNode.style.display="none";
}
 
Hi

PushCode said:
Code:
document.getElementsByTagName("!");//get all comments
I never heard such thing before. But would not expect it to work.

The way to search for HTML comment nodes is to check [tt]childNodes[/tt] recursively :
JavaScript:
[b]function[/b] [COLOR=darkgoldenrod]getcomment[/color][teal]([/teal]where[teal])[/teal]
[teal]{[/teal]
  [b]for[/b] [teal]([/teal][b]var[/b] i[teal]=[/teal][purple]0[/purple][teal],[/teal]l[teal]=[/teal]where[teal].[/teal]childNodes[teal].[/teal]length[teal];[/teal]i[teal]<[/teal]l[teal];[/teal]i[teal]++)[/teal] [teal]{[/teal]
    [b]if[/b] [teal]([/teal]where[teal].[/teal]childNodes[teal][[/teal]i[teal]].[/teal]nodeType[teal]==[/teal]Node[teal].[/teal]COMMENT_NODE[teal])[/teal]
      console[teal].[/teal][COLOR=darkgoldenrod]log[/color][teal]([/teal]where[teal].[/teal]childNodes[teal][[/teal]i[teal]])[/teal]
    [COLOR=darkgoldenrod]getcomment[/color][teal]([/teal]where[teal].[/teal]childNodes[teal][[/teal]i[teal]])[/teal]
  [teal]}[/teal]
[teal]}[/teal]

Feherke.
 
This is for a SharePoint site. All SharePoint field controls have a <!-- comment --> tag, so I'm using this as a sort of universal identifier.

I'll try to incorporate your method and report back...
 
turns out, I don't know how to make this work with my code.

Can you/someone help me?
 
The reason for the error is the fact that in firefox your
Code:
var arr = document.getElementsByTagName("!")

Returns absolutely zero elements.

That is it can't find any elements with the tag name "!" because in Firefox comments have no tag Name.

If you are hiding form fields, why not search for form fields.

Code:
var arr = document.getElementsByTagName("input")

not sure how the html is set up, so can't you what else you may need to traverse through though.

----------------------------------
Phil AKA Vacunita
----------------------------------
Ignorance is not necessarily Bliss, case in point:
Unknown has caused an Unknown Error on Unknown and must be shutdown to prevent damage to Unknown.

Web & Tech
 
Hi

This version returns all found comment nodes as an array :
JavaScript:
[b]function[/b] [COLOR=darkgoldenrod]getcomment[/color][teal]([/teal]where[teal])[/teal]
[teal]{[/teal]
  [b]var[/b] result[teal]=[][/teal]
  [b]for[/b] [teal]([/teal][b]var[/b] i[teal]=[/teal][purple]0[/purple][teal],[/teal]l[teal]=[/teal]where[teal].[/teal]childNodes[teal].[/teal]length[teal];[/teal]i[teal]<[/teal]l[teal];[/teal]i[teal]++)[/teal] [teal]{[/teal]
    [b]if[/b] [teal]([/teal]where[teal].[/teal]childNodes[teal][[/teal]i[teal]].[/teal]nodeType[teal]==[/teal]Node[teal].[/teal]COMMENT_NODE[teal])[/teal]
      result[teal].[/teal][COLOR=darkgoldenrod]push[/color][teal]([/teal]where[teal].[/teal]childNodes[teal][[/teal]i[teal]])[/teal]
    result[teal]=[/teal]result[teal].[/teal][COLOR=darkgoldenrod]concat[/color][teal]([/teal][COLOR=darkgoldenrod]getcomment[/color][teal]([/teal]where[teal].[/teal]childNodes[teal][[/teal]i[teal]]))[/teal]
  [teal]}[/teal]
  [b]return[/b] result
[teal]}[/teal]
Note that I kept it simple. You could optimize it by doing [tt]Array.concat()[/tt] only when necessary.

I have a feeling that you need only one comment node at a time. So another optimization would be to tell it which node you need and make it to return only that one, as soon as it is found. But an even better optimization would be to use that function only once and store its result, then later search only that saved array. Of course, this would work only if comments are not altered dynamically with DOM methods.


Feherke.
 
I'm sure you're right that this is the fix. I just don't know how to implement it with the other js provided above. I tried replacing my findacontrol function with yours, like this:


function findacontrol(where)
{
var result=[]
for (var i=0,l=where.childNodes.length;i<l;i++) {
if (where.childNodes.nodeType==Node.COMMENT_NODE)
result.push(where.childNodes)
result=result.concat(getcomment(where.childNodes))
}
return result
}


But no luck. It's not hiding the fields now, in IE or Firefox. How do I make what you provided, work with what I already have?
 
Hi

My getcomment() expects a node as parameter. It searches recursively starting with that node. Regarding your findacontrol() function I have no idea how it should work. Please show us an HTML document on which findacontrol() is expected to work.


Feherke.
 
I think the problem here is actually looking into the comment to see the text, and have it match to the text provided.

So here:
Code:
control = findacontrol("State");
Finds a comment with the word State, and then moves up 2 parent levels to hide the input.

I would like to see the html, if you have ID's or unique identifiers for the form fields it would be easier to find, rather than having to rely on comment tags.





----------------------------------
Phil AKA Vacunita
----------------------------------
Ignorance is not necessarily Bliss, case in point:
Unknown has caused an Unknown Error on Unknown and must be shutdown to prevent damage to Unknown.

Web & Tech
 
findacontrol() is designed to look for comments, then traverse them to find the specified controls. The idea behind this is that All SharePoint form fields have a comment like those below, regardless of input type. Thus this is a one size fits all solution. Again, this works as expected in IE.

Here's some of the relevant HTML:
Code:
			<TABLE class="ms-formtable" style="margin-top: 8px;" border=0 cellpadding=0 cellspacing=0 width=100%>
			
		...
		<TR>
		<TD nowrap="true" valign="top" width="190px" class="ms-formlabel"><H3 class="ms-standardheader">
		<nobr>PR Number</nobr>

	</H3></TD>
		<TD valign="top" class="ms-formbody" width="400px">
		<!-- FieldName="PR Number"
			 FieldInternalName="PR_x0020_Number"
			 FieldType="SPFieldText"
		  -->
			<span dir="none">
		<input name="ctl00$m$g_2631fc69_1b25_4a63_9a7b_4f6ab5c1a158$ctl00$ctl04$ctl02$ctl00$ctl00$ctl04$ctl00$ctl00$TextField" type="text" maxlength="255" id="ctl00_m_g_2631fc69_1b25_4a63_9a7b_4f6ab5c1a158_ctl00_ctl04_ctl02_ctl00_ctl00_ctl04_ctl00_ctl00_TextField" title="PR Number" class="ms-long" /><br>
	</span>
			Project Request Number
			
		</TD>
	</TR>

	
		<TR>
		<TD nowrap="true" valign="top" width="190px" class="ms-formlabel"><H3 class="ms-standardheader">
		<nobr>Status</nobr>
	</H3></TD>
		<TD valign="top" class="ms-formbody" width="400px">
		<!-- FieldName="Status"
			 FieldInternalName="Status"
			 FieldType="SPFieldChoice"
		  -->
			<span dir="none"><select name="ctl00$m$g_2631fc69_1b25_4a63_9a7b_4f6ab5c1a158$ctl00$ctl04$ctl03$ctl00$ctl00$ctl04$ctl00$DropDownChoice" id="ctl00_m_g_2631fc69_1b25_4a63_9a7b_4f6ab5c1a158_ctl00_ctl04_ctl03_ctl00_ctl00_ctl04_ctl00_DropDownChoice" title="Status" class="ms-RadioText">
					<option selected="selected" value="New">New</option>

					<option value="Open">Open</option>
					<option value="Estimated">Estimated</option>
					<option value="WIP">WIP</option>
					<option value="Closed">Closed</option>
					<option value="Rejected">Rejected</option>
					<option value="SWHM Approved">SWHM Approved</option>

					<option value="Client Approved">Client Approved</option>
					<option value="Ready">Ready</option>
					<option value="Hold">Hold</option>
					<option value="Cancelled">Cancelled</option>

				</select><br></span>
			
			
		</TD>

	</TR>
...
</TABLE>
 
Hi

Ok, this one should fit better :
JavaScript:
[b]function[/b] [COLOR=darkgoldenrod]findacontrol[/color][teal]([/teal]content[teal],[/teal]where[teal])[/teal]
[teal]{[/teal]
  [b]var[/b] result
  [b]if[/b] [teal](![/teal]where[teal])[/teal] where[teal]=[/teal]document
  [b]for[/b] [teal]([/teal][b]var[/b] i[teal]=[/teal][purple]0[/purple][teal],[/teal]l[teal]=[/teal]where[teal].[/teal]childNodes[teal].[/teal]length[teal];[/teal]i[teal]<[/teal]l[teal];[/teal]i[teal]++)[/teal] [teal]{[/teal]
    [b]if[/b] [teal]([/teal]where[teal].[/teal]childNodes[teal][[/teal]i[teal]].[/teal]nodeType[teal]==[/teal]Node[teal].[/teal]COMMENT_NODE
    [teal]&&[/teal] where[teal].[/teal]childNodes[teal][[/teal]i[teal]].[/teal]textContent[teal].[/teal][COLOR=darkgoldenrod]indexOf[/color][teal]([/teal]content[teal])>[/teal][purple]0[/purple][teal])[/teal]
      [b]return[/b] where[teal].[/teal]childNodes[teal][[/teal]i[teal]][/teal]
    [b]if[/b] [teal]([/teal]result[teal]=[/teal][COLOR=darkgoldenrod]findacontrol[/color][teal]([/teal]content[teal],[/teal]where[teal].[/teal]childNodes[teal][[/teal]i[teal]]))[/teal]
      [b]return[/b] result
  [teal]}[/teal]
[teal]}[/teal]
Note that it has a change to work only in standard compliant browsers. Comments have no [tt]innerHTML[/tt], so [tt]textContent[/tt] should be used. But Explorer has no [tt]textContent[/tt], it uses the proprietary innerText instead. Try to use [tt]data[/tt] or [tt]nodeValue[/tt] instead of [tt]textContent[/tt], maybe one of them is known by Explorer too.

Feherke.
 
Hi

PushCode, keep in mind what Phil wrote earlier today :
Phil said:
If you are hiding form fields, why not search for form fields.
For example with [tt]querySelector()[/tt] you can reference the [tt]form[/tt] elements directly :
JavaScript:
document[teal].[/teal][COLOR=darkgoldenrod]querySelector[/color][teal]([/teal][green][i]'input[title="PR Number"]'[/i][/green][teal])[/teal]
document[teal].[/teal][COLOR=darkgoldenrod]querySelector[/color][teal]([/teal][green][i]'select[title="Status"]'[/i][/green][teal])[/teal]

[gray]// or generically, if you have no other elements with those title texts[/gray]

document[teal].[/teal][COLOR=darkgoldenrod]querySelector[/color][teal]([/teal][green][i]'*[title="PR Number"]'[/i][/green][teal])[/teal]
document[teal].[/teal][COLOR=darkgoldenrod]querySelector[/color][teal]([/teal][green][i]'*[title="Status"]'[/i][/green][teal])[/teal]
Of course, this exact code's portability is limited as Explorer supports [tt]querySelector()[/tt] only since version 8. But with jQuery you could use similar expressions without having to care about cross-browser issues.

Despite all that, I would still prefer my code posted at 2 Nov 11 15:01 together with the mentioned optimization.


Feherke.
 
I'd probably go for the input tags, and then filter by title attribute myself.

Otherwise yes, Feherke's comment finder should work.

----------------------------------
Phil AKA Vacunita
----------------------------------
Ignorance is not necessarily Bliss, case in point:
Unknown has caused an Unknown Error on Unknown and must be shutdown to prevent damage to Unknown.

Web & Tech
 
Got pulled away. Just tried Feherke's solution:
function findacontrol(content,where)
{
var result
if (!where) where=document
for (var i=0,l=where.childNodes.length;i<l;i++) {
if (where.childNodes.nodeType==Node.COMMENT_NODE
&& where.childNodes.textContent.indexOf(content)>0)
return where.childNodes
if (result=findacontrol(content,where.childNodes))
return result
}
}

I'm getting javascript error: Node is not defined. Thoughts?

Oh, and I can't just look for form fields. I need to be able to re-use this on display pages too, where there are no form fields.
 
Hi

PushCode said:
I'm getting javascript error: Node is not defined.
Is suppose that happens on Trident, as it works for me with Gecko, Presto and WebKit. Do it the quick & dirty way : replace [tt]Node.COMMENT_NODE[/tt] with 8.


Feherke.
 
Got it! It's working in Firefox and IE! Here's the final working function. Replaced Node.COMMENT_NODE with 8, and replaced textContent with nodeValue. Thanks so much for all of your help Feherke! Thanks also to vacunita!

Code:
function findacontrol(content,where)
{
  var result
  if (!where) where=document
  for (var i=0,l=where.childNodes.length;i<l;i++) {
      if (where.childNodes[i].nodeType==8
      && where.childNodes[i].nodeValue.indexOf(content)>0)
        return where.childNodes[i]
        if (result=findacontrol(content,where.childNodes[i]))
      return result
  }
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top