ReactJS: Need to change card styling using onClick function

react change class onclick without state
react onclick change state
react change icon on click
react button onclick link
highlight button onclick react
react onclick list item
react change style based on state
react mouse events

I know this will need a refactor later to separate things out into their own components, but I'm up against a time crunch at the moment and need to wire this up as is. I used array.map() to create card elements from a JSON object I'm using for testing purposes. I'm attempting to use an onClick function on a card <div> to save some identifiable information like 'offerid' into the component state and then check if the id in state matches the current card. If it matches, I want to add cardActive as the className on the div so that only that specific card changes color. I'm not sure how to do this. As it is now, all card stylings are updated no matter which card is selected. My React component and corresponding CSS are listed below. Any help would be hugely appreciated

React

import React, { Component } from 'react';
import Grid from '@material-ui/core/Grid';
import './Button.css';

class UsersList extends Component {
    constructor(){
        super();

        this.state = {
            cardActive: false,

            customers:
            [
                {
                    "CustomerId": "1",
                    "LastName": "Doe",
                    "FirstName": "Jane",
                    "Address": {
                      "Address1": "1811 Chestnut Street",
                      "Address2": null,
                      "City": "Philadelphia",
                      "State": "Pennsylvania",
                      "Zip": "19103"
                    },
                    "Offers": [
                      {
                        "OfferId": "Offer1",
                        "Name": "Offer 1",
                        "Products": [
                          {
                            "ProductId": 1,
                            "ProductName": "Stuff"
                          },
                          {
                            "ProductId": 2,
                            "ProductName": "More stuff"
                          }
                        ],
                        "Price": "$1"
                      },
                      {
                        "OfferId": "Offer2",
                        "Name": "Offer 2",
                        "Price": "$2",
                        "Products": [
                          {
                            "ProductId": 3,
                            "ProductName": "A lot of stuff"
                          },
                          {
                            "ProductId": 4,
                            "ProductName": "And then there was stuff"
                          }
                        ]
                      },
                      {
                        "OfferId": "Offer3",
                        "Name": "Offer 3",
                        "Price": "$3",
                        "Products": [
                          {
                            "ProductId": 5,
                            "ProductName": "Good grief would you look at all this stuff"
                          },
                          {
                            "ProductId": 5,
                            "ProductName": "What a great deal for stuff"
                          }
                        ]
                      }
                    ]
                  }
              ]
        }
    }

    selectCard(){
        this.setState({ cardActive: !this.state.cardActive })
    }


    render (){
        let card_class = this.state.cardActive ? "cardActive" : "card";
        return (
            <div>
                {this.state.customers.map((customer, index) => {
                    return  <div key={index + customer.CustomerId}>
                                <h2>Customer</h2>
                                <hr></hr>
                                    <h3 >Name: {customer.LastName}, {customer.FirstName}</h3>
                                    <h3 >Customer ID: {customer.CustomerId}</h3>
                                    <h3 >
                                    Address: 
                                    <br></br>
                                    {customer.Address.Address1}
                                    <br></br>
                                    {customer.Address.City}, {customer.Address.State} {customer.Address.Zip} 
                                    </h3>
                                    <br></br>
                                    <h2>Available Offers</h2>
                                    <Grid container spacing={24} justify="center"> 
                                    {customer.Offers.map((Offer,index) => {
                                        return <div key={index + Offer.OfferId} onClick={this.selectCard.bind(this)}>
                                                <Grid item xs={12}>
                                                <div className="card" class={card_class}>
                                                    <div className="container">
                                                        <h5><b>{Offer.OfferId}</b></h5> 
                                                        <h2>{Offer.Name}</h2>
                                                        {Offer.Products.map((Product, index) => {
                                                            return <div key={index + Product.ProductId}>
                                                                    <p>+ {Product.ProductName}</p>
                                                                  </div>

                                                        })}
                                                        <h3>{Offer.Price}</h3> 
                                                    </div>
                                                </div>
                                                </Grid>
                                            </div>
                                    })}

                                    </Grid>

                            </div>

                })}
                <button className="navbuttonSelected">Submit</button>
            </div>
        )
    }
}

export default UsersList

CSS

  .card {
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
    transition: 0.3s;
    border-radius: 5px; /* 5px rounded corners */
    margin-left: 70px;
    margin-right: 70px;
    margin-bottom: 5%;
    cursor: pointer;
  }

  .cardActive {
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
    transition: 0.01s;
    border-radius: 5px; /* 5px rounded corners */
    margin-left: 70px;
    margin-right: 70px;
    margin-bottom: 5%;
    background: #0c72c5 !important;
    color: white !important;
    cursor: pointer;
  }

  .cardActive:hover {
    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
  }

  .card:hover {
    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
  }

Set id of selected card:

selectCard(offerId) {   
  this.setState({ cardActive: offerId });
}

change how onClick is called and apply specific class when Offer.OfferId === this.state.cardActive

