Skip to content

Commit a7542e0

Browse files
authored
Merge pull request #145 from mostafaznv/dev
feat: alert before unsaved changes #144
2 parents f064909 + ef8044b commit a7542e0

File tree

7 files changed

+121
-21
lines changed

7 files changed

+121
-21
lines changed

config/nova-ckeditor.php

+2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@
114114

115115
'force-paste-as-plain-text' => false,
116116

117+
'alert-before-unsaved-changes' => true,
118+
117119
'ui-language' => [
118120
'name' => 'en',
119121

dist/js/field.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/SUMMARY.md

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
* [Limit On Index](advanced-usage/ckeditor-field-options/limit-on-index.md)
2929
* [Content Language](advanced-usage/ckeditor-field-options/content-language.md)
3030
* [Force Paste as Plain Text](advanced-usage/ckeditor-field-options/force-page-as-plain-text.md)
31+
* [Alert Before Unsaved Changes](advanced-usage/ckeditor-field-options/alert-before-unsaved-changes.md)
3132
* [Text Part Language](advanced-usage/ckeditor-field-options/text-part-language.md)
3233
* [General HTML Support](advanced-usage/ckeditor-field-options/general-html-support.md)
3334
* [Group Items In Overflow Mode](advanced-usage/ckeditor-field-options/group-items-in-overflow-mode.md)
@@ -54,6 +55,7 @@
5455
* [Options](advanced-usage/configuration/toolbars/toolbar-1/options.md)
5556
* [Content Lang](advanced-usage/configuration/toolbars/toolbar-1/content-lang.md)
5657
* [Force Past as Plain Text](advanced-usage/configuration/toolbars/toolbar-1/force-page-as-plain-text.md)
58+
* [Alert Before Unsaved Changes](advanced-usage/configuration/toolbars/toolbar-1/alert-before-unsaved-changes.md)
5759
* [UI Language](advanced-usage/configuration/toolbars/toolbar-1/ui-language/README.md)
5860
* [UI Language Name](advanced-usage/configuration/toolbars/toolbar-1/ui-language/ui-language-name.md)
5961
* [UI Language Script](advanced-usage/configuration/toolbars/toolbar-1/ui-language/ui-language-script.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
description: alertBeforeUnsavedChanges
3+
---
4+
5+
# Alert Before Unsaved Changes
6+
7+
<table><thead><tr><th>Argument</th><th width="141">Type</th><th width="149" data-type="checkbox">Required</th><th>Default</th></tr></thead><tbody><tr><td>status</td><td>bool</td><td>false</td><td>true</td></tr></tbody></table>
8+
9+
This feature is enabled by default and triggers an alert if a user attempts to navigate away or refresh the page without saving CKEditor content, just like other form fields in Nova.
10+
11+
12+
13+
14+
15+
```php
16+
use Mostafaznv\NovaCkEditor\CkEditor;
17+
18+
class Article extends Resource
19+
{
20+
public function fields(Request $request): array
21+
{
22+
return [
23+
CkEditor::make(trans('Content'), 'content')
24+
->alertBeforeUnsavedChanges()
25+
];
26+
}
27+
}
28+
```
29+
30+
{% hint style="info" %}
31+
This feature has been available since <mark style="color:red;">v7.6.0</mark>
32+
{% endhint %}
33+
34+
35+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
description: toolbars.toolbar-1.alert-before-unsaved-changes
3+
---
4+
5+
# Alert Before Unsaved Changes
6+
7+
<table><thead><tr><th width="390">Property Name</th><th width="152.33333333333331">Type</th><th>Default</th></tr></thead><tbody><tr><td>toolbars.toolbar-1.alert-before-unsaved-changes</td><td>bool</td><td>true</td></tr></tbody></table>
8+
9+
This feature is enabled by default and triggers an alert if a user attempts to navigate away or refresh the page without saving CKEditor content, just like other form fields in Nova.
10+
11+
if you’d rather disable this behavior, simply set <mark style="color:red;">`toolbars.toolbar-1.alert-before-unsaved-changes`</mark> to <mark style="color:red;">`false`</mark> in the configuration.
12+
13+
14+
15+
{% hint style="info" %}
16+
This feature has been available since <mark style="color:red;">v7.6.0</mark>
17+
{% endhint %}
18+
19+
20+

resources/js/fields/editor-field.vue

+20-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ export default {
4040
components: {SnippetBrowser, MediaBrowser},
4141
data() {
4242
return {
43-
mounted: false
43+
mounted: false,
44+
fieldHasChanged: false
4445
}
4546
},
4647
computed: {
@@ -114,6 +115,10 @@ export default {
114115
priority: 'lowest'
115116
})
116117
118+
model.document.on('change:data', () => {
119+
this.fieldHasChanged = true
120+
})
121+
117122
editor.editing.view.change((writer) => {
118123
// set the height of the editor when editing
119124
if (this.currentField.height > 1) {
@@ -284,6 +289,8 @@ export default {
284289
285290
fill(formData) {
286291
if (this.currentlyIsVisible) {
292+
this.fieldHasChanged = false
293+
287294
formData.append(this.currentField.attribute, this.value || '')
288295
}
289296
},
@@ -323,6 +330,16 @@ export default {
323330
if (innerEditor?.length) {
324331
resizeObserver.observe(innerEditor[0])
325332
}
333+
},
334+
335+
alertOnUnchangedSaves() {
336+
if (this.currentField.alertBeforeUnsavedChanges) {
337+
window.addEventListener('beforeunload', (event) => {
338+
if (this.fieldHasChanged) {
339+
event.preventDefault()
340+
}
341+
})
342+
}
326343
}
327344
},
328345
created() {
@@ -336,6 +353,8 @@ export default {
336353
}
337354
338355
this.mounted = true
356+
357+
this.alertOnUnchangedSaves()
339358
},
340359
beforeUnmount() {
341360
this.destroyCkEditor()

src/CkEditor.php

+41-19
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ class CkEditor extends Field
7171
*/
7272
public bool $forcePasteAsPlainText;
7373

74+
/**
75+
* Alert Before Unsaved Changes
76+
*
77+
* @var bool
78+
*/
79+
public bool $alertBeforeUnsavedChanges;
80+
7481
/**
7582
* Text Part Language
7683
*
@@ -228,6 +235,19 @@ public function forcePasteAsPlainText(bool $status = true): self
228235
return $this;
229236
}
230237

238+
/**
239+
* Set Alert Before Unsaved Changes
240+
*
241+
* @param bool $status
242+
* @return $this
243+
*/
244+
public function alertBeforeUnsavedChanges(bool $status = true): self
245+
{
246+
$this->alertBeforeUnsavedChanges = $status;
247+
248+
return $this;
249+
}
250+
231251
/**
232252
* Set Text Part Language
233253
*
@@ -340,25 +360,26 @@ public function snippets(array $snippets): self
340360
public function jsonSerialize(): array
341361
{
342362
return array_merge(parent::jsonSerialize(), [
343-
'toolbarName' => $this->toolbarName,
344-
'snippetBrowser' => $this->snippetBrowser,
345-
'imageBrowser' => $this->imageBrowser,
346-
'videoBrowser' => $this->videoBrowser,
347-
'audioBrowser' => $this->audioBrowser,
348-
'fileBrowser' => $this->fileBrowser,
349-
'toolbar' => $this->toolbar,
350-
'toolbarOptions' => $this->toolbarOptions,
351-
'height' => $this->height,
352-
'indexLimit' => $this->indexLimit,
353-
'contentLanguage' => $this->contentLanguage,
354-
'forcePasteAsPlainText' => $this->forcePasteAsPlainText,
355-
'textPartLanguage' => $this->textPartLanguage,
356-
'htmlSupport' => $this->htmlSupport,
357-
'uiLanguage' => $this->uiLanguage,
358-
'shouldNotGroupWhenFull' => $this->shouldNotGroupWhenFull,
359-
'shouldShow' => $this->shouldBeExpanded(),
360-
'videoHasLaruploadTrait' => $this->videoHasLaruploadTrait(),
361-
'imageHasLaruploadTrait' => $this->imageHasLaruploadTrait()
363+
'toolbarName' => $this->toolbarName,
364+
'snippetBrowser' => $this->snippetBrowser,
365+
'imageBrowser' => $this->imageBrowser,
366+
'videoBrowser' => $this->videoBrowser,
367+
'audioBrowser' => $this->audioBrowser,
368+
'fileBrowser' => $this->fileBrowser,
369+
'toolbar' => $this->toolbar,
370+
'toolbarOptions' => $this->toolbarOptions,
371+
'height' => $this->height,
372+
'indexLimit' => $this->indexLimit,
373+
'contentLanguage' => $this->contentLanguage,
374+
'forcePasteAsPlainText' => $this->forcePasteAsPlainText,
375+
'alertBeforeUnsavedChanges' => $this->alertBeforeUnsavedChanges,
376+
'textPartLanguage' => $this->textPartLanguage,
377+
'htmlSupport' => $this->htmlSupport,
378+
'uiLanguage' => $this->uiLanguage,
379+
'shouldNotGroupWhenFull' => $this->shouldNotGroupWhenFull,
380+
'shouldShow' => $this->shouldBeExpanded(),
381+
'videoHasLaruploadTrait' => $this->videoHasLaruploadTrait(),
382+
'imageHasLaruploadTrait' => $this->imageHasLaruploadTrait()
362383
]);
363384
}
364385

@@ -443,6 +464,7 @@ private function prepareToolbar(string $toolbar, array $items = null): void
443464
$this->snippetBrowser = $this->prepareSnippets($toolbar['snippets']);
444465
$this->contentLanguage = $toolbar['content-lang'];
445466
$this->forcePasteAsPlainText = $toolbar['force-paste-as-plain-text'] ?? false;
467+
$this->alertBeforeUnsavedChanges = $toolbar['alert-before-unsaved-changes'] ?? true;
446468
$this->textPartLanguage = $toolbar['text-part-language'] ?? $defaultTextPartLanguage;
447469
$this->htmlSupport = $toolbar['html-support'] ?? $defaultHtmlSupport;
448470
$this->uiLanguage = $toolbar['ui-language']['name'] ?? 'en';

0 commit comments

Comments
 (0)