-2

I have a table that typically looks like this on the screen: enter image description here

The multiple rooms are displayed by using a foreach loop.

Now I need to disable all the second dropdown boxes when a value has been selected in one of the first ones, or vice versa.

Typical code for one of the dropdown boxes is

<select onchange="std()" class="numrooms" name="numrooms[4]">
<option value="" selected>Select</option>
<option value="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1</option>
<option value="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2</option>
</select>

I am using the following javascript:

function std() {
d = document.getElementsByClassNames("numrooms").value;
if (d>0) {
    document.getElementsByClassNames('numrooms_nr').disabled = true;
}else{
    document.getElementsByClassNames('numrooms_nr').disabled = false;
}
}
function nr() {
e = document.getElementsByClassNames("numrooms_nr").value;
if (e>0) {
    document.getElementsByClassNames('numrooms').disabled = true;
}else{
    document.getElementsByClassNames('numrooms').disabled = false;
}
}

but it doesn't work.

I have tried changing the classes to IDs and then using GetElementById() in the script and that does work, but of course it only works on one pair of dropdowns. I thought going to classes and using Get ElementsBy ClassName() would do the trick, but apparently not.

Am I missing something obvious? Or doing it completely wrong?

EDIT As everyone pointed out, I wrote "getElementsByClass" in the question when it should have been "getElementsByClassName". However that was a mistake when I wrote the question and not in my actual code. I've corrected it here now.

EDIT2 I'm getting there, but not quite fully sorted yet. I've adopted @Notulysses suggestion so for testing purpose my script is

function std() {
d = document.getElementsByClassName('numrooms')[1].value;
if (d>0) {
var n = document.getElementsByClassName('numrooms_nr')
for(var i=0;i<n.length;i++){
   n[i].disabled = true;
}
}else{
var n = document.getElementsByClassName('numrooms_nr')
for(var i=0;i<n.length;i++){
   n[i].disabled = false;
}
}
}
function nr() {
e = document.getElementsByClassName('numrooms_nr')[0].value;
if (e>0) {
var n = document.getElementsByClassName('numrooms')
for(var i=0;i<n.length;i++){
   n[i].disabled = true;
}
}else{
var n = document.getElementsByClassName('numrooms')
for(var i=0;i<n.length;i++){
   n[i].disabled = false;
}
}
}

function(std) now disables all of the second dropdown boxes when the first dropdown in the second room is selected (because I have set it to 1). Similarly function(nr) disables all of the first dropdown boxes (because I have set it to [0]). But how do I disable all the second dropdowns when any of the first dropdowns is selected?

Community
  • 1
  • 1
TrapezeArtist
  • 777
  • 1
  • 13
  • 38
  • 1
    getElementsByClass returns an array, you can't acces value directly, yo need to use for exmaple `d = document.getElementsByClass("numrooms")[0].value;` – juvian May 01 '14 at 17:14

4 Answers4

3

You are using getElementsByClass (it doesn't exist) and changing property for the whole collection (not valid, you should iterate through Node list to change attribute's value). You should do something like this :

var n = document.getElementsByClassName('numrooms')
for(var i=0;i<n.length;i++){
   n[i].disabled = true;
}
potashin
  • 44,205
  • 11
  • 83
  • 107
2

Its GetElementsByClassName not GetElementsByClass and it returns you NodeList of nodes so if you want to change any property you need to use indexing, i.e, looping:

document.getElementsByClassName('numrooms_nr')[0].disabled = true;

and here is your complete code:

var d = document.getElementsByClassNames("numrooms");
for(var i=d.length-1;i>=0; i--){
  if(n[i].value > 0){
    n[i].disabled = true;
  }
  else{
    n[i].disabled = false;
  }
}
Zaheer Ahmed
  • 28,160
  • 11
  • 74
  • 110
1

You are using it wrong. It's not getElementsByClass , it is getElementsByClassName. And it returns a HTMLCollection of found elements. To have an access to any element you should use indexing.

document.getElementsByClassName('someclass')[0] <- index

See the link for more details -> Link

W.D.
  • 1,033
  • 1
  • 7
  • 12
  • Explain the downvote. – W.D. May 01 '14 at 18:01
  • I've read and so what. I just pointed out that `getElementsByClass` method doesn't exist and the OP should use `getElementsByClassName`. How is your comment related with my answer being wrong? – W.D. May 01 '14 at 18:14
  • Because you say `getElementsByClassName()` returns an array, but it doesn't. – Teemu May 01 '14 at 18:15
  • NOT `getElementsByTagName()` , but `getElementsByClassName()` and it returns a NodeList in this case you may say an array, which can be looped through. – W.D. May 01 '14 at 18:17
  • You may not call it array, because it has not those methods arrays have. Is it that hard to just correct the answer, and get rid of the downvote? – Teemu May 01 '14 at 18:18
  • Basically its an array that one can loop through. Although, it's not an array (and in this case I meant a list and I'll edit my answer to clarify that), but it's an array-like object and it’s an array of some sorts. I also don't get why downvoting only my post, when the above post misses as you say something obvious as well?! – W.D. May 01 '14 at 18:27
  • Your post definitely is not the only downvoted post here. Actually also Notulysses' answer is incorrect. [getElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName) returns a [HTMLCollection](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection) which is slightly different from [NodeList](https://developer.mozilla.org/en-US/docs/Web/API/NodeList), hence it seems the dottoro article is also deprecated. – Teemu May 01 '14 at 18:38
  • OK. And which documentation is correct http://help.dottoro.com/ljpxmhgp.php or https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection ? – W.D. May 01 '14 at 18:40
  • You can make a quick-test with `namedItem(name)`, it's not supported by NodeList, but works in HTMLCollection... – Teemu May 01 '14 at 18:42
  • Also in Mozilla's documentation it says that `getElementsByClassName` returns an `array` of all child elements https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName – W.D. May 01 '14 at 18:42
  • @Teemu, Very interesting. May I ask where do you work ? :) and this is from google's cache http://webcache.googleusercontent.com/search?q=cache:OU7teV8BqzwJ:https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName+&cd=1&hl=hy&ct=clnk&gl=am&client=firefox-a - I'll keep the page ;) – W.D. May 01 '14 at 18:54
  • Haha, I'm just an engineer. We're all learning here, even MDN ; ). Now +1 for a correct answer. – Teemu May 01 '14 at 19:01
  • 1
    Indeed, that's why we are here. Good talking to you ;) – W.D. May 01 '14 at 19:10
-1

getElementsByClassName and getElementsByTagName do not return a single element, like get ElementById. Rather, they return an array containing all the elements with that class. This has tripped up many Javascripters over time. Also note that getElementsByClassName won't work in early IE versions (surprise surprise!)

As such, you are missing the bit with the [0] or [1] or the [2] etc. after getElementsByClassName is written, for example:

document.getElementsByClassName("numrooms")[0]

will refer to the first of the bunch with that class name.

tomysshadow
  • 870
  • 1
  • 8
  • 23