Rabbi Musayev
Rabbi Musayev

Reputation: 322

How to change input background color dynamically?

I have a custom Time-picker like this.

I want to change input background color when I click It and If I click another one the previous one bg should be white. But when I click second or etc previous one don't back to normal bg.

  const [hours, setHours] = useState('09')

  const onClickHours = (e) => {
    e.preventDefault();
    setHours(e.target.value)
  }

  const onClickFullTime = (e) => {
    e.preventDefault();
    setFullTime(e.target.value)
    getTime(e.target.value);
    changeColor(e);
  }

  const changeColor = (e) => {
    
      let currentColor = e.target.attributes['data-color'].value;
      let newColor = currentColor === "#fff" ? "#40a9ff" : "#fff";
      e.target.style.backgroundColor = newColor;
      e.target.setAttribute('data-color' , newColor);
  }


  

  const getTime= (fullTime) => {
    onSelectTime(fullTime)
  }

  const hoursArray = [];
  for (let i = 9; i < 22; i++) {
    if (i < 10) {
      i = '0' + i;
    }
    hoursArray.push(
      <input key={i}  onClick={onClickHours} value={i} readOnly />
    )
  }

  const fullTimeArray = [];
  for(let j = 0; j < 60; j = j + 5){
    fullTimeArray.push(hours + ":" + (j< 10 ? '0' + j : j))
  }


              <div className="timepicker">
                <div className="hours">
                  {hoursArray}
                </div>
                <div className="full-time">
                  {
                  fullTimeArray.map((time, index) => (
                    <input name="fullTime" data-color="#fff" key= 
                    {index} onClick={onClickFullTime} value={time} 
                    readOnly/>
                    ))}
                </div>
             </div>

after click to input

Upvotes: 0

Views: 1079

Answers (2)

Codeburned
Codeburned

Reputation: 71

If only one should be set at a time just give each button a dynamic html id attribute (just timebutton + i value or something unique) and store that in a variable. When a button is clicked set the stored id (if it exists) to have no background and also set the clicked button to be the stored id, setting its background.

You should only need to keep track of the buttons that are highlighted and update them.

EDIT: I will elaborate further, client side Javascript is needed for the solution I mentioned above example of node.js client side.

Here is an example I have made for simple client side js to highlight a clicked button storing the id and resetting it when clicking another.

var buttonNumId = ""; // variable for saving the currently highlighted element Id
function myFunction(clickedElement) {
  // unhighlight the current element
  if (buttonNumId !== "") document.getElementById(buttonNumId).style.background = "white";
  // set the currently clicked element and change its color
  buttonNumId = clickedElement.id;
  clickedElement.style.background = "red";
  // update the textbox for demo purposes
  document.getElementById("demo").innerHTML = "Button Id: " + buttonNumId;
}
<!DOCTYPE html>
<html>

<body>

  <h1>Highlight on click</h1>

  <button id="Button1" style="background-color: white;" onclick="myFunction(this)">Click me 1</button>
  <button id="Button2" style="background-color: white;" onclick="myFunction(this)">Click me 2</button>
  <button id="Button3" style="background-color: white;" onclick="myFunction(this)">Click me 3</button>
  <button id="Button4" style="background-color: white;" onclick="myFunction(this)">Click me 4</button>

  <p id="demo"></p>

</body>

</html>

Upvotes: 0

MB_
MB_

Reputation: 1747

Try this :

import React, { useState, useEffect } from 'react';
import './style.css';

export default function App() {
  const [hours, setHours] = useState('09');
  const [currentInput, setCurrentInput] = useState('');

  const fullTimeArray = [];
  for (let j = 0; j < 60; j = j + 5) {
    fullTimeArray.push(hours + ':' + (j < 10 ? '0' + j : j));
  }

  const onClickFullTime = (e) => {
    e.preventDefault();
    setCurrentInput(e.target.value);
  };

  useEffect(() => {
    changeColor(currentInput);
  }, [currentInput]);

  const changeColor = (current) => {
    const inputElem = document.querySelectorAll("input[name='fullTime']");

    inputElem.forEach((elem) => {
      if (elem.value === current) {
        elem.style.backgroundColor = '#40a9ff';
      } else {
        elem.style.backgroundColor = '#fff';
      }
    });
  };

  return (
    <div className="timepicker">
      <div className="full-time">
        {fullTimeArray.map((time, index) => (
          <input
            name="fullTime"
            key={index}
            onClick={onClickFullTime}
            value={time}
            readOnly
          />
        ))}
      </div>
    </div>
  );
}
  • (No need data-color)
  • Create a state (currentInput in my example) where you store the current value of the clicked input (see onClickFullTime function)
  • When the value of currentInput changes, useEffect passes it to the changeColor function

Demo : Stackblitz

Upvotes: 1

Related Questions