Changes for page Create Application

Last modified by Thomas Mortagne on 2023/11/30 14:34

From version 12.1
edited by Thomas Mortagne
on 2022/07/05 14:36
Change comment: Install extension [org.xwiki.platform:xwiki-platform-appwithinminutes-ui/14.5]
To version 13.1
edited by Thomas Mortagne
on 2022/10/31 16:28
Change comment: Install extension [org.xwiki.platform:xwiki-platform-appwithinminutes-ui/14.9]

Summary

Details

Page properties
Content
... ... @@ -27,27 +27,29 @@
27 27   </ul>
28 28   </div>
29 29   <form action="$doc.getURL()" method="post" class="xform wizard-body">
30 - #locationPicker({
31 - 'id': 'app',
32 - 'title': {
33 - 'label': 'platform.appwithinminutes.appNameLabel',
34 - 'hint': 'platform.appwithinminutes.appNameHint',
35 - 'name': 'appName'
36 - },
37 - 'preview': {
38 - 'label': 'appWithinMinutes.createApp.location.label',
39 - 'hint': 'appWithinMinutes.createApp.location.hint'
40 - },
41 - 'parent': {
42 - 'label': 'appWithinMinutes.createApp.parent.label',
43 - 'hint': 'appWithinMinutes.createApp.parent.hint',
44 - 'name': 'appParentReference',
45 - 'reference': $doc.documentReference.wikiReference,
46 - 'placeholder': 'appWithinMinutes.createApp.parent.placeholder'
47 - }
48 - })
49 - <div class="appName-preview"></div>
50 - #appWizardFooter(1)
30 + <fieldset>
31 + #locationPicker({
32 + 'id': 'app',
33 + 'title': {
34 + 'label': 'platform.appwithinminutes.appNameLabel',
35 + 'hint': 'platform.appwithinminutes.appNameHint',
36 + 'name': 'appName'
37 + },
38 + 'preview': {
39 + 'label': 'appWithinMinutes.createApp.location.label',
40 + 'hint': 'appWithinMinutes.createApp.location.hint'
41 + },
42 + 'parent': {
43 + 'label': 'appWithinMinutes.createApp.parent.label',
44 + 'hint': 'appWithinMinutes.createApp.parent.hint',
45 + 'name': 'appParentReference',
46 + 'reference': $doc.documentReference.wikiReference,
47 + 'placeholder': 'appWithinMinutes.createApp.parent.placeholder'
48 + }
49 + })
50 + <div class="appName-preview"></div>
51 + #appWizardFooter(1)
52 + </fieldset>
51 51   </form>
52 52  #end
53 53  
XWiki.JavaScriptExtension[0]
Code
... ... @@ -1,9 +1,14 @@
1 -require(['jquery'], function($) {
1 +require(['jquery', 'xwiki-form-validation-async'], function($) {
2 2   var appNameInput = $('input[name="appName"]');
3 3   var appParentInput = $('input[name="appParentReference"]');
4 4   var preview = $('.appName-preview');
5 - var submitButton = $('#wizard-next').prop('disabled', true);
6 6  
6 + if (appNameInput.val() === '') {
7 + // We use a function instead of passing directly the promise because we want to avoid the "Uncaught (in promise)"
8 + // error. Basically, we want the rejected promise to be caught.
9 + appNameInput.validateAsync(() => Promise.reject(), 'awm');
10 + }
11 +
7 7   var errorMessage = appNameInput.closest('dd').prev('dt').find('.xErrorMsg');
8 8   if (!errorMessage.length) {
9 9   errorMessage = $(document.createElement('span')).addClass('xErrorMsg').hide().appendTo(errorMessage.addBack());
... ... @@ -11,8 +11,9 @@
11 11  
12 12   var toggleValidationError = function(message) {
13 13   if (message) {
14 - appNameInput.addClass('xErrorField').focus();
19 + appNameInput.addClass('xErrorField');
15 15   errorMessage.text(message).show();
21 + return Promise.reject();
16 16   } else {
17 17   appNameInput.removeClass('xErrorField');
18 18   errorMessage.hide();
... ... @@ -22,37 +22,24 @@
22 22   var updatePreview = function(content) {
23 23   preview.removeClass('loading').html(content);
24 24   var error = preview.find('.xErrorMsg');
25 - submitButton.prop('disabled', error.length);
26 - toggleValidationError(error.remove().text());
31 + return toggleValidationError(error.remove().text());
27 27   };
28 28  
29 29   var fetchPreviewUpdate = function() {
30 - if (appNameInput.val() == '') {
31 - updatePreview('<span class="xErrorMsg">$escapetool.javascript($services.localization.render("platform.appwithinminutes.appNameEmptyError"))</span>');
35 + if (appNameInput.val() === '') {
36 + return updatePreview('<span class="xErrorMsg">$escapetool.javascript($services.localization.render("platform.appwithinminutes.appNameEmptyError"))</span>');
32 32   } else {
33 33   preview.addClass('loading');
34 - $.get(XWiki.currentDocument.getURL('get'), submitButton.closest('form').serialize(), updatePreview);
39 + return $.get(XWiki.currentDocument.getURL('get'), appNameInput.closest('form').serialize()).then(updatePreview);
35 35   }
36 36   };
37 37  
38 - var previewTimeout;
39 - var schedulePreviewUpdate = function() {
40 - clearTimeout(previewTimeout);
41 - submitButton.prop('disabled', true);
42 - setTimeout(fetchPreviewUpdate, 500);
43 - };
44 -
45 - appNameInput.add(appParentInput)
46 - .on('input', schedulePreviewUpdate)
47 - .on('keyup', function(event) {
48 - // Show the error message if the user presses Enter before typing anything.
49 - if (event.which == 13 && appNameInput.val() == '' && !appNameInput.hasClass('xErrorField')) {
50 - fetchPreviewUpdate();
51 - }
52 - });
53 - submitButton.closest('form').on('submit', function (event) {
54 - if (appNameInput.hasClass('xErrorField')) {
55 - event.preventDefault();
43 + appNameInput.add(appParentInput).on('input', () => {
44 + appNameInput.validateAsync(fetchPreviewUpdate, 500, 'awm');
45 + }).on('keyup', function(event) {
46 + // Show the error message if the user presses Enter before typing anything.
47 + if (event.which === 13 && appNameInput.val() === '' && !appNameInput.hasClass('xErrorField')) {
48 + appNameInput.validateAsync(fetchPreviewUpdate, 'awm').catch(() => appNameInput.focus());
56 56   }
57 57   });
58 58  });