How to close SFToolTip on clicked outside?

Hello,

As the title says, how can we close an SFToolTip when clicked/touched outside of the tooltip?

I want to use the Click as open mode but I also want it to close when the user clicks the outside of the Tooltip element. How can I achieve that?

Tha


10 Replies 1 reply marked as answer

SM Shalini Maragathavel Syncfusion Team July 23, 2021 02:22 PM UTC

Hi Ahmet, 

Greetings from Syncfusion support. 

Based on your query we could understand that you need to show the Tooltip while clicking on the target and close the Tooltip on document click. You can achieve your requirement by setting the OpensOn property as Custom, then open and close the Tooltip using OpenAsync and CloseAsync methods based on the target in server to client method (using JS Interop) in Created event of Tooltip component.  

Refer to the below code snippet, 

index.razor 
<div class="col-lg-8 control-section"> 
    <!-- Tooltip element --> 
    <SfTooltip @ref="tooltip" HtmlAttributes="HtmlAttribute" Created="created" ID="@Id"  Height="@TooltipHeight" Width="@TooltipWidth" Content="@TooltipContent" OpensOn="@OpensOn"> 
        <SfButton   Content="Show Tooltip"></SfButton> 
    </SfTooltip> 
</div> 
 
@code 
{ 
    SfTooltip tooltip; 
    string OpensOn = "Custom"; 
    [Inject] 
    public IJSRuntime JSRuntime { get; set; } 
    public void created() 
    { 
        JsRuntime.InvokeAsync<string>("tooltip", new object[] { DotNetObjectReference.Create<object>(this) }); 
    } 
    [JSInvokable] 
    public void Tooltip_Element(bool tooltip) 
    { 
         
        if (tooltip)  
        { 
            this.tooltip.OpenAsync(); //to open tooltip on target click 
        } 
        Else  
        { 
            this.tooltip.CloseAsync();  //to close tooltip on document click 
 
        } 
    } 
 
} 

_host.cshtml 
<script>  
       window.tooltip = (args) => { 
            document.addEventListener("click", function (e) {               
              if (e.target.classList.contains('e-btn')) { //to check the target click 
              args.invokeMethodAsync('Tooltip_Element', true); 
              } 
           else { 
             args.invokeMethodAsync('Tooltip_Element', false); 
                    } 
                    }); 
            };  
        
    </script> 

Please find the below sample for your reference, 
Please let us know if you need further assistance. 

Regards, 
Shalini M. 



AH Ahmet July 23, 2021 03:18 PM UTC

Hi Shalini,

Thanks but in your example, the tooltip is also closed when clicked on the tooltip. Is it possible to close it only when clicked on the outside of the tooltip?



SM Shalini Maragathavel Syncfusion Team July 26, 2021 11:52 AM UTC

Hi Ahmet, 

Good day to you. 

You can prevent the Tooltip from closing while clicking on the Tooltip by calling the OpenAsync and CloseAsync methods based on the target as demonstrated in the below code snippet,  
 
_host.cshtml 
<script>  
   window.tooltip = (args) => { 
  document.addEventListener("click", function (e) { 
  if (e.target.classList.contains('e-btn')) { 
   args.invokeMethodAsync('Tooltip_Element', true); 
 } 
   else if (!e.target.closest('.e-popup-open')) { 
    args.invokeMethodAsync('Tooltip_Element', false); 
     } 
  }); 
   };  
 </script> 

Please find the below sample for your reference, 
Please let us know if you need further assistance. 

Regards, 
Shalini M. 



Marked as answer

AH Ahmet July 26, 2021 02:36 PM UTC

That did the job, thanks a lot.



KR Keerthana Rajendran Syncfusion Team July 27, 2021 05:02 AM UTC

Hi Ahmet, 

Most welcome. We are glad that the provided suggestion helped you. Please get back to us if you need further assistance. 

Regards, 
Keerthana. 



MW Mike Wozniak replied to Shalini Maragathavel January 22, 2024 06:44 PM UTC

This works fine for a single tooltip. How do you handle more than one tooltip on the page?  I can create a unique ref for each tooltip , but how do I determine which tooltip needs to be opened or closed?


I'm not very familiar with JavaScript.  Is there a way to pass some sort of identifier to the

Tooltip_Element invoked method?  Something like:

    [JSInvokable]
    public void Tooltip_Element(bool tooltip, string ID)
    {
        if (tooltip)
        {
            _toolTip.OpenAsync(); //to open tooltip on target click
        }
        else
        {
            _toolTip.CloseAsync(); //to close tooltip on document click
        }
    }


Or is there a better way?  I was able to create a razor component with the necessary code, but when I place two components on the same page, both get executed when I click on either one.  I cannot figure out how to tell which tooltip should be opened or closed.

I attached the zipped custom component source.


Attachment: CustomToolTip_2deb1bc3.rar



