Search code examples
web-chatbotframework

How to add tooltip to QnAMakerOptions button in Microsoft Bot Framework Webchat


I am getting options from QnAMakerOptions and displaying it on Webchat..sometimes the text on that option is too large and it gets truncated. Hence, I need to provide tootip on those options, so that user can hover over it and read complete text. I see a property _element.title in bot framework's webchat.js , but what value needs to be assigned to it or is there any other way it can be achieved. Any pointers would be helpful. Thanks in advance.

enter image description here


Solution

  • If you make use of Web Chat's store, you can filter per activity and find the associated card in the DOM. Then, it's simply a matter of applying the button's textContent value to the title property.

    Please note:

    • In Web Chat, all cards are rendered as adaptive cards, though elements of the card (e.g. buttons) may reference a different schema based on the original card type sent (e.g. hero card). Hence, the below query is correctly searching for .ac-adaptiveCard.
    • The setTimeout() is necessary as, without it, the script will query the DOM, looking for .ac-adaptiveCard's, before the store has finished processing activities (a processed activity is an indication that it is being rendered in the transcript window as HTML). The result is an attempt to update the button will occur before the button actually exists in the DOM.
    [...]
    
    const store = window.WebChat.createStore( {}, ( { dispatch } ) => next => action => {
      if ( action.type === 'DIRECT_LINE/INCOMING_ACTIVITY' ) {
        let activity = action.payload.activity;
        if (activity?.attachments && activity.attachments[ 0 ]?.contentType.includes( 'card' ))
    
        setTimeout( () => {
          let cards = document.querySelectorAll( '.ac-adaptiveCard' )
          let cardLength = cards.length;
          let card = cards[ cardLength - 1 ];
          card.querySelectorAll( 'button' ).forEach( button => {
            if ( !!button.children[ 0 ].textContent === true ) {
              button.title = button.children[ 0 ].textContent;
            }
          } );
        }, 300 )
      }
    
      return next( action );
    } );
    
    [...]
    
    render(
      <ReactWebChat
        directLine={await window.WebChat.createDirectLine( {token} )}
        store={store}
      />,
      document.getElementById( 'webchat' )
    );
    

    Hope of help!