|
| 1 | +--- |
| 2 | +title: Add Font Icons in Editor |
| 3 | +description: How to insert <i> tags in the Editor for Blazor to render custom icons in the Editor content? |
| 4 | +type: how-to |
| 5 | +page_title: How to Add Font Icons in the Telerik Editor for Blazor |
| 6 | +slug: editor-kb-add-icons |
| 7 | +position: |
| 8 | +tags: blazor, editor, prosemirror, schema, icon |
| 9 | +ticketid: |
| 10 | +res_type: kb |
| 11 | +--- |
| 12 | + |
| 13 | +## Environment |
| 14 | +<table> |
| 15 | + <tbody> |
| 16 | + <tr> |
| 17 | + <td>Product</td> |
| 18 | + <td>Editor for Blazor</td> |
| 19 | + </tr> |
| 20 | + </tbody> |
| 21 | +</table> |
| 22 | + |
| 23 | + |
| 24 | +## Description |
| 25 | + |
| 26 | +This KB article answers the following questions: |
| 27 | + |
| 28 | +* How to add custom icons in the Editor content? When adding an icon such as `<i class="fa-light fa-envelope">`, the icon's HTML disappears upon saving. |
| 29 | +* How can I add an `<i>` element inside the Editor? |
| 30 | + |
| 31 | +## Solution |
| 32 | + |
| 33 | +The default schema of the Telerik Editor does not include an `<i>` tag, so the Editor strips such elements automatically. To allow adding font icons through `<i>` tags in the Editor content: |
| 34 | + |
| 35 | +1. [Modify the ProseMirror schema]({%slug editor-modify-default-schema%}) to include a node for the `<i>` element. |
| 36 | +2. Ensure the required font icon stylesheets can affect the Editor content. The approach varies depending on the [edit mode of the Editor]({%slug editor-edit-modes-overview%}): |
| 37 | + * [Iframe Edit Mode](#add-icons-in-iframe-edit-mode) |
| 38 | + * [Div Edit Mode](#add-icons-in-div-edit-mode) |
| 39 | + |
| 40 | + |
| 41 | +### Add Icons in Iframe Edit Mode |
| 42 | + |
| 43 | +When the [Editor `EditMode` is set to `EditorEditMode.Iframe`]({%slug editor-edit-modes-iframe%}), the content area is inside an `<iframe>` element that does not apply the CSS rules from the current page. |
| 44 | + |
| 45 | +This means that you need to inject the icons stylesheet into the `<iframe>`, so the icons are properly rendered. At the time of writing (UI for Blazor **6.1.0**), [the Editor does not support injecting your CSS files into the iframe](https://feedback.telerik.com/blazor/1543925-add-the-ability-to-inject-css-files-into-the-iframe) but you can inject them with JSInterop in `OnAfterRenderAsync`. |
| 46 | + |
| 47 | +>caption Add icons in an Editor with Iframe edit mode |
| 48 | +
|
| 49 | +````CSHTML |
| 50 | +@using Telerik.Blazor.Components.Editor |
| 51 | +@inject IJSRuntime js |
| 52 | +
|
| 53 | +<TelerikEditor @bind-Value="@EditorValue" |
| 54 | + Tools="@EditorTools" |
| 55 | + Schema="schemaProvider" |
| 56 | + Height="300px"> |
| 57 | +</TelerikEditor> |
| 58 | +
|
| 59 | +@code { |
| 60 | + private string EditorValue { get; set; } = @"<p>Here is an example icon in the Editor content <i class='fa fa-info-circle'></i></p>"; |
| 61 | +
|
| 62 | + private List<IEditorTool> EditorTools { get; set; } = new List<IEditorTool>() { new ViewHtml() }; |
| 63 | +
|
| 64 | + protected override async Task OnAfterRenderAsync(bool firstRender) |
| 65 | + { |
| 66 | + if (firstRender) |
| 67 | + { |
| 68 | + await js.InvokeVoidAsync("injectEditorStylesheet"); |
| 69 | + } |
| 70 | + } |
| 71 | +} |
| 72 | +
|
| 73 | +@* Move JavaScript code to a separate JS file in production *@ |
| 74 | +<script suppress-error="BL9992"> |
| 75 | +
|
| 76 | + //define the icon node |
| 77 | + var iconNode = { |
| 78 | + attrs: { |
| 79 | + class: { default: null }, |
| 80 | + type: { default: null }, |
| 81 | + }, |
| 82 | + group: "inline", |
| 83 | + content: "text*", |
| 84 | + inline: true, |
| 85 | + parseDOM: [ |
| 86 | + { |
| 87 | + tag: "i", |
| 88 | + getAttrs: (dom) => ({ |
| 89 | + class: dom.getAttribute("class"), |
| 90 | + }), |
| 91 | + }, |
| 92 | + ], |
| 93 | + toDOM: (node) => { |
| 94 | + const attrs = { |
| 95 | + class: node.attrs.class |
| 96 | + }; |
| 97 | + return ["i", attrs]; |
| 98 | + }, |
| 99 | + }; |
| 100 | +
|
| 101 | + //add the icon node to the Editor ProseMirror schema |
| 102 | + window.schemaProvider = (args) => { |
| 103 | + const schema = args.getSchema(); |
| 104 | + const Schema = args.ProseMirror.Schema |
| 105 | +
|
| 106 | + let nodes = schema.spec.nodes.addToEnd("i", iconNode); |
| 107 | +
|
| 108 | + const newSchema = new Schema({ nodes }); |
| 109 | + return newSchema; |
| 110 | + } |
| 111 | +
|
| 112 | + //inject the stylesheet for the icons, so they are properly visualized |
| 113 | + function injectEditorStylesheet() { |
| 114 | + var doc = document.querySelector("iframe").contentWindow.document; |
| 115 | + var head = doc.querySelector("head"); |
| 116 | +
|
| 117 | + var bootstrapCssLink = document.createElement("link"); |
| 118 | + bootstrapCssLink.href = "https://cdnjs.cloudflare.com/ajax/libs/open-iconic/1.1.1/font/css/open-iconic-bootstrap.min.css"; |
| 119 | + bootstrapCssLink.rel = "stylesheet"; |
| 120 | +
|
| 121 | + var fontAwesomeCssLink = document.createElement("link"); |
| 122 | + fontAwesomeCssLink.href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"; |
| 123 | + fontAwesomeCssLink.rel = "stylesheet"; |
| 124 | +
|
| 125 | + head.appendChild(bootstrapCssLink); |
| 126 | + head.appendChild(fontAwesomeCssLink); |
| 127 | + }; |
| 128 | +
|
| 129 | +</script> |
| 130 | +```` |
| 131 | + |
| 132 | +### Add Icons in Div Edit Mode |
| 133 | + |
| 134 | +When the [Editor `EditMode` is set to `EditorEditMode.Div`]({%slug editor-edit-modes-div%}), the content area is a `<div contenteditable="true">` element that inherits the CSS rules from the current page. |
| 135 | + |
| 136 | +This allows you to include the icon stylesheets in the `<head>` of the web page along with the other stylesheets. |
| 137 | + |
| 138 | +>caption Add icons in an Editor with Div edit mode |
| 139 | +
|
| 140 | +````CSHTML |
| 141 | +@using Telerik.Blazor.Components.Editor |
| 142 | +
|
| 143 | +@* Just one example of including custom font icon libraries. |
| 144 | +Make sure to use the correct way and resources for your actual project *@ |
| 145 | +<link href="https://cdnjs.cloudflare.com/ajax/libs/open-iconic/1.1.1/font/css/open-iconic-bootstrap.min.css" rel="stylesheet" /> |
| 146 | +<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet" /> |
| 147 | +
|
| 148 | +<TelerikEditor @bind-Value="@EditorValue" |
| 149 | + Tools="@EditorTools" |
| 150 | + Schema="schemaProvider" |
| 151 | + EditMode="@EditorEditMode.Div" |
| 152 | + Height="300px"> |
| 153 | +</TelerikEditor> |
| 154 | +
|
| 155 | +@code { |
| 156 | + private string EditorValue { get; set; } = @"Here is an example icon in the Editor content <i class='fa fa-info-circle'></i>"; |
| 157 | +
|
| 158 | + private List<IEditorTool> EditorTools { get; set; } = new List<IEditorTool>() { new ViewHtml() }; |
| 159 | +} |
| 160 | +
|
| 161 | +@* Move JavaScript code to a separate JS file in production *@ |
| 162 | +<script suppress-error="BL9992"> |
| 163 | +
|
| 164 | + //define the icon node |
| 165 | + var iconNode = { |
| 166 | + attrs: { |
| 167 | + class: { default: null }, |
| 168 | + type: { default: null }, |
| 169 | + }, |
| 170 | + group: "inline", |
| 171 | + content: "text*", |
| 172 | + inline: true, |
| 173 | + parseDOM: [ |
| 174 | + { |
| 175 | + tag: "i", |
| 176 | + getAttrs: (dom) => ({ |
| 177 | + class: dom.getAttribute("class"), |
| 178 | + }), |
| 179 | + }, |
| 180 | + ], |
| 181 | + toDOM: (node) => { |
| 182 | + const attrs = { |
| 183 | + class: node.attrs.class |
| 184 | + }; |
| 185 | + return ["i", attrs]; |
| 186 | + }, |
| 187 | + }; |
| 188 | + debugger |
| 189 | +
|
| 190 | + //add the icon node to the Editor ProseMirror schema |
| 191 | + window.schemaProvider = (args) => { |
| 192 | + const schema = args.getSchema(); |
| 193 | + const Schema = args.ProseMirror.Schema |
| 194 | +
|
| 195 | + let nodes = schema.spec.nodes.addToEnd("i", iconNode); |
| 196 | +
|
| 197 | + const newSchema = new Schema({ nodes }); |
| 198 | + return newSchema; |
| 199 | + } |
| 200 | +
|
| 201 | +</script> |
| 202 | +```` |
| 203 | + |
| 204 | +## See Also |
| 205 | + |
| 206 | +* [Custom Editor Tools]({%slug editor-custom-tools%}) |
| 207 | +* [Modify the ProseMirror Schema]({%slug editor-modify-default-schema%}) |
0 commit comments