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 Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using getAttribute to get a custom attribute? 1

Status
Not open for further replies.

clone45

Programmer
Mar 28, 2006
22
US
Hello!

I'm writing a form validation script that's supposed to iterate through each of the fields in a form and look for tags that contain a custom attribute called validation_style.

A sample tag looks something like:

<input name="population" type="text" validation_style="numeric">

My javascript looks like this:

for(y=0; y < the_form.elements.length; y++)
{
form_element = the_form.elements[y];
validation_style = form_element.getAttribute("validation_style");

alert(validation_style); // should eventually print out numeric
}

This works great in IE, but not in Firefox nor in Opera. I *think* that the getAttribute() call isn't finding my custom attribute, but I'm no expert.

Thanks!
- Bret
 
If you get an array of elements on the page and loop through them you can just grab the custom tag value like this.
In the code below objForm was the name of the form and passed in with the function call. You can access it directly if you need to, this is just a simplified excerpt from my own validation code.

Code:
var elArr = objForm.elements;
for(var i=0;i<elArr.length; i--) { 
  with(elArr[i]) {
    var v = elArr[i].validation_style;
    if (v)
      alert(validation_style);
  }
}

Stamp out, eliminate and abolish redundancy!
 
Thanks! That solved the issue in Opera, but Firefox is still not identifying the custom tag.

Here's the modified ocde:

Code:
	for(y=0; y < the_form.elements.length; y++)
	{
		with(the_form.elements[y])
		{
			var v = the_form.elements[y].validation_style;

			if (v) alert("testing: " + v);

			alert("testing: " + v + " " + y);
		}
	}

Any insights would be highly appreciated!
 
I take it back.. actually, I think this code is working only for IE. I can't get it to work for either Opera or Mozilla Firefox. :-( Any suggestions?
 
I tested in Firefox here and it does not work. Not certain why. It could be that their DOM implementation does not allow for the custom tags but I do not know I have almost no experience supporting FF or anything other than IE really.

Well, a better approach than custom tags (which is what I currently use but want to get away from) is to put the validation info inside comment tags. You can read the document innerHTML string and then parse out the comment tags looking for validation data. I plan on attempting this in the near future but have not had time yet.

Jemminger has created his own validation system that uses comment tags rather than custom tags inside the input fields. It allows for XHTML validation as well.
I have not looked over his code, just the capabilities of it and think that ultimately my own system will suit my needs better but the idea of putting the validation info into comments is a good one.
Ultimately I plan to build an interface to generate the validation data for a given form within a GUI but that is way off right now.

If you find out how to get the tags working in the other browsers let me know. I will play around with it a bit and see what happens myself.


Stamp out, eliminate and abolish redundancy!
 
clone45, this code is a bit rough but is a possible alternative.
I put the validation commands into div tags.
The div tags have both ID and Name properties because IE reads the ID when using getElementsByName but ignores the Name while FireFox is reading the Name tag but ignoring ID.
There are other ways to compensate but this was quick.

The divs all have the same name/id so they will read in as an array. I grab the innerHTML of each div, strip out the comment tag and then split the commands using the pipe symbol. I am assuming multiple possible validation commands per field which is why I have the pipe as a separator but you could remove that section and the associated loop and just use a single command per field.
If you use it as is then the alert would be replaced with a function call to the function for that type of validation.

The divs can be stored anywhere on the page, they do not have to be before or after the input they are related to.
The first value in the div is the name of the field it is associated with followed by a pipe separator and then the validation types.

As I said it is rough but shows an approach that might work cross browser.
I can see a lot of other possible ways to do this but this one came together quickest for me and is a good starting point. :)

Code:
<html>
<head>
<script type="text/javascript">
function testvalid()
{
  var validArr=document.getElementsByName("validator");
  for(var i=0; i<validArr.length; i++)
  {
    var myval = validArr[i].innerHTML.substring(5,(validArr[i].innerHTML.length-4));
    var arrCommands = myval.split('|'); //Split values at |
    var fldname = arrCommands[0];
    for(var x=1; x<arrCommands.length;x++)
    {
      alert(fldname + " Validates with: " + arrCommands[x]);
    }
  }
}
</script>
</head>
<body>
<form name="the_form">
<input name="field1" type="text"><br>
<div id="validator" name="validator"><!-- field1|A|B|C --></div>
<input name="field2" type="text"><br>
<input name="field3" type="text"><br>
<div id="validator" name="validator"><!-- field3|D|E|F --></div>
<input name="field4" type="text"><br>
<div id="validator" name="validator"><!-- field4|G|H|I --></div>
</form>
<input type="button" value="Go" onclick="testvalid()">
</body>
</html>

