Search code examples
reactjstypescriptmicrosoft-graph-toolkit

How do I have a button nested in the mgt-person-card template?


I have been implementing the MGT toolkit within my React + Typescript. It has all worked well, but I've tried to add a button within the template in the card. But the onClick doesn't seem to be working, I'm assuming this is something to do with the fact it is a template.

I see that there might be a problem as it is a template that might get copied across but I figured that the work around below would be fine. But whatever I get I can't get anything from the

    const mgtPersonRef = useRef<null | MgtPerson>(null);

    useEffect(() => {
        const mgtPerson = mgtPersonRef.current;
        if (mgtPerson === null) {
            return;
        }
        mgtPerson.personCardInteraction = PersonCardInteraction.hover;
        const button= mgtPerson.querySelector('#' + BUTTON);

        if (button) {
            button.addEventListener('onmousedown', () => {console.log("DONE IT!")});
            return button.removeEventListener('onmousedown', () => void 0);
        }

    }, [mgtPersonRef.current]);
    return <mgt-person
        show-name={true}
        user-id={id}
        ref={mgtPersonRef}
    >
        <template data-type="person-card">
            <mgt-person-card person-details="{{person}}" >
                {
                    showButton
                        ? <template data-type="additional-details">
                            <button
                                id={BUTTON}
                            >Click me</button>
                        </template>
                        : null
                }
            </mgt-person-card>
        </template>
    </mgt-person>;

Solution

  • You can use the templateRendered event here which fires after a template has been rendered and passes the element and the dataContext for you to work with. You will have to register this event twice, once for the person and then for the person card.

    mgtPerson.addEventListener('templateRendered', e => {
    
      const personCard = e.detail.element.querySelector('mgt-person-card');
      personCard.addEventListener('templateRendered', e => {
    
        const templateType = e.detail.templateType; // the data-type of the template
        const dataContext = e.detail.context; // the data context passed to the template
        const element = e.detail.element; // the root element of the rendered template
    
        const button = element.querySelector('button');
        if (button) {
          button.addEventListener('click', () => {});
        }
    
      });
    });
    
    

    This can also be helpful if you want to use React for rendering of the template as well.

    P.S. There is a PR in progress on the Microsoft Graph Toolkit to make this even easier by adding ability to register events directly in your templates