Reputation: 1396
I have three coloured buttons. When I pick a button, I want it to be selected, and the other two to be deselected. red, blue and yellow are objects with the property isSelected set to true or false. I can select one button once, setting isSelected to true for that button. However, I can't seem to select a new button and deselect the current one.
(I know I can do this with jQuery easily... but I'm trying to learn how to use Javascript objects here...)
The code below doesn't run, it's the bits I think are relevant to the problem without the HTML and CSS. The app is on CodePen: http://codepen.io/isachenx/pen/LxEOOR
My idea is to set isSelected to true or false for each of the selectors. If isSelected is true, I add the class .selected to the html string, if it's false, the string does not include the class. I then re-render (at least that's what I think I'm doing) the string every time the li element is clicked...
//create constructor
function Selector(colour){
this.colour = colour
this.isSelected = false
}
//set method to select and deselect the list items
Selector.prototype.selectColour = function(){
this.isSelected = true
}
Selector.prototype.deselectColour = function(){
this.isSelected = false
}
//render the string for the list item to HTML
Selector.prototype.toHTML = function(){
let htmlString = ""
htmlString += '<li id="' + this.colour + '" class="' + this.colour
if (this.isSelected){
htmlString += ' selected'
}
htmlString += '"></li>'
return htmlString
}
//Constructor to render every list item to html
function Controls(){
this.selectors = []
}
Controls.prototype.add = function(selector){
this.selectors.push(selector)
}
Controls.prototype.renderInElement = function(list){
list.innerHTML = ''
for (let i=0; i<this.selectors.length; i++){
list.innerHTML += this.selectors[i].toHTML()
}
}
let controls = new Controls
let red = new Selector('red')
let blue = new Selector('blue')
let yellow = new Selector('yellow')
controls.add(red)
controls.add(blue)
controls.add(yellow)
let controlElement = document.getElementById('controlButtons')
controls.renderInElement(controlElement)
let redButton = document.getElementById('red')
redButton.onclick = function(){
red.selectColour()
blue.deselectColour()
yellow.deselectColour()
controls.renderInElement(controlElement)
}
let blueButton = document.getElementById('blue')
blueButton.onclick = function(){
blue.selectColour()
red.deselectColour()
yellow.deselectColour()
controls.renderInElement(controlElement)
}
let yellowButton = document.getElementById('yellow')
yellowButton.onclick = function(){
yellow.selectColour()
red.deselectColour()
blue.deselectColour()
controls.renderInElement(controlElement)
}
Upvotes: 0
Views: 104
Reputation: 2922
By your code, a second click on either button does not work.
The reason is that onclick
is set only for the first time.
Your toHTML
function clears the existing buttons (line 33: list.innerHTML = ''
), as a result clears their onclick
events. You have to set them again inside toHTML
.
Like so:
Selector.prototype.toHTML = function(){
// set the on click function to the desired color
let onclickStr = 'setOnClick(\'' + this.colour + '\')';
let htmlString = ""
htmlString += '<li id="' + this.colour + '" class="' + this.colour
if (this.isSelected){
htmlString += ' selected'
}
// Note the following change
htmlString += '" onclick="' + onclickStr + '"></li>'
return htmlString
}
Then, wrap your xxxbutton.onclick
functions with:
function setOnClick(color) {
let redButton = document.getElementById('red')
let blueButton = document.getElementById('blue')
let yellowButton = document.getElementById('yellow')
if(color==='red'){
red.selectColour()
blue.deselectColour()
yellow.deselectColour()
}else if(color==='blue'){
blue.selectColour()
red.deselectColour()
yellow.deselectColour()
}else{
yellow.selectColour()
red.deselectColour()
blue.deselectColour()
}
controls.renderInElement(controlElement)
}
Upvotes: 1
Reputation: 411
Setting isSelected
to true
or false
doesn't change the class on the DOM element. To add/remove a class:
var colourObj = document.querySelector(colour);
colourObj.classList.add('selected');
//or to remove a class
colourObj.classList.remove('selected');
Upvotes: 1