Stamp out, eliminate and abolish redundancy!
 
The op's original post function segment works just fine in ie, ff/nn and op. Some echo null, some just empty for fields without the custom attribute. The problem lies elsewhere. The follow-ups, I do not read with attention.
 
Have you defined the variable the_form something like this?
[tt] var the_form=document.forms["formname"];[/tt]
Or just in case the name is "the_form", then at least this too.
[tt] var the_form=document.the_form;[/tt]
The parent must the explicit, except grand-parent window is not needed.
 
theniteowl,

Thanks a ton for all of your help! I checked out Jemminger's form validation. Normally I'd totally use it, but at the moment I'm coding in coldfusion and his library and the cfform (coldfusion's form tag) don't play well together.

I was intrigued by his technique of using the html comments to hold the form validation information. I figure that's similar to your DIV tag solution. Do you know how his javascript could get access to the HTML comments without wrapping them in DIV tags? Are they part of the DOM?

Thanks! (Soon I may have to ditch this research and revert back to coldfusion's somewhat lame cfinput validation tags due to time constraints. However, I would really love to roll my own!)

- B
 
tsumi, When the OP's first post came in I was at work where I only have IE so I never did test the original code but instead posted an extract of my own code that I use at work.
When I got home I tested the new code in FF and found it did not work for me.

So you have tested the original code and say it works while clone45 says it does not work for him. I tested the bit of code I posted and found it not to work in FF and neither did the slightly altered version clone45 posted.

tsuji, can you test the first bit of code I posted above and see how it runs? There may be a difference between your FF installation and ours.


Stamp out, eliminate and abolish redundancy!
 
clone45, Jemminger's code sets up prototypes for the custom tags then uses commands to get elements of the document then uses previousSibling/nextSibling to move through the nodes of the element and tests them to see if they are a comment tag using nodeType.
There is too much about the process that I do not understand for me to implement these methods in my own code yet but I will be looking into it.

I had tried writing code to test the nodeType of elements in my own page and had some success in IE but it completely failed in FireFox and I assume that is where the prototypes in Jemminger's code come in handy but I do not know enough about them yet.
I want to learn the methods Jemminger used so that I understand them and can write my own code without just modifying Jemminger's to suit my own needs.

As far as my code example above goes, it only effectively differs in that the comments are inserted within the div tags (you could use span tags if you wanted also) because I could not get FF to recognize the comment tags directly. While there must be a way to do it this was quick and easy.

An alternative would be to create a single div tag with the validation info for all fields in the one tag instead of separate divs for each field. Use carriage returns to separate commands and something else to separate fields like this:
<div id="validator" name="validator"><!--
field1
A
B
C
---
field2
D
E
F
--></div>
Then you read in the innerHTML of the div and split it at the --- to leave you with an array with one element for each field listed. Then you loop through that array, split each element at the carriage returns and you end up with the name and all parameters for an individual field.

Here is how I setup my own code.
I wanted to create a set of validation functions that were more generic in application rather than writing functions for extremely specific types of validation. This means within my validation routine I need to apply more than one type of validation per field (sometimes).
A simple example would be validating that a field contains only alpha characters but is between 5 and 8 characters long. Rather than having a function that specific I just do an alpha test and then do a length test so my validator tag would include a command for each test. This way I can have a host of simple validation routines that can be combined on the fly to do much more complex validation and I do not end up with a HUGE library of very specific validation routines.
I also built in the ability to use logical and/or operators within my validation so I can say things like this field must be ((5 digits and whole positive integer) OR valid US phone number) so I can write very sophisticated methods of validation for any individual field.

I also have the ability to pass parameters from my validator tags so if I call for validation that a field has to be a certain number of characters or within a range I can pass those parameters along as well. One of my validation functions works by tying in the validation of another field as well so I set Field2 up with a validation saying "if field1 validates then field2 must validate otherwise do not test field2".
Then I have the ability to have masked sets of validation fields. Under some circumstances you may want certain fields to be validated/enforced but have which ones are affected change based on selections on the page. For instance if the checkbox "use same address for shipping" is checked then you do not enforce the filling out of a second set of address info for shipping so I use an event to set a mask flag value. During validation if a flag is set then my function tests to see if the individual field has a mask value and if it does it compares it against the current flag. If it has a value that does not match then the field is ignored, if they match it tests and if it did not have a mask value at all it is tested normally.
There are other options such as data transformation, methods of reporting errors to the client, etc but you get the idea. The code is really compact but is very powerful. Of course with the increase in abilities comes complexity in setting it up so I am working on ways to simplify selecting and entering the validation tags.


Stamp out, eliminate and abolish redundancy!
 
theniteowl, I will try do it tomorrow. I have not read in detail your last post, maybe there is no longer any need? (Your post is "so long" to read at a time I cannot sit down and do calmly! I am not complaining!)
 
tsuji, the last post was directed at clone45 and just relates to technical details of approaching the project and do not concern the above code.
I will test the original code in FireFox when I get home this evening. I had not done so before because by the time I got home we were already working with a different set of code.

Thanks.


Stamp out, eliminate and abolish redundancy!
 
clone45, I came up with new code that is working in both IE and FF.
No div is needed, just the comment tag. It does not matter where on the page the comment tag exists as it will loop through and find all of them. The first field is the name of the input field it is associated with and the rest are parameters. They do not have to be on individual lines, they could be separated by a character then you use the split command to separate out each part and call whatever validation routine it specifies against the named field.

I threw the trim command I use in there also just in case there are any leading or trailing spaces from the comment tags.

Code:
<html>
<head>

<script type="text/javascript">

function getValidationInfo(which)
{
  var el = which.elements[0];
  var commentchk = '';
  while (commentchk != null)
  {
    if (el.nextSibling) {
      el = el.nextSibling
      if (el.nodeType == 8)
        alert(trim(el.nodeValue)+'#');
    }
    else
    {
      commentchk = null;
    }
  }
}

function trim(value,parm) { //parm=l trims only left, parm=r trims only right. Any other value for parm trims both.
  return ((parm == 'l')?value.replace(/^\s+/,''):(parm == 'r')?value.replace(/\s+$/,''):value.replace(/^\s+|\s+$/g,''));
}
</SCRIPT>
</head>
<body>
<form name="formOne">
<input type="checkbox" name="fieldInfo" onclick="mytest()"><br>
<!-- fieldInfo1 
First
Second
Third -->
<input type="checkbox" name="fieldInfo2" onclick="mytest()"><br>
<!-- fieldInfo2
First
Second
Third -->
</form>
<form name="myFormId">
<textarea name="myTextArea">Some text</textarea>
</form>
<input type="button" value="Go" onclick="getValidationInfo(formOne)">
<center>
<form>
</body>
</html>

Stamp out, eliminate and abolish redundancy!
 
I don't know if I am too simplistic... I make this test page and it works as expected "cross-browser" (ie/moz/op). It is drafted from the idea that I read into and between the lines of the op's first post.
[tt]
<html>
<head>
<script language="javascript">
function checkit() {
var the_form=document.forms["formname"];
var form_element;
var validation_style;
for(var i=0; i < the_form.elements.length; i++)
{
form_element = the_form.elements;
validation_style = form_element.getAttribute("validation_style");
//alert(validation_style);
switch (validation_style) {
case "numeric":
alert("form_element:\t" + form_element.name + "\nvalidation_style:\t" + validation_style + "\nvalue:\t" + form_element.value + "\nvalidation:\t" + !isNaN(form_element.value));
break;
case "string": //normally not a good criteria, anything back would be a string, anyway...
alert("form_element:\t" + form_element.name + "\nvalidation_style:\t" + validation_style + "\nvalue:\t" + form_element.value + "\nvalidation:\t" + isNaN(form_element.value));
break;
default:
break;
}
}
}
//window.onload=checkit;
</script>
</head>
<body>
<form name="formname" onsubmit="checkit();return false">
x:&nbsp;<input name="x" type="text" value="something" /><br />
y:&nbsp;<input name="y" type="text" value="123" validation_style="numeric" /><br />
z:&nbsp;<input name="z" type="text" value="some string" validation_style="string" /><br />
p:&nbsp;<input name="p" type="text" value="some other string" validation_style="numeric" /><br />
q:&nbsp;<input name="q" type="text" value="456" validation_style="string" /><br />
<input type="submit" /><br />
</form>
</body>
</html>
[/tt]
As to the request from theniteowl for the followup scripts, I still have to figure out what is the significance. But, I am sure alert(validation_style) should all work okay once the the_form is correctly referenced! or I really miss something.
 
tsuji is right, once the original code had the object the_form correctly instantiated the code worked.
Thanks tsjui!

But, this was a great excuse for working up code to pull the info from within comment tags which I had wanted to do anyway.

Stamp out, eliminate and abolish redundancy!
 
Thanks theniteowl! I am glad you are happy for what reached sofar, that save me a lot of immediate reading. I am sure there are excellent ideas in your substantial/substantive posts here-above. I can then spare the reading at some more relaxing hours. Thanks!
 
Execellent! Thanks for all of the feedback. I've learned a lot on the subject!

- Bret
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top