user3230660
user3230660

Reputation:

Get attribute value in click handler?

How can I get the value of the eventKey attribute and pass it to my function in the following line?

<Accordion.Toggle 
   as={Card.Header} 
   eventKey="2" 
   data-foo="zzz" 
   onClick={(e) => CardClick(e.currentTarget.getAttribute('eventKey') ?? "unknown")}> // unknown.  Desired value: 2

The following is addressed in this question. In my case however the attribute I need to get is not prefixed with "data-".

Works:

<Accordion.Toggle 
   as={Card.Header} 
   eventKey="2" 
   data-foo="zzz" 
   onClick={(e) => CardClick(e.currentTarget.getAttribute('data-foo') ?? "unknown")}> // zzz 

Not works:

<Accordion.Toggle 
   as={Card.Header} 
   eventKey="2" 
   data-foo="zzz" 
   onClick={(e) => CardClick(e.currentTarget.getAttribute('data-eventKey') ?? "unknown")}> // unknown

Complete component:

<Card>
    <Accordion.Toggle as={Card.Header} eventKey="0" className="faq-header" onClick={(e) => CardClick(e.currentTarget.getAttribute('eventKey') ?? "unknown")}>
        <span className="rh5">Some text</span>
    </Accordion.Toggle>
    <Accordion.Collapse eventKey="0">
        <Card.Body>
            <span className="rh6">
                Some text
            </span>
        </Card.Body>
    </Accordion.Collapse>
</Card>

Upvotes: 2

Views: 335

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42298

As explained by @DrewReese in the comments, it is impossible to get the eventKey from the DOM element (e.target) because it is never passed down to the DOM.

We should get it from the props instead. We do need to use eventKey in three places: as the eventKey prop in both the Toggle and the Collapse and in our onClick. But when it becomes abstracted out as a component prop, we only need to declare the specific event key, ie. eventKey="2", once.

import React from "react";
import { Accordion, Card } from "react-bootstrap";

interface RenderCardProps {
  eventKey: string;
  CardClick: (key: string) => void;
  /** add whatever else you need */
}

const RenderCard = ({ eventKey, CardClick }: RenderCardProps) => {
  return (
    <Card>
      <Accordion.Toggle
        as={Card.Header}
        eventKey={eventKey}
        className="faq-header"
        onClick={() => CardClick(eventKey)}
      >
        <span className="rh5">Some text</span>
      </Accordion.Toggle>
      <Accordion.Collapse eventKey={eventKey}>
        <Card.Body>
          <span className="rh6">Some text</span>
        </Card.Body>
      </Accordion.Collapse>
    </Card>
  );
};

export default () => <RenderCard CardClick={console.log} eventKey="2" />;

You probably want to make ToggleContents and CardContents into props too in order to use this as an actual component.

Upvotes: 2

Related Questions