PM Prasanth Madhaiyan Syncfusion Team January 23, 2024 12:14 PM UTC

Hi Mike,


Based on the shared details, to handle more than one tooltip on the page, you can create a unique reference (ref) for each tooltip. Additionally, you can use the target element ID as an identifier for the tooltip component. This way, you can determine which tooltip needs to be opened or closed using the OpenAsync and CloseAsync methods of the Tooltip component.


Refer to the below code snippets.


[Index.razor]


<div class="col-lg-8 control-section">

    <!-- Tooltip 1 -->

    <SfTooltip @ref="tooltip1" CssClass="tooltip_style" Created="() => created()" ID="tooltip1" Height="@TooltipHeight" Width="@TooltipWidth" Content="@TooltipContent1" OpensOn="@OpensOn">

        <SfButton id="btn1" Content="Show Tooltip 1"></SfButton>

    </SfTooltip>

   

    <!-- Tooltip 2 -->

    <SfTooltip @ref="tooltip2" CssClass="tooltip_style" Created="() => created()" ID="tooltip2" Height="@TooltipHeight" Width="@TooltipWidth" Content="@TooltipContent2" OpensOn="@OpensOn">

        <SfButton id="btn2"  Content="Show Tooltip 2"></SfButton>

    </SfTooltip>

</div>

 

@code

{

    SfTooltip tooltip1;

    SfTooltip tooltip2;

 

   

    string TooltipContent1 = "Tooltip Content1";

    string TooltipContent2 = "Tooltip Content2";

    string id1 = "tooltip1";

    string id2 = "tooltip2";

 

    [Inject]

    public IJSRuntime JSRuntime { get; set; }

 

    public void created()

    {

        JsRuntime.InvokeAsync<string>("tooltip", new object[] { DotNetObjectReference.Create<object>(this) });

    }

 

    [JSInvokable]

    public void Tooltip_Element(string tooltipId, bool showTooltip)

    {

        Dictionary<string, SfTooltip> tooltips = new Dictionary<string, SfTooltip>

        {

            { "btn1", tooltip1 },

            { "btn2", tooltip2 }

        };

 

        if (tooltips.TryGetValue(tooltipId, out var tooltip))

        {

            HandleTooltip(tooltip, showTooltip);

        }

        else

        {

            foreach (var t in tooltips.Values)

            {

                t.CloseAsync();

            }

        }

    }

 

    private void HandleTooltip(SfTooltip tooltip, bool showTooltip)

    {

        if (showTooltip)

        {

            tooltip.OpenAsync();

        }

        else

        {

            tooltip.CloseAsync();

        }

    }

}


[_Host.cshtml]


 

<script>

    window.tooltip = (args) => {

        document.addEventListener("click", function (e) {

            if (e.target.id == "btn1" || e.target.id == "btn2") {

                args.invokeMethodAsync('Tooltip_Element', e.target.id, true);

            } else {

                args.invokeMethodAsync('Tooltip_Element', e.target.id, false);

            }

        });

    };

</script>


For your reference, we have attached the sample.


Sample: Attached as a zip file.


Check out the attached sample, and if we have misunderstood your exact requirement in the Tooltip component, could you please share the exact requirement with more details? If possible, share the sample as well. Based on that, we will check and provide you with a prompt solution. Kindly get back to us with the requested details.


Regards,

Prasanth Madhaiyan.


Attachment: BlazorTooltipSample_ee34730d.zip


DA Dan January 23, 2024 10:15 PM UTC

Thank you, that helped.




DA Dan January 25, 2024 08:32 PM UTC

Using the sample code you provided, I created a razor tooltip component.  For some reason, the tooltip is always placed underneath the targeted component.  I have tried setting the Position property of SfTooltip, but it has no effect.  In addition, there is an odd drawing anomaly next to the tip of the arrow.  It is a small circle next to the tip (see screenshot).

I cannot reproduce this in the sample application you provided in this thread.


I'm attaching the source code for the razor component and screenshots of the issue.  Any ideas on how to troubleshoot this?  I'm using version 24.1.44.



tooltip_placement.png


Attachment: FloqqueToolTip_74bf60d2.zip



PM Prasanth Madhaiyan Syncfusion Team January 26, 2024 12:24 PM UTC

Hi Dan,


Based on the shared details, we have validated your reported query by preparing a sample using the provided code snippets. We were able to reproduce the mentioned scenario in the Blazor Tooltip component. However, to overcome this scenario, you need to enable the WindowCollision property on your end. This property indicates whether to set the collision target element as the page viewport (window) or the Tooltip element when using the target.


For your reference, we have attached the sample and screenshot.


Sample: Attached as a zip file.


Screenshot:



Check out the attached sample and let us know if you need any further assistance.


Regards,

Prasanth Madhaiyan.


Attachment: BlazorTooltipSample_d5109722.zip

Loader.
Up arrow icon