CrystalGarnet
CrystalGarnet

Reputation: 119

Color picker ignoring set value

I'm unable to set the value of my color picker using the syntax:

color_picker.value = button_color

I created this snippet to show my attempt, but I also can't seem to figure out why in this snippet, button_color is returning an empty string instead of the background color of the button.

<button id="button_1">Button</button>
<input type="color" id="color_picker"/>
#button_1 {
  background-color: blue;
  width: 400px;
  height: 200px;
  font-size: 30px;
}
const button_1 = document.getElementById('button_1')
const color_picker = document.getElementById('color_picker')

let button_color = button_1.style.backgroundColor
console.log('button_color is ', button_color)
color_picker.value = button_color
console.log('showColorPickerButtons color picker value is ', color_picker.value)
color_picker.oninput = () => {
        let color = color_picker.value
        changeButtonsColor(color)
    }
    
function changeButtonsColor(color) {
    console.log(color)
    let buttons = document.getElementsByClassName('button')
    for (var i = 0; i < buttons.length; i++) {
        buttons[i].style.backgroundColor = color
    }
}

Upvotes: 0

Views: 335

Answers (2)

Kinglish
Kinglish

Reputation: 23654

This turned out to be more complex than I thought. I wasn't able to extract the background color at page load. So, I went with window.getComputedStyle - which returned an RGB value. The color picker only accepts full 7-character hex values, so I used a helper function to convert the rgb to hex and walla, it works!

The event listener has a single function argument event, which I am referring to as e below. The caller of the listener (the color picker) is the target, so getting the value is e.target.value. We then just apply that to the button's background-color style.

const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`
window.addEventListener('DOMContentLoaded', () => {
  let button = document.querySelector('#button_1');
  let bg = window.getComputedStyle(button, null).getPropertyValue('background-color');
  document.querySelector('#color_picker').value = rgba2hex(bg)
  document.querySelector('#color_picker').addEventListener('input', e => {
    button.style.backgroundColor = e.target.value
  })
})
#button_1 {
  background-color: #ff0000;
  width: 400px;
  height: 200px;
  font-size: 30px;
}
<button id="button_1">Button</button>
<input type="color" id="color_picker" value="" />

Upvotes: 3

nip
nip

Reputation: 1697

backgroundColor is an empty string because you are acessing the style prop of the element.

As you can see here the style prop only returns values that are defined inline.

If you want to get the button's background color to use on the color input, you need to use getComputedStyle

Replace by

let button_color = getComputedStyle(button_1, null).getPropertyValue("background-color")

Then, since the input won't accept an rgb value you'll need to convert it to hex.

const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`

Full code for initial color in input using button's background color:

const button_1 = document.getElementById('button_1')
console.log("b", button_1)
const color_picker = document.getElementById('color_picker')

let button_color = getComputedStyle(button_1, null).getPropertyValue("background-color")
console.log('button_color is ', button_color)
const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`
const hexColor = rgba2hex(button_color);
color_picker.value = hexColor;
console.log('showColorPickerButtons color picker value is ', color_picker.value)
color_picker.oninput = () => {
        let color = color_picker.value
        changeButtonsColor(color)
    }
    
function changeButtonsColor(color) {
    console.log(color)
    let buttons = document.getElementsByClassName('button')
    for (var i = 0; i < buttons.length; i++) {
        buttons[i].style.backgroundColor = color
    }
}
#button_1 {
  background-color: blue;
  width: 400px;
  height: 200px;
  font-size: 30px;
}
<button id="button_1">Button</button>
<input type="color" id="color_picker"/>

Upvotes: 1

Related Questions