1

I am trying to make a button with javascript and css that when clicked, will change the class of the clicked element to make it obvious to the user that it is the currently selected button.

There are four buttons on the page. I haven't implemented the 4th one yet. The brute force code (show after) is working.

function selected_button(opCode){
    switch(opCode){
        case 1:
            document.getElementById('button1').className += "selected";
            document.getElementById('button2').className = document.getElementById("button2").className.replace( /(?:^|\s)selected(?!\S)/ , '' );
            document.getElementById('button3').className = document.getElementById("button3").className.replace( /(?:^|\s)selected(?!\S)/ , '' );
            document.getElementById('button4').className = document.getElementById("button4").className.replace( /(?:^|\s)selected(?!\S)/ , '' );
            break;
        case 2: //Really similar to case 1 but shifted numbers around
            document.getElementById('button2').className += "selected";
            document.getElementById('button1').className = document.getElementById("button1").className.replace( /(?:^|\s)selected(?!\S)/ , '' );
            document.getElementById('button3').className = document.getElementById("button3").className.replace( /(?:^|\s)selected(?!\S)/ , '' );
            document.getElementById('button4').className = document.getElementById("button4").className.replace( /(?:^|\s)selected(?!\S)/ , '' );
            break;
        default: //really similar to case 1 but shifted numbers around
            document.getElementById('button3').className += "selected";
            document.getElementById('button1').className = document.getElementById("button1").className.replace( /(?:^|\s)selected(?!\S)/ , '' );
            document.getElementById('button2').className = document.getElementById("button2").className.replace( /(?:^|\s)selected(?!\S)/ , '' );
            document.getElementById('button4').className = document.getElementById("button3").className.replace( /(?:^|\s)selected(?!\S)/ , '' );
    }
}

I want to make a more general function of this so what I came up with is the following:

function general_selected(selected_elem_num, num_elem, elem_name, desired_class){
    var i = 0;
    for( i = 0; i < num_elem + 1; i++){ //dehighlights all options
             document.getElementById(elem_name + i.toString()).className = 
              document.getElementById(elem_name + i.toString()).className.replace
               ( /(?:^|\s) *should be a parameter here* (?!\S)/ , '' );
                /* code wrapped for readability - above is all one statement */
    }
    //highlights selected option
    document.getElementById(elem_name + selected_elem_num).className 
              += desired_class;
}

The following two function calls should be practically equivalent:

selected_button(1);
general_selected( 1, 4, 'button', 'selected');

2 problems I'm having though:

1) I don't know how to insert desired class into the regex as a parameter.

2) The really long method in the for loop is causing an error. The error seems to be persistent because I get the same error even when I replace the method in the for loop with the following:

document.getElementByID(elem_name + i.toString()).className = desired_class;

Code loosely based on this thread: Change an element's class with JavaScript

Community
  • 1
  • 1
Zigu
  • 1,625
  • 4
  • 23
  • 33

2 Answers2

0

Add event listener to the root node and track actual target.

document.addEventListener('click', function(event){
     var old = document.querySelector(".selected");
     old.className = old.className.replace( /(?:^|\s)selected(?!\S)/ , '' );
     event.target.className += " selected";
}, false);
kirilloid
  • 14,011
  • 6
  • 38
  • 52
0
  1. Create the regex dynamically using the new Regex(string)

reg = new Regex('?:^|\s)'+desired_class+'(?!\S)');

  1. Your loop starts at 0, but your button names starts at 1

for(i = 1; i < num_elements + 1 .....

The rest, as they say, is left as an exercise to the reader

Kristoffer Sall-Storgaard
  • 10,576
  • 5
  • 36
  • 46