4

I have the following line of code:

document.getElementById("question_*").setAttribute("disabled", "false");

I want to use a form of wildcard for the element ID. The script is run and used by lots of different buttons, they all have ID's of question_something - is it possible to make this setAttribute to make the button enabled for various ID's?

<button id="question_1a" onClick="nextQuestion(this.id)" disabled>Next question</button>

EDIT:

I've switched to a classname as suggested. Buttons now are:

<button id="question_1a" class="nextButton" disabled>Next question</button>

I've added the following line to make this not disabled:

var elems = document.getElementsByClassName('nextButton').setAttribute("disabled", "false");

But I get: Uncaught TypeError: Object # has no method 'setAttribute'

Francesca
  • 26,842
  • 28
  • 90
  • 153

5 Answers5

17

You can't use wildcards with document.getElementById(), you can, however, with document.querySelectorAll():

var elems = document.querySelectorAll('button[id^="question_"]');

This, of course, requires a relatively up to date browser; on the other hand using a class-name (for example question) to associate those elements would allow you to use:

var elems = document.getElementsByClassName('question');

Or:

var elems = document.querySelectorAll('button.question');

I tried doing this: var elems = document.getElementsByClassName('nextButton').setAttribute("disabled", "false"); - but I get: Uncaught TypeError: Object # has no method 'setAttribute'

That's because you can't modify the properties of a NodeList all at once, you can, however, use a for (){...} loop, or similar to do so:

Using for(){...}:

var elems = document.getElementsByClassName('question');
for (var i = 0, len = elems.length; i < len; i++){
    elems[i].disabled = false; // to make them all enabled
}

JS Fiddle demo.

Or using forEach (up to date browsers):

var elems = document.getElementsByClassName('question');
[].forEach.call(elems, function(a){
    a.disabled = false; // will make all elements enabled
});

JS Fiddle demo.

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • Thanks, I tried doing this: var elems = document.getElementsByClassName('nextButton').setAttribute("disabled", "false"); - but I get: Uncaught TypeError: Object # has no method 'setAttribute' – Francesca Mar 16 '14 at 20:57
  • 1
    See the updates to the answer (using the `for (){...}` loop is easier, and more compatible but, sadly, less sexy...) – David Thomas Mar 16 '14 at 21:04
3

That's precisely what classes are for:

<button class="question" id="question_1a" onClick="nextQuestion(this.id)" disabled>Next question</button>

And

var elems = document.getElementsByClassName("question");
for(var z=0;z<elems.length; z++){
   elems[z].setAttribute("disabled", "false")
}
JCOC611
  • 19,111
  • 14
  • 69
  • 90
2

Another possibility, if querySelectorAll or getElementsByClassName (could be shimmed in a similar manner) wasn't available and you wanted to match multiple IDs.

HTML

<button>Question</button>
<button id="question_1a">Question</button>
<button id="question_1b">Question</button>
<button id="question_1c">Question</button>
<button id="question_1d">Question</button>
<button id="question_2a">Question</button>

Javascript

function getElementsById(regex) {
    var tags = document.getElementsByTagName('*'),
        tagsLength = tags.length,
        matches = [],
        index,
        tag;

    for (index = 0; index < tagsLength; index += 1) {
        tag = tags[index];
        if (regex.test(tag.id)) {
            matches.push(tag);
        }
    }

    return matches;
}

console.log(getElementsById(/^question_1[a-z]?$/));

Output

[button#question_1a, button#question_1b, button#question_1c, button#question_1d]

On jsFiddle

Then you can iterate this array and set the attributes

And the getElementsByclassName shim

function getElementsByClassName(node, className) {
    var array = [],
        regex = new RegExp("(^| )" + className + "( |$)"),
        elements = node.getElementsByTagName("*"),
        length = elements.length,
        i = 0,
        element;

    while (i < length) {
        element = elements[i];
        if (regex.test(element.className)) {
            array.push(element);
        }

        i += 1;
    }

    return array;
}
Xotic750
  • 22,914
  • 8
  • 57
  • 79
0

Nope wildcard isn't supported. But to solve this problem you can use jQuery to do the same.

P. S. I will try to post code once I am back at desk

Update agree David Thomas & Beemo's code hint that should solve your problem

Baljeetsingh Sucharia
  • 1,990
  • 1
  • 19
  • 37
-1

You can use JQuery $("[id^='question_']") selector to get all elements with an id starting by question_

Beemo
  • 17
  • 1
  • 5