Skip to content

Commit 69cd30f

Browse files
dimodiTsvetomir-Hr
andauthored
kb(Editor): Add KB for focus event handling (#3179)
* kb(Editor): Add KB for focus event handling * Update knowledge-base/editor-focus-event.md Co-authored-by: Tsvetomir Hristov <[email protected]> * Polish code examples --------- Co-authored-by: Tsvetomir Hristov <[email protected]>
1 parent e9a7e39 commit 69cd30f

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
---
2+
title: Editor Focus Event
3+
description: Learn how to subscribe to the Editor focus event.
4+
type: how-to
5+
page_title: How to Handle the Editor Focus Event
6+
slug: editor-kb-focus-event
7+
tags: telerik, blazor, editor, events
8+
ticketid: 1695979
9+
res_type: kb
10+
---
11+
12+
## Environment
13+
14+
<table>
15+
<tbody>
16+
<tr>
17+
<td>Product</td>
18+
<td>Editor for Blazor</td>
19+
</tr>
20+
</tbody>
21+
</table>
22+
23+
## Description
24+
25+
This KB article answers the following questions:
26+
27+
* How to detect when the user focuses the Editor content?
28+
* How to handle the Editor focus event?
29+
* Is it possible to do a Blazor action on Editor OnFocus?
30+
31+
## Solution
32+
33+
The required approach depends on the [Editor `EditMode`](slug:editor-edit-modes-overview), due to the different Editor HTML rendering:
34+
35+
* [Using `Div` edit mode](#div-editmode)
36+
* [Using `Iframe` edit mode](#iframe-editmode)
37+
38+
### `Div` EditMode
39+
40+
1. Learn how to [call JavaScript code from C# code](https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-javascript-from-dotnet).
41+
1. Wrap the Editor in a container with an `@onfocusin` event.
42+
1. Use JavaScript to check if the Editor content `<div class="k-content ProseMirror">` is focused.
43+
44+
>caption Detect Editor focus when using Div EditMode
45+
46+
````RAZOR
47+
@using Telerik.Blazor.Components.Editor
48+
49+
@inject IJSRuntime js
50+
51+
<div @onfocusin="@OnDivEditorFocus">
52+
<TelerikEditor @bind-Value="@EditorValue"
53+
Tools="@EditorToolSets.All"
54+
EditMode="@EditorEditMode.Div"
55+
Height="300px">
56+
</TelerikEditor>
57+
</div>
58+
59+
@* Move JavaScript code to a separate JS file *@
60+
<script suppress-error="BL9992">
61+
function isEditorDivFocused() {
62+
return document.activeElement &&
63+
document.activeElement.classList.contains("k-content") &&
64+
document.activeElement.classList.contains("ProseMirror");
65+
}
66+
67+
</script>
68+
69+
@code {
70+
#nullable enable
71+
72+
private string EditorValue { get; set; } = @"<p>foo 1</p><p>bar 1</p>";
73+
74+
private async Task OnDivEditorFocus()
75+
{
76+
bool isEditorContentFocused = await js.InvokeAsync<bool>("isEditorDivFocused");
77+
78+
if (isEditorContentFocused)
79+
{
80+
EditorValue = $"<p>Editor content DIV was focused at {DateTime.Now.ToLongTimeString()}.</p>";
81+
}
82+
}
83+
}
84+
````
85+
86+
### `Iframe` EditMode
87+
88+
1. Learn how to [call C# code from JavaScript code](https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-dotnet-from-javascript) and [vice-versa](https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-javascript-from-dotnet).
89+
1. Use the first firing of `OnAfterRenderAsync` to:
90+
1. Obtain the `<body>` element inside the Editor content `iframe`.
91+
1. [Subscribe](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) to the `focusin` event to the `iframe` `body`.
92+
1. In the JavaScript `focusin` handler, call a C# method.
93+
94+
>caption Detect Editor focus when using Iframe EditMode
95+
96+
````RAZOR
97+
@using Telerik.Blazor.Components.Editor
98+
99+
@implements IDisposable
100+
101+
@inject IJSRuntime js
102+
103+
<TelerikEditor @bind-Value="@EditorValue"
104+
Tools="@EditorToolSets.All"
105+
Id="@EditorId"
106+
Height="300px">
107+
</TelerikEditor>
108+
109+
@* Move JavaScript code to a separate JS file *@
110+
<script suppress-error="BL9992">
111+
var dotNet;
112+
113+
function attachIframeFocusHandler(id, dotNetRef) {
114+
var editor = document.getElementById(id);
115+
if (editor) {
116+
dotNet = dotNetRef;
117+
editor.querySelector("iframe").contentWindow.document.body.addEventListener("focusin", OnEditorBodyFocus);
118+
}
119+
}
120+
121+
function OnEditorBodyFocus(args) {
122+
dotNet.invokeMethodAsync("OnEditorFocus2");
123+
}
124+
125+
function detachIframeFocusHandler(id) {
126+
var editor = document.getElementById(id);
127+
if (editor) {
128+
editor.querySelector("iframe").contentWindow.document.body.removeEventListener("focusin", OnEditorBodyFocus);
129+
}
130+
}
131+
</script>
132+
133+
@code {
134+
#nullable enable
135+
136+
private string EditorValue { get; set; } = @"<p>foo 2</p><p>bar 2</p>";
137+
138+
private const string EditorId = "iframe-editor";
139+
140+
// Replace __Main with your Razor component type
141+
private DotNetObjectReference<Home>? DotNetRef { get; set; }
142+
143+
[JSInvokable("OnEditorFocus2")]
144+
public void OnEditorFocus2()
145+
{
146+
EditorValue = $"<p>Editor content IFRAME was focused at {DateTime.Now.ToLongTimeString()}.</p>";
147+
StateHasChanged();
148+
}
149+
150+
protected override void OnInitialized()
151+
{
152+
DotNetRef = DotNetObjectReference.Create(this);
153+
}
154+
155+
protected override async Task OnAfterRenderAsync(bool firstRender)
156+
{
157+
if (firstRender)
158+
{
159+
await Task.Delay(1); // wait for HTML to render
160+
161+
await js.InvokeVoidAsync("attachIframeFocusHandler", EditorId, DotNetRef);
162+
}
163+
164+
await base.OnAfterRenderAsync(firstRender);
165+
}
166+
167+
public void Dispose()
168+
{
169+
DotNetRef?.Dispose();
170+
}
171+
}
172+
````
173+
174+
## See Also
175+
176+
* [Editor Events](slug:editor-events)

0 commit comments

Comments
 (0)