Skip to content

Commit 7f008cb

Browse files
authored
Merge pull request #9714 from gjulivan/development
Rich Text: add custom fonts and image from entity selection
2 parents 54ca981 + c6aacbb commit 7f008cb

File tree

5 files changed

+200
-56
lines changed

5 files changed

+200
-56
lines changed

content/en/docs/marketplace/platform-supported-content/widgets/richtext/_index.md

Lines changed: 200 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ The [Rich Text](https://marketplace.mendix.com/link/component/74889/) widget pro
3030
* Supports code highlight, which enables the user to insert code fragments and have a live preview with highlighted syntax
3131

3232
{{% alert color="info" %}}
33-
3433
Unlike Rich Text v3, this version no longer hosts the editor inside a sandboxed `iframe`. Thus, page styling will directly affect the rich text's styling.
35-
3634
{{% /alert %}}
3735

3836
## Configuration
@@ -46,55 +44,54 @@ To configure this widget, follow these steps:
4644
### General Tab
4745

4846
* **Data source**
49-
* **Value attribute** (required) – sets a String attribute to store the rich-text content
47+
* **Value attribute** (required) – sets a String attribute to store the rich-text content.
5048
* **General**
5149
* **Show label**
52-
* **Yes** – if selected, you can define the label caption
53-
* **Label caption** – defines the label caption of the widget that is displayed on the page
54-
* **No** (default) – if selected, there is no label for this widget on the page
55-
* **Enable status bar** display status bar on the bottom of the editor
50+
* **Yes** – if selected, you can define the label caption.
51+
* **Label caption** – defines the label caption of the widget that is displayed on the page.
52+
* **No** (default) – if selected, there is no label for this widget on the page.
53+
* **Enable status bar** display status bar on the bottom of the editor.
5654
* **Toolbar**
57-
* **Toolbar** display toolbar based on the selected location on the editor
55+
* **Toolbar** display toolbar based on the selected location on the editor.
5856
* **Basic** – if selected, the following menu will be shown:
59-
* | bold italic | numlist bullist | outdent indent | link | removeformat
57+
* bold italic | numlist bullist | outdent indent | link | removeformat
6058
* **Standard** – if selected, the following menu will be shown:
61-
* | undo redo | bold italic underlined | bullist numlist loweralphalist | outdent indent | ltr rtl | alignleft aligncenter alignjustify alignright | fontfamily fontsize forecolor backcolor | link image | blockquote codesample codeblock (view/edit)code | removeformat
59+
* undo redo | bold italic underlined | bullist numlist loweralphalist | outdent indent | ltr rtl | alignleft aligncenter alignjustify alignright | fontfamily fontsize forecolor backcolor | link image | blockquote codesample codeblock (view/edit)code, removeformat
6260
* **Full** – if selected, the following menu will be shown:
63-
* | undo redo | bold italic underlined strikethrough | superscript subscript | bullist numlist loweralphalist checklist | outdent indent | ltr rtl | alignleft aligncenter alignjustify alignright | fontfamily fontsize forecolor backcolor | link image video formula | heading | blockquote codesample codeblock (view/edit)code | removeformat
64-
* **Custom** – allows you to make your own menubar selection based on the **full** selection list
61+
* undo redo | bold italic underlined strikethrough | superscript subscript | bullist numlist loweralphalist checklist | outdent indent | ltr rtl, alignleft aligncenter alignjustify alignright | fontfamily fontsize forecolor backcolor | link image video formula | heading | blockquote codesample codeblock (view/edit)code | removeformat
62+
* **Custom** – allows you to make your own menubar selection based on the **full** selection list.
6563
* **Location**
66-
* **Sticky** – if selected, toolbar will be placed on the top of the editor and sticky position will apply upon scrolled
67-
* **Top** – if selected, toolbar will be placed on the top of the editor
68-
* **Bottom** – if selected, toolbar will be placed on the bottom of the editor
69-
* **Hide** – if selected, toolbar will be hidden or not shown
64+
* **Sticky** – if selected, toolbar will be placed on the top of the editor and sticky position will apply upon scrolled.
65+
* **Top** – if selected, toolbar will be placed on the top of the editor.
66+
* **Bottom** – if selected, toolbar will be placed on the bottom of the editor.
67+
* **Hide** – if selected, toolbar will be hidden or not shown.
7068

7169
* **Editable** – determines when user can edit content in the editor and when it is read-only.
70+
* **Read-only style** - determines the style of the rich text when set to read-only.
71+
For more information, see the [Editability Section](/refguide/common-widget-properties/#editability) in *Properties Common in the Page Editor*.
7272

73-
{{% alert color="info" %}}For more information, see [Editability Section](/refguide/common-widget-properties/#editability) in the *Studio Pro Guide*.{{% /alert %}}
74-
75-
* **Read-only style** - determines the style of the rich text when set to read-only
76-
77-
* **Visible** – determines if the widget is visible on the page
78-
79-
{{% alert color="info" %}}For more information, see [Visibility Section](/refguide/common-widget-properties/#visibility-properties) in the *Studio Pro Guide*.{{% /alert %}}
80-
73+
* **Visible** – determines if the widget is visible on the page.
74+
For more information, see the [Visibility Section](/refguide/common-widget-properties/#visibility-properties) in *Properties Common in the Page Editor*.
75+
8176
### Custom Toolbar Tab
8277

83-
* **Custom** – allows you to make your toolbar with customized options
78+
* **Custom** – allows you to make your toolbar with customized options.
8479
* **Toolbar group**
85-
* **Basic** (default) – if selected, you can select which of the following toolbar groups are available in the toolbar
86-
* **Edit history** - items: undo, redo
87-
* **Font style** - items: bold, italic, underline, strikethrough
88-
* **Font script** - items: superscript, subscript
89-
* **List** - items: bullist numlist loweralphalist checklist
90-
* **Indentation** - items: outdent, indent, ltr rtl
91-
* **Embedded media** - items: link, image, video, formula
92-
* **Alignment** - items: alignleft aligncenter alignjustify alignright
93-
* **Syntax** - items: blockquote, codesample, codeblock, (view/edit)code
94-
* **Font colors** - items: fontfamily, fontsize, forecolor, backcolor
95-
* **Content type** - items: header
96-
* **Removal** - items: clear
97-
* **Advanced** – if selected, you can configure buttons for different toolbar groups
80+
* **Basic** (default) – if selected, you can select which of the following toolbar groups are available in the toolbar:
81+
* **Edit history** - items: undo, redo.
82+
* **Font style** - items: bold, italic, underline, strikethrough.
83+
* **Font script** - items: superscript, subscript.
84+
* **List** - items: bullist numlist loweralphalist checklist.
85+
* **Indentation** - items: outdent, indent, ltr rtl.
86+
* **Embedded media** - items: link, image, video, formula.
87+
* **Alignment** - items: alignleft aligncenter alignjustify alignright.
88+
* **Syntax** - items: blockquote, codesample, codeblock, (view/edit)code.
89+
* **Font colors** - items: fontfamily, fontsize, forecolor, backcolor.
90+
* **Content type** - items: header.
91+
* **View** - items: fullscreen.
92+
* **Removal** - items: clear.
93+
* **Table** - items: table.
94+
* **Advanced** – if selected, you can configure buttons for different toolbar groups:
9895

9996
{{% alert color="info" %}}All the toolbar groups that you configure will be available in the toolbar. With vertical bars or separator options ("|"), you can separate different toolbar groups.{{% /alert %}}
10097

@@ -105,31 +102,178 @@ To configure this widget, follow these steps:
105102

106103
### Dimensions Tab
107104

108-
* **Width unit** – the width of the widget
109-
* **Percentage** – specifies the width in relation to the rest of the elements on the page
110-
* **Pixels** – specifies the width in pixels
111-
* **Width** – used as an appropriate CSS value
112-
* **Height unit** – the height of the widget
113-
* **Percentage of width** – specifies the height in relation to the width
114-
* **Pixels** – specifies the height in pixels
115-
* **Percentage of parent** – specifies the width in relation to the rest of the elements on the page
116-
* **Height** – used as an appropriate CSS value
117-
* **Minimum height** – applicable if height is relative to parent's percentage
105+
* **Width unit** – the width of the widget.
106+
* **Percentage** – specifies the width in relation to the rest of the elements on the page.
107+
* **Pixels** – specifies the width in pixels.
108+
* **Width** – used as an appropriate CSS value.
109+
* **Height unit** – the height of the widget.
110+
* **Percentage of width** – specifies the height in relation to the width.
111+
* **Pixels** – specifies the height in pixels.
112+
* **Percentage of parent** – specifies the width in relation to the rest of the elements on the page.
113+
* **Height** – used as an appropriate CSS value.
114+
* **Minimum height** – applicable if height is relative to parent's percentage.
118115

119116
### Events Tab
120117

121-
* **On change** – specifies an action to execute when the user changes the value of the editor
122-
* **On change type** - specifies which type of event that will trigger the on change action
123-
* **When user leaves input field** - if selected, an on change action will be triggered when user moves focus out of the editor
124-
* **While user is entering data** - if selected, an on change action will be triggered each time a data change occurs
125-
* **On enter** – specifies an action to execute when the user focuses on the editor
126-
* **On leave** – specifies an action to execute when the user move focus out of the editor
127-
* **On load** – specifies an action to execute after the editor is fully loaded in the DOM
118+
* **On change** – specifies an action to execute when the user changes the value of the editor.
119+
* **On change type** - specifies which type of event that will trigger the on change action.
120+
* **When user leaves input field** - if selected, an on change action will be triggered when user moves focus out of the editor.
121+
* **While user is entering data** - if selected, an on change action will be triggered each time a data change occurs.
122+
* **On enter** – specifies an action to execute when the user focuses on the editor.
123+
* **On leave** – specifies an action to execute when the user move focus out of the editor.
124+
* **On load** – specifies an action to execute after the editor is fully loaded in the DOM.
128125

129126
### Advanced Tab
130127

131-
* **Enable spell checking** – configures to use the browser’s native spell checker
128+
* **Enable spell checking** – configures to use the browser’s native spell checker.
129+
* **Custom fonts** – configures extra fonts selection for the font family.
130+
* **Selectable images** – configures image entity source to allow rich text to use images from entity instead of base64 string.
131+
* **Enable default upload** – if enabled, it will keep the current image upload method using base64 string, otherwise it is hidden (default value: **true**).
132132

133133
### Common Tab
134134

135135
For more information, see [Common Section](/refguide/common-widget-properties/#common-properties) in *Properties Common in the Page Editor*.
136+
137+
## Advanced Configuration
138+
139+
### Custom Fonts
140+
141+
This advance configuration allows you to add extra font list to the font family selection in Rich Text widget.
142+
143+
#### Prerequisites
144+
145+
Before use, please ensure you meet the following prerequisites:
146+
147+
* Prior to adding a new font, the font files and font family have to already be included in your project. To add font files into the project, you can put the font files inside your styles/web directory.
148+
* Define font family in styling. You will need to define the new font by adding the font face custom styling.
149+
150+
```css
151+
@font-face {
152+
font-family: 'Your-font-family-name';
153+
src: url('YourFontFile.ttf') format('truetype');
154+
font-weight: 100;
155+
font-style: normal;
156+
}
157+
```
158+
159+
#### Adding a Custom Font
160+
161+
{{% alert color="info" %}}
162+
This feature is available from Rich Text version 4.7.0 and above.
163+
{{% /alert %}}
164+
165+
To add a new custom font, simply click the **Advanced** tab and click new on custom font:
166+
167+
* **Font name** – this is the font name that will be use to display the font on font-family selection in Rich Text toolbar.
168+
* **Font style** – this is the font-family declaration that you have set previously in font-face styling.
169+
170+
#### Display Custom Font with Correct Styling in the Toolbar
171+
172+
**Font name variable** is an optional configuration that user can employ to display custom fonts, in their own styling, on the font-family toolbar selection.
173+
174+
The new font name will be display in the toolbar with data-value attribute as `data-value="your-font-name"`. The name will be derived from **Font name** configuration by set it to lower case, and replace all spaces (" ") with dashes ("-"). You can use this custom styling to display it correctly in the toolbar:
175+
176+
```css
177+
.widget-rich-text .ql-toolbar [data-value=your-font-name]:before {
178+
font-family: 'Your-font-family-name';
179+
}
180+
```
181+
182+
### Image From Entity
183+
184+
{{% alert color="info" %}}
185+
This feature is available from Rich Text version 4.8.0 and above.
186+
{{% /alert %}}
187+
188+
The default image upload and selection method of Rich Text is to use base64 string as the image source. This has found to be troublesome if the image size is too large that causes the string value attribute to be big. By using image source from entity, Rich Text will use the image URL instead of base64.
189+
190+
#### Using File Uploader Widget
191+
192+
The default and recommended way of uploading and selecting images from entity in Rich Text widget is to use [File Uploader](/appstore/modules/file-uploader/) module.
193+
194+
##### Prerequisites
195+
196+
Entity that being used for Rich Text data source value attribute have to use FileUploadContext entity generalization.
197+
198+
{{< figure src="/attachments/appstore/platform-supported-content/widgets/rich-text/entity-with-file-upload-context.png" alt="Rich text entity with FileUploadContext generalization" >}}
199+
200+
##### Configuration
201+
202+
Use following configuration information to set up the file uploader widget:
203+
204+
1. Set selectable images:
205+
1. Rich text needs to know the source of image entity to be display. Click the **Advanced** tab > **Selectable images**, then choose association to **UploadedImage_FileUploadContext/UploadedImage** entity.
206+
1. By selecting this, Rich Text will display a dropzone for image upload widget.
207+
208+
1. Configure the image upload widget:
209+
1. Drag and drop file uploader widget to the available image upload dropzone underneath Rich Text widget.
210+
1. Open the file uploader widget configuration and select **Images** as the **Upload mode**.
211+
1. On the **Advanced** tab of file uploader widget, set **Enable custom buttons** to **Yes** and add a custom buttons.
212+
1. Set **Default file action** to **Yes** on the custom button and call the [nanoflow to select images](#configuring-image-selection-nanoflow) as the action.
213+
214+
#### Using Another Widget as Image Selector
215+
216+
User can also configure to use another widget as the image selector for Rich Text. This widget have to has access to the System.Image object.
217+
218+
##### Prerequisites
219+
220+
To use another widget as an image selector for Rich Text, ensure you meet the following prerequisites:
221+
222+
* Entity that being used for Rich Text data source value attribute have to use has association to System.Image entity:
223+
224+
{{< figure src="/attachments/appstore/platform-supported-content/widgets/rich-text/entity-with-system-image.png" alt="Rich text entity with FileUploadContext generalization" >}}
225+
226+
* The custom widget needs to have access to the System.Image object and able to call nanoflow action when image being selected.
227+
* It is not mandatory that the custom widget have upload image functionality (for example, it is also possible to use [Gallery](/appstore/modules/gallery/) and [Image](/appstore/widgets/image/) widgets with onClick), because the Rich Text widget only needs the selection action call.
228+
229+
##### Configuration
230+
231+
Configuration instructions for using another widget as an image selector are as follows:
232+
233+
1. Selectable images:
234+
1. Rich text needs to know the source of image entity to be display. So, after clicking **Advanced** > **Selectable images**, choose the association to the **System.Image** entity.
235+
1. By selecting this, Rich Text will display a dropzone for image upload widget.
236+
237+
1. Configuring the image upload widget:
238+
1. Drag and drop the custom widget to the available image upload dropzone underneath Rich Text widget.
239+
1. Use the same **System.Image** association as the datasource.
240+
1. Set the action to call the [nanoflow to select images](#configuring-image-selection-nanoflow) as necessary.
241+
242+
#### Configuring Image Selection Nanoflow
243+
244+
The nanoflow is needed to trigger image object selection and returning the flow back to Rich Text widget:
245+
246+
{{< figure src="/attachments/appstore/platform-supported-content/widgets/rich-text/image-selection-nanoflow.png" alt="Image selection nanoflow" >}}
247+
248+
To configure the nanoflow, do the following:
249+
250+
1. Set the nanoflow parameter:
251+
1. The nanoflow needs to have access to the **System.Image** entity. Set this as the parameter.
252+
1. In case of using File Uploader, this should be automatically set up when creating the nanoflow from custom action button.
253+
254+
1. Get the object GUID:
255+
1. The first step of the nanoflow is to get the GUID from the image object.
256+
1. Set call to JavaScript action GetGuid provided by [Nanoflow Commons](/appstore/modules/nanoflow-commons/) module.
257+
258+
1. Trigger image selection JavaScript (required to pass the GUID of the image object back to Rich Text):
259+
1. Create a new JavaScript action and add a string parameter.
260+
1. In this example, we will name the parameter *fileGuid* and *selectImage* as the Javascript action:
261+
262+
{{< figure src="/attachments/appstore/platform-supported-content/widgets/rich-text/js-action-setup.png" alt="Javascript action configuration" >}}
263+
264+
Use the following code in the JavaScript action:
265+
266+
```Javascript
267+
export async function selectImage(fileGuid) {
268+
// BEGIN USER CODE
269+
const img = {
270+
id: fileGuid,
271+
url: mx.data.getDocumentUrl(fileGuid, Date.now(), false)
272+
}
273+
const customEvent = new CustomEvent("imageSelected", { bubbles: true, detail: img });
274+
window.getSelection().anchorNode.dispatchEvent(customEvent);
275+
// END USER CODE
276+
}
277+
```
278+
279+
This code will trigger a new event called **imageSelected** and bubble up the event back to Rich Text widget to continue the flow. The user then can use the **image id** instead of **base64 string** as the image source.

0 commit comments

Comments
 (0)