6
votes

Other than the fact that my brief research tells me the latter will return a collection rather than a a single element with the ID passed.

Consider the following code:

function validateAllFields()
{
var clientid = document.getElementById("clientid");
var programs = document.getElementById("programs");
var startmonth = document.getElementById("startmonth");
var startday = document.getElementById("startday");
var startyear = document.getElementById("startyear");
var completed = document.getElementsByName("completed");
var goals = document.getElementsByName("goals");
var errors = document.getElementById("errorMsg");
errors.innerHTML = "";

if(isNumeric(clientid, errors, "Please enter a valid client ID")){
    if(madeSelection(programs, errors, "Please select a program from the drop-down list")){
        if(madeSelection(startmonth, errors, "Please enter a month for the start date")){
            if(madeSelection(startday, errors, "Please enter a day for the start date")){
                if(madeSelection(startyear, errors, "Please enter a year for the start date")){
                    if(checked(completed, errors, "Please choose an option that indicate whether the client has completed the program")){
                        if(checked(goals, errors, "Please choose an option that indicate whether the client has met his/her goals.")){
                            window.alert("GOT IN TO  RETURN TRUE");
                            return true;
                        }
                    }
                }
            }
        }
    }
}
return false;
}
</script>

The above code works perfectly after placing it in the onsubmit handler of the form. However, earlier, for the elements (programs, startmonth, startday, startyear) I was using getElementsByName(), the following happened:

  1. The code seems to get to the second line of the if blocks "if(madeSelection(programs...." and it displayed the error msg via innerHTML for a brief second and
  2. Proceeded to submit the form AS IF the JS had indeed returned true. As you can tell, there is a popup alert right before returning true and the popup DID NOT show up at all.
  3. Bad data was submitted to my test database because the form had not been validated. (yet to write server-side validation with this form, but I will).

please assume the elements programs, startmonth, startday, and startyear are drop-down lists with the same id and name attributes.

Also, the madeSelection function is given as:

function madeSelection(element, error, msg) {
if (element[0].value == "none" || element[0].valueOf == "none" || element[0].value == "") {
    error.innerHTML = msg;
    element.focus();
    return false;
} else {
    return true;
}
}

My code does work right now after I changed those elements to be using getElementById(), I was just wondering why getElementsByName presented such behavior.

6
do you mean getElementsByTagName()?kinakuta
Your code is a mess with all that indentation. Consider returning false after each detected error and returning true in the end if there were no errors.Zecc
Talk about messy code... This is where I LOL when people says that PHP is messy... nice comment ZeccSamuel Ramzan

6 Answers

7
votes

The GetElementsByName method returns an array, and when you tried to call element.focus() you got an error because there is no focus method on an array. When you get an error in the event handler it won't prevent the form from posting.

If you use GetElementById you should use element to access the element, and if you use GetElementsByName you should use element[0].

10
votes
<input type="text" name="foo" id="bar">
                   ^^^^       ^^

getElementsByName gets elements by their name, getElementById gets the element by its id. There may be many elements on a page with the same name (hence getElementsByName always returns a list of elements), but there is (must) only be one element with a given id (therefore getElementById only returns a single element).

3
votes

The name attribute is not designed to be unique, while the id attribute is.

<div name="nonUnique" />
<div id="unique" />
3
votes

To expand a little on the answers already provided, the name attribute was provided early in the days of the browser DOM, to allow the contents of elements in forms to be submitted with reference to that name attribute, so that parameters could be passed to a CGI script at the server side. This dates from before the more modern ability to reference DOM elements for manipulation of such things as styles by JavaScript.

When the DOM was expanded to allow said modern manipulations, the id attribute was added, so that individual elements could be manipulated at will. When you want to perform DOM manipulations, you select elements to be manipulated either via the id attribute, if you're only interested in manipulating a single DOM element, or via the class attribute (suitably set by yourself), if you want to manipulate several elements together in the same manner. In this latter case, you can set the class attribute to multiple values (name strings separated by spaces), so that you can, for example, designate elements to belong to more than one class, and perform manipulations accordingly. You can mix and match id and class attributes practically at will, provided you exercise some care to avoid name clashes.

So, for example, you could have five buttons on your web page, all set to:

class="Set1"

and change the style of all those buttons, first by using a statement such as:

myButtons = document.getElementsByClassName("Set1");

to obtain an array of Element objects corresponding to your buttons, then running the following loop:

for (i=0; i<myButtons.length; i++)
    myButtons[i].style.color="#FF0000";

to change the colour of the text to red. One of those buttons could additionally have an id attribute set to "Special", and you could then do something such as:

ref = document.getElementById("Special");
ref.style.backgroundColor = "#FFFF00";

to set the background colour of that one button in the set to yellow, to signal that it's intended for a special function within the set.

In short, use the name attribute for form submissions, and the id and class attributes for referring to elements you intend to perform DOM manipulations upon, or attach event handlers to, etc.

2
votes

In order for the form to not be submitted, return false needs to be returned (you said you used the onsubmit handler)

in the second line of your code, because a selection is indeed returned by getElementsByName (it would work with .getElementsByName("test")[0] ) a js error is thrown. The rest of the code is not executed, therefore nothing is returned and the form by-passes the rest of the validation completely.

2
votes

The getElementById method can access only one element at a time, and that is the element with the ID that you specified. The getElementsByName method is different. It collects an array of elements that have the name that you specified. You access the individual elements using an index which starts at 0.

getElementById

enter image description here

  • It will get only one element for you.
  • That element bears the ID that you specified inside the parentheses of getElementById().

getElementsByName

enter image description here

  • It will get a collection of elements whose names are all the same.
  • Each element is indexed with a number starting from 0 just like an array
  • You specify which element you wish to access by putting its index number into the square brackets in getElementsByName's syntax below.

function test() {
  var str = document.getElementById("a").value;
  console.log(str);

  var str1 = document.getElementsByName("a")[0].value;
  console.log(str1);
  var str2 = document.getElementsByName("a")[1].value;
  console.log(str2);
}
<input type="text" id="a" value="aValue" />
<br>
<br>
<input type="text" name="a" value="bValue" />
<br>
<br>
<input type="text" name="a" value="cValue" />
<br>
<br>
<button onclick="test()">Click Here</button>