return (  
 <div
   key={index + Offer.OfferId}
   onClick={() => this.selectCard(Offer.OfferId)}
 >
   <Grid item xs={12}>
     <div
      className={Offer.OfferId === this.state.cardActive ? "cardActive" : "card"}>

Working example: https://codesandbox.io/s/mjryv01528

React JS, React has the same events as HTML: click, change, mouseover etc. render() { return ( <button onClick={this.shoot}>Take the shot! If you must use regular functions instead of arrow functions you have to bind this to the component instance� Example: Updating the State in an onClick Event Handler. A very common use of an inline function inside of an onClick event handler in React is to update a component’s state. You’ll do this when you want to update the state with the button’s value, or using a value from a loop, for example.

React Events, Change background Color Button with onClick in reactjs onClick in reactjs. This is a template about changing the background color of a button in reactjs. A Pen by style.css .container {. display: flex;. justify-content: center;. align-items. } .buttonTrue { I want to change the background color of the button which is clicked. For example, I make use of notifications in React JS using Noty, and the styling should be able to handle plugins too. Some of my goals in answering the question included covering these: Global

...
constructor(){
    super();

    this.state = {
        cardActive: "",

        customers: [...]
    }
    this.selectCard = this.selectCard.bind(this);
    this.getCardClass = this.getCardClass.bind(this);
}

selectCard(offerId){
    this.setState({ cardActive: offerId })
}

getCardClass(offerId) {
    const { cardActive } = this.state;
    return offerId === cardActive ? 'cardActive' : 'card';
}

render() {
...
    customer.Offers.map((Offer,index) => {
        return <div key={index + Offer.OfferId} onClick={() => this.selectCard(Offer.OfferId)}>
            <div item xs={12}>
            <div className="card" class={this.getCardClass(Offer.OfferId)}>
                <div className="container">
                    <h5><b>{Offer.OfferId}</b></h5> 
                    <h2>{Offer.Name}</h2>
                    {Offer.Products.map((Product, index) => {
                        return <div key={index + Product.ProductId}>
                                <p>+ {Product.ProductName}</p>
                              </div>

                    })}
                    <h3>{Offer.Price}</h3> 
                </div>
            </div>
            </div>
        </div>
    })
...

}

Here the selected card is stored in the state instead of just the it being true or false. The selectCard helper method sets the value of cardActive while getCardClass determines the selected card's class.

Change background Color Button with onClick in reactjs � GitHub, In the above example, we define a function sayHello which alerts a message. Then, we use this function as the value of the onClick prop. Button text. Changing the� You can render a normal html <button> with React, as usual React prop conventions apply, such as onClick, style, etc. Button onClick. The button's onClick prop is what allows us to add a function which fires when the user clicks on the button. In the above example, we define a function sayHello which alerts a message. Then, we use this function

React Button Examples, It's included automatically with React-Bootstrap, but you should reference the API for Instead the <Overlay> (or <OverlayTrigger> ) components, inject ref and style props. You can also also have an "arrow" element, like the tooltips and popovers, but Pro Tip: Using the function form of OverlayTrigger avoids a React . React defines these synthetic events according to the W3C spec, so you don’t need to worry about cross-browser compatibility. See the SyntheticEvent reference guide to learn more. When using React, you generally don’t need to call addEventListener to add listeners to a DOM element after it is created. Instead, just provide a listener when

Overlays, The Box component packages all the style functions that are exposed in @ material-ui/system . For instance, you want to change the text color of the button. If you need to have access to the parent component in the handler, you also need to bind the function to the component instance (see below). How do I bind a function to a component instance? There are several ways to make sure functions have access to component attributes like this.props and this.state , depending on which syntax and build

Box React component, Note that all aria-* HTML attributes are fully supported in JSX. <input type="text " aria-label={labelText} aria-required="true" onChange={onchangeHandler}� Can I use inline styles? Yes, see the docs on styling here. Are inline styles bad? CSS classes are generally better for performance than inline styles. What is CSS-in-JS? “CSS-in-JS” refers to a pattern where CSS is composed using JavaScript instead of defined in external files. Read a comparison of CSS-in-JS libraries here.

Comments
  • If you're setting state based on a previous value in state, you should call it as a function: this.setState((state) => ({ cardActive: !state.cardActive })); That way you never get messed up by order of state setting
  • This is the best approach IMO.
  • Approach 1 sounds like the way to go but how would that look in code? I updated my constructor to include this.state = { clickedId: -1, } changed my selectCard function to this: selectCard(event){ const id = event.target.offerid this.setState({ cardActive: !this.state.cardActive, clickedId: id }) console.log(this.state.clickedId); } and changed the onClick to onClick={this.selectCard} but now when I click all I'm getting in the console is -1 and then undefined whenever I click
  • Rather than sending only event, why not send offer Id and the customer ID selected? You can use the selected offerid and customer ID (if needed) to identify which offer is selected and apply styles to that card
  • That was actually going to be my next question, how would I do that? My end goal is to pass both offerId and Customer ID to a function that sends a POST action when the user clicks submit
  • Will you be having only 1 card active at a time? if thats the case, you can maintain customerId and offer id in state and send it to POST action when user clicks submit. If not I would suggest go with the second approach where you can select all the active cards using isActive property within the customers/offers object and send those ids to your POST method
  • Yeup only 1 card selected at a time! I need to pass the following unique values from the initial JSON response (SessionID, CustomerID, Offers {OfferID, OfferName}) back in that POST action. Would I update my state then to look like: this.state = { cardActive: "", customerID: " ", Offer: " ", OfferID: " ", OfferName: " ", customers: [...] } and then bind them to state in a function like: submitSelection(offerId, offerName, CustomerId, SessionId, ){ this.setState({ offerId: , offerName, CustomerId, SessionId}); }