Tooltip Does Not Update Content with the View-Model fields and events
Environment
Product | Tooltip for Blazor |
Description
When I have some dynamic content inside the tooltip template, the tooltip seems not to be re-rendering. E.g. when I have a tooltip with a text input and button and wish to disable the button when no text is entered, the tooltip seems to be only refreshing after closing and re-opening it. Calling StateHasChanged
in the desired event does not help.
Steps to Reproduce
A simplified example - show the tooltip, type in the textbox - the expected behavior is that the button will get enabled, but it does not
@* Type in the textbox *@
<TelerikButton Class="search-tooltip" ThemeColor="primary">Click for tooltip</TelerikButton>
<TelerikTooltip TargetSelector=".search-tooltip" Position="TooltipPosition.Bottom" ShowOn="TooltipShowEvent.Click">
<Template>
<TelerikTextBox @bind-Value="@SearchText"></TelerikTextBox>
<TelerikButton OnClick="@Search" Enabled="@(!string.IsNullOrEmpty(SearchText))">Search</TelerikButton>
</Template>
</TelerikTooltip>
@code{
string SearchText { get; set; }
void Search()
{
Console.WriteLine("Search Click");
}
}
Possible Cause
The Tooltip component renders at the root of the app to ensure its correct position - it is a direct child of the <TelerikRootComponent>
in the main layout.
This means that its content is no longer a sibling or child of the current component whose view-model you changed, and this is why calls to StateHasChanged
do not update it.
Solution
Encapsulate the desired Tooltip content in a separate child component that has its own logic and component life cycle. This will help with the rendering updates. You can expose the necessary parameters and events, so that there are no API changes in the view-model of the main component
Note that the child component will call its OnParametersSet
method only on Tooltip display. If you need OnParametersSet
to execute on each parameter change from the parent component, then use two nested components inside the Tooltip template.
<TelerikButton Class="search-tooltip-target" ThemeColor="@ThemeConstants.Button.ThemeColor.Primary">Click to Show Tooltip</TelerikButton>
@SearchClickLog
<TelerikTooltip TargetSelector=".search-tooltip-target"
Position="TooltipPosition.Bottom"
ShowOn="TooltipShowEvent.Click">
<Template>
@* The Update AnotherParameter button will not work
unless the whole Tooltip Template content is in a child component. *@
<TelerikButton OnClick="@UpdateAnotherParameter"
ThemeColor="@ThemeConstants.Button.ThemeColor.Error">
Update AnotherParameter
</TelerikButton>
<TelerikButton OnClick="@UpdateAnotherValue"
ThemeColor="@ThemeConstants.Button.ThemeColor.Success">
Update AnotherValue
</TelerikButton>
<br />
<br />
<SearchTooltipContent @ref="@CounterRef"
@bind-SearchText="@SearchText"
AnotherParameter="@AnotherValue"
OnSearch="@Search" />
</Template>
</TelerikTooltip>
@code{
private string SearchText { get; set; } = string.Empty;
private string SearchClickLog { get; set; } = string.Empty;
private int AnotherValue { get; set; }
private Counter? CounterRef { get; set; }
private void Search()
{
SearchClickLog = $"Search Button clicked at {DateTime.Now.ToString("HH:mm:ss.fff")} for {SearchText}.";
}
private void UpdateAnotherParameter()
{
// Will not work inside a Tooltip,
// unless this method is insde a child component of the Tooltip Template
// and AnotherValue is consumed by a grand child.
// Use the next method as an alternative.
AnotherValue = DateTime.Now.Millisecond;
}
private void UpdateAnotherValue()
{
AnotherValue = DateTime.Now.Millisecond;
CounterRef?.GetValuesFromParent(AnotherValue);
}
}