ksenia
ksenia

Reputation: 177

Apply style to only one element of a map of elements

I am trying to imitate a behaviour of a checked componenet applied to a map of divs. I am mapping displayName and imageUrl of an array of elements called price. On click of the div, in handleProductSelect function, I would like only the clicked div to be highlighted, however they all become highlighted, which makes sense, because I am collectively making a change in the style.

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            borderColor: 'white',
}
}


    handleProductSelect() {
        const { borderColor } = this.state;
        let newBorderColour = borderColor === 'white' ? 'blue' : 'white';
        this.setState({
            borderColor: newBorderColour,
        })
    }

(price.map(p =>
                    <div key={p.productId}>
                        <div
                            style={{ 
                                borderRadius: '10%',
                                borderStyle: 'solid',
                                padding: '10px',
                                marginBottom: 10,
                                borderColor: this.state.borderColor,
                             }}
                            onClick={this.handleProductSelect(p.productId)}>
                            <div>{p.displayName}</div><br />
                            <div>{p.imageUrl !== '' ? p.imageUrl : <img style={{ width: '100px', height: '50px' }} src={"https://source.unsplash.com/200/150"} />}</div><br />
                        </div>
                    </div>
                ))
}

Does anyone have any idea on how to make only the clicked element highlighted?

Upvotes: 0

Views: 2464

Answers (2)

Anupam Maurya
Anupam Maurya

Reputation: 2231

Here I have fixes the syntax of ternary operator style css, and fatArrow function call with onClick event

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            borderColor: 'white',
            active_id: null
        };
}


    handleProductSelect(productId) {
        const { borderColor } = this.state;
        let newBorderColour = borderColor === 'white' ? 'blue' : 'white';
        this.setState({
            borderColor: newBorderColour,
            active_id: productId
        })
    }

render {
return(
    (price.map(p =>
        <div key={p.productId}>
            <div
                style={{ 
                    borderRadius: '10%',
                    borderStyle: 'solid',
                    padding: '10px',
                    marginBottom: 10,
                    p.productId === this.state.active_id ? { borderColor: this.state.borderColor} : {borderColor : 'white'}
                 }}


                onClick={(p)=> this.handleProductSelect(p.productId)}>
                <div>{p.displayName}</div><br />
                <div>{p.imageUrl !== '' ? p.imageUrl : <img style={{ width: '100px', height: '50px' }} src={"https://source.unsplash.com/200/150"} />}</div><br />
            </div>
        </div>
    ))
    }
)}

Upvotes: 0

Velimir Tchatchevsky
Velimir Tchatchevsky

Reputation: 2825

Use the id that you are passing to your handleProductSelect function and save it to the state. You can use it in the render method, to figure which one is the clicked element and apply the appropriate style to it

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            borderColor: 'white',
            active_id: null
        };
}


    handleProductSelect(productId) {
        const { borderColor } = this.state;
        let newBorderColour = borderColor === 'white' ? 'blue' : 'white';
        this.setState({
            borderColor: newBorderColour,
            active_id: productId
        })
    }

render {
return(
    (price.map(p =>
        <div key={p.productId}>
            <div
                style={{ 
                    borderRadius: '10%',
                    borderStyle: 'solid',
                    padding: '10px',
                    marginBottom: 10,
                    borderColor: ( p.productId === this.state.active_id ? this.state.borderColor : 'white'),
                 }}
                onClick={this.handleProductSelect.bind(this, p.productId)}>
                <div>{p.displayName}</div><br />
                <div>{p.imageUrl !== '' ? p.imageUrl : <img style={{ width: '100px', height: '50px' }} src={"https://source.unsplash.com/200/150"} />}</div><br />
            </div>
        </div>
    ))
    }
)}

Upvotes: 1

Related Questions