diff --git a/src/addons/calendar/pages/edit-event/edit-event.page.ts b/src/addons/calendar/pages/edit-event/edit-event.page.ts index 41aad7974..bcb25057c 100644 --- a/src/addons/calendar/pages/edit-event/edit-event.page.ts +++ b/src/addons/calendar/pages/edit-event/edit-event.page.ts @@ -43,6 +43,7 @@ import { AddonCalendarOfflineEventDBRecord } from '../../services/database/calen import { CoreError } from '@classes/errors/error'; import { CoreNavigator } from '@services/navigator'; import { CanLeave } from '@guards/can-leave'; +import { CoreForms } from '@singletons/form'; /** * Page that displays a form to create/edit an event. @@ -518,7 +519,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { const result = await AddonCalendar.submitEvent(this.eventId, data); event = result.event; - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, result.sent, this.currentSite.getId()); + CoreForms.triggerFormSubmittedEvent(this.formElement, result.sent, this.currentSite.getId()); if (result.sent) { // Event created or edited, invalidate right days & months. @@ -588,7 +589,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { try { await AddonCalendarOffline.deleteEvent(this.eventId!); - CoreDomUtils.triggerFormCancelledEvent(this.formElement, this.currentSite.getId()); + CoreForms.triggerFormCancelledEvent(this.formElement, this.currentSite.getId()); this.returnToList(); } catch { @@ -611,7 +612,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { await CoreDomUtils.showConfirm(Translate.instant('core.confirmcanceledit')); } - CoreDomUtils.triggerFormCancelledEvent(this.formElement, this.currentSite.getId()); + CoreForms.triggerFormCancelledEvent(this.formElement, this.currentSite.getId()); return true; } diff --git a/src/addons/mod/assign/components/edit-feedback-modal/edit-feedback-modal.ts b/src/addons/mod/assign/components/edit-feedback-modal/edit-feedback-modal.ts index ffcee4261..6e48aab65 100644 --- a/src/addons/mod/assign/components/edit-feedback-modal/edit-feedback-modal.ts +++ b/src/addons/mod/assign/components/edit-feedback-modal/edit-feedback-modal.ts @@ -15,6 +15,7 @@ import { Component, Input, ViewChild, ElementRef } from '@angular/core'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; +import { CoreFormFields, CoreForms } from '@singletons/form'; import { CoreUtils } from '@services/utils/utils'; import { ModalController, Translate } from '@singletons'; import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../../services/assign'; @@ -47,7 +48,7 @@ export class AddonModAssignEditFeedbackModalComponent { await CoreDomUtils.showConfirm(Translate.instant('core.confirmcanceledit')); } - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); ModalController.dismiss(); } @@ -61,7 +62,7 @@ export class AddonModAssignEditFeedbackModalComponent { e.preventDefault(); e.stopPropagation(); - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); // Close the modal, sending the input data. ModalController.dismiss(this.getInputData()); @@ -72,8 +73,8 @@ export class AddonModAssignEditFeedbackModalComponent { * * @return Object with the data. */ - protected getInputData(): Record { - return CoreDomUtils.getDataFromForm(document.forms['addon-mod_assign-edit-feedback-form']); + protected getInputData(): CoreFormFields { + return CoreForms.getDataFromForm(document.forms['addon-mod_assign-edit-feedback-form']); } /** diff --git a/src/addons/mod/assign/pages/edit/edit.ts b/src/addons/mod/assign/pages/edit/edit.ts index a85013e36..1a8aa7507 100644 --- a/src/addons/mod/assign/pages/edit/edit.ts +++ b/src/addons/mod/assign/pages/edit/edit.ts @@ -21,6 +21,7 @@ import { CoreNavigator } from '@services/navigator'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSync } from '@services/sync'; import { CoreDomUtils } from '@services/utils/dom'; +import { CoreFormFields, CoreForms } from '@singletons/form'; import { Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { @@ -105,7 +106,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy, CanLeave { // Nothing has changed or user confirmed to leave. Clear temporary data from plugins. AddonModAssignHelper.clearSubmissionPluginTmpData(this.assign!, this.userSubmission, this.getInputData()); - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); return true; } @@ -199,8 +200,8 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy, CanLeave { * * @return Input data. */ - protected getInputData(): Record { - return CoreDomUtils.getDataFromForm(document.forms['addon-mod_assign-edit-form']); + protected getInputData(): CoreFormFields { + return CoreForms.getDataFromForm(document.forms['addon-mod_assign-edit-form']); } /** @@ -234,7 +235,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy, CanLeave { * @param inputData The input data. * @return Promise resolved with the data to submit. */ - protected prepareSubmissionData(inputData: Record): Promise { + protected prepareSubmissionData(inputData: CoreFormFields): Promise { // If there's offline data, always save it in offline. this.saveOffline = this.hasOffline; @@ -353,7 +354,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy, CanLeave { } // Submission saved, trigger events. - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, sent, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormSubmittedEvent(this.formElement, sent, CoreSites.getCurrentSiteId()); CoreEvents.trigger( AddonModAssignProvider.SUBMISSION_SAVED_EVENT, diff --git a/src/addons/mod/assign/services/assign-helper.ts b/src/addons/mod/assign/services/assign-helper.ts index c71681b36..b4bbb4eb7 100644 --- a/src/addons/mod/assign/services/assign-helper.ts +++ b/src/addons/mod/assign/services/assign-helper.ts @@ -35,6 +35,7 @@ import { CoreGroups } from '@services/groups'; import { AddonModAssignSubmissionDelegate } from './submission-delegate'; import { AddonModAssignFeedbackDelegate } from './feedback-delegate'; import { makeSingleton } from '@singletons'; +import { CoreFormFields } from '@singletons/form'; /** * Service that provides some helper functions for assign. @@ -88,7 +89,7 @@ export class AddonModAssignHelperProvider { clearSubmissionPluginTmpData( assign: AddonModAssignAssign, submission: AddonModAssignSubmission | undefined, - inputData: Record, + inputData: CoreFormFields, ): void { if (!submission) { return; @@ -362,7 +363,7 @@ export class AddonModAssignHelperProvider { async getSubmissionSizeForEdit( assign: AddonModAssignAssign, submission: AddonModAssignSubmission, - inputData: Record, + inputData: CoreFormFields, ): Promise { let totalSize = 0; @@ -537,7 +538,7 @@ export class AddonModAssignHelperProvider { async hasSubmissionDataChanged( assign: AddonModAssignAssign, submission: AddonModAssignSubmission | undefined, - inputData: Record, + inputData: CoreFormFields, ): Promise { if (!submission) { return false; @@ -580,7 +581,7 @@ export class AddonModAssignHelperProvider { siteId?: string, ): Promise { - const pluginData: Record = {}; + const pluginData: CoreFormFields = {}; const promises = feedback.plugins ? feedback.plugins.map((plugin) => AddonModAssignFeedbackDelegate.preparePluginFeedbackData(assignId, userId, plugin, pluginData, siteId)) @@ -603,7 +604,7 @@ export class AddonModAssignHelperProvider { async prepareSubmissionPluginData( assign: AddonModAssignAssign, submission: AddonModAssignSubmission | undefined, - inputData: Record, + inputData: CoreFormFields, offline = false, ): Promise { diff --git a/src/addons/mod/assign/services/assign.ts b/src/addons/mod/assign/services/assign.ts index 237703ab4..aa53f5f4f 100644 --- a/src/addons/mod/assign/services/assign.ts +++ b/src/addons/mod/assign/services/assign.ts @@ -33,6 +33,7 @@ import { CoreComments } from '@features/comments/services/comments'; import { AddonModAssignSubmissionFormatted } from './assign-helper'; import { CoreWSError } from '@classes/errors/wserror'; import { AddonModAssignAutoSyncData, AddonModAssignManualSyncData, AddonModAssignSyncProvider } from './assign-sync'; +import { CoreFormFields } from '@singletons/form'; const ROOT_CACHE_KEY = 'mmaModAssign:'; @@ -1808,7 +1809,7 @@ type AddonModAssignSaveSubmissionWSParams = { /** * All subplugins will decide what to add here. */ -export type AddonModAssignSavePluginData = Record; +export type AddonModAssignSavePluginData = CoreFormFields; /** * Params of mod_assign_submit_for_grading WS. diff --git a/src/addons/mod/assign/services/feedback-delegate.ts b/src/addons/mod/assign/services/feedback-delegate.ts index 604b7298a..8c9951877 100644 --- a/src/addons/mod/assign/services/feedback-delegate.ts +++ b/src/addons/mod/assign/services/feedback-delegate.ts @@ -19,6 +19,7 @@ import { AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin, A import { makeSingleton } from '@singletons'; import { CoreWSExternalFile } from '@services/ws'; import { AddonModAssignSubmissionFormatted } from './assign-helper'; +import { CoreFormFields } from '@singletons/form'; /** * Interface that all feedback handlers must implement. @@ -61,7 +62,7 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler { assignId: number, userId: number, siteId?: string, - ): Record | Promise | undefined> | undefined; + ): CoreFormFields | Promise | undefined; /** * Get files used by this plugin. @@ -102,7 +103,7 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler { assign: AddonModAssignAssign, submission: AddonModAssignSubmission, plugin: AddonModAssignPlugin, - inputData: Record, + inputData: CoreFormFields, userId: number, ): boolean | Promise; @@ -165,7 +166,7 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler { assignId: number, userId: number, plugin: AddonModAssignPlugin, - data: Record, + data: CoreFormFields, siteId?: string, ): void | Promise; } @@ -276,7 +277,7 @@ export class AddonModAssignFeedbackDelegateService extends CoreDelegate, + inputData: CoreFormFields, userId: number, ): Promise { return await this.executeFunctionOnEnabled( @@ -371,7 +372,7 @@ export class AddonModAssignFeedbackDelegateService extends CoreDelegate, + inputData: CoreFormFields, siteId?: string, ): Promise { return await this.executeFunctionOnEnabled( diff --git a/src/addons/mod/assign/services/submission-delegate.ts b/src/addons/mod/assign/services/submission-delegate.ts index b7a62a797..a58da6eac 100644 --- a/src/addons/mod/assign/services/submission-delegate.ts +++ b/src/addons/mod/assign/services/submission-delegate.ts @@ -19,6 +19,7 @@ import { AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin, A import { makeSingleton } from '@singletons'; import { CoreWSExternalFile } from '@services/ws'; import { AddonModAssignSubmissionsDBRecordFormatted } from './assign-offline'; +import { CoreFormFields } from '@singletons/form'; /** * Interface that all submission handlers must implement. @@ -70,7 +71,7 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { assign: AddonModAssignAssign, submission: AddonModAssignSubmission, plugin: AddonModAssignPlugin, - inputData: Record, + inputData: CoreFormFields, ): void; /** @@ -173,7 +174,7 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { assign: AddonModAssignAssign, submission: AddonModAssignSubmission, plugin: AddonModAssignPlugin, - inputData: Record, + inputData: CoreFormFields, ): number | Promise; /** @@ -189,7 +190,7 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { assign: AddonModAssignAssign, submission: AddonModAssignSubmission, plugin: AddonModAssignPlugin, - inputData: Record, + inputData: CoreFormFields, ): boolean | Promise; /** @@ -233,7 +234,7 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { assign: AddonModAssignAssign, submission: AddonModAssignSubmission, plugin: AddonModAssignPlugin, - inputData: Record, + inputData: CoreFormFields, pluginData: AddonModAssignSavePluginData, offline?: boolean, userId?: number, @@ -304,7 +305,7 @@ export class AddonModAssignSubmissionDelegateService extends CoreDelegate, + inputData: CoreFormFields, ): void { return this.executeFunctionOnEnabled(plugin.type, 'clearTmpData', [assign, submission, plugin, inputData]); } @@ -424,7 +425,7 @@ export class AddonModAssignSubmissionDelegateService extends CoreDelegate, + inputData: CoreFormFields, ): Promise { return await this.executeFunctionOnEnabled( plugin.type, @@ -446,7 +447,7 @@ export class AddonModAssignSubmissionDelegateService extends CoreDelegate, + inputData: CoreFormFields, ): Promise { return await this.executeFunctionOnEnabled( plugin.type, @@ -521,7 +522,7 @@ export class AddonModAssignSubmissionDelegateService extends CoreDelegate, + inputData: CoreFormFields, pluginData: AddonModAssignSavePluginData, offline?: boolean, userId?: number, diff --git a/src/addons/mod/forum/components/edit-post/edit-post.ts b/src/addons/mod/forum/components/edit-post/edit-post.ts index 958db0662..1070e5c4b 100644 --- a/src/addons/mod/forum/components/edit-post/edit-post.ts +++ b/src/addons/mod/forum/components/edit-post/edit-post.ts @@ -20,6 +20,7 @@ import { CoreDomUtils } from '@services/utils/dom'; import { ModalController, Translate } from '@singletons'; import { AddonModForumData, AddonModForumPost, AddonModForumReply } from '@addons/mod/forum/services/forum'; import { AddonModForumHelper } from '@addons/mod/forum/services/forum-helper'; +import { CoreForms } from '@singletons/form'; /** * Page that displays a form to edit discussion post. @@ -93,9 +94,9 @@ export class AddonModForumEditPostComponent implements OnInit { } if (data) { - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); } else { - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); } ModalController.dismiss(data); diff --git a/src/addons/mod/forum/components/post/post.ts b/src/addons/mod/forum/components/post/post.ts index 3e244193b..e86cfd393 100644 --- a/src/addons/mod/forum/components/post/post.ts +++ b/src/addons/mod/forum/components/post/post.ts @@ -53,6 +53,7 @@ import { CoreUtils } from '@services/utils/utils'; import { AddonModForumPostOptionsMenuComponent } from '../post-options-menu/post-options-menu'; import { AddonModForumEditPostComponent } from '../edit-post/edit-post'; import { CoreRatingInfo } from '@features/rating/services/rating'; +import { CoreForms } from '@singletons/form'; /** * Components that shows a discussion post, its attachments and the action buttons allowed (reply, etc.). @@ -129,7 +130,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges ngOnChanges(changes: {[name: string]: SimpleChange}): void { if (changes.leavingPage && this.leavingPage) { // Download all courses is enabled now, initialize it. - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); } } @@ -498,7 +499,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges this.onPostChange.emit(); - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, sent, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormSubmittedEvent(this.formElement, sent, CoreSites.getCurrentSiteId()); if (this.syncId) { CoreSync.unblockOperation(AddonModForumProvider.COMPONENT, this.syncId); @@ -520,7 +521,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges // Reset data. this.setReplyFormData(); - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); if (this.syncId) { CoreSync.unblockOperation(AddonModForumProvider.COMPONENT, this.syncId); diff --git a/src/addons/mod/forum/pages/new-discussion/new-discussion.page.ts b/src/addons/mod/forum/pages/new-discussion/new-discussion.page.ts index 8ff69c794..390672083 100644 --- a/src/addons/mod/forum/pages/new-discussion/new-discussion.page.ts +++ b/src/addons/mod/forum/pages/new-discussion/new-discussion.page.ts @@ -39,6 +39,7 @@ import { CoreFileUploader } from '@features/fileuploader/services/fileuploader'; import { CoreTextUtils } from '@services/utils/text'; import { CanLeave } from '@guards/can-leave'; import { CoreSplitViewComponent } from '@components/split-view/split-view'; +import { CoreForms } from '@singletons/form'; type NewDiscussionData = { subject: string; @@ -519,7 +520,7 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy, CanLea CoreDomUtils.showErrorModalDefault(null, 'addon.mod_forum.errorposttoallgroups', true); } - CoreDomUtils.triggerFormSubmittedEvent( + CoreForms.triggerFormSubmittedEvent( this.formElement, !!discussionIds, CoreSites.getCurrentSiteId(), @@ -551,7 +552,7 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy, CanLea await Promise.all(promises); - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); this.returnToDiscussions(); } catch (error) { @@ -585,7 +586,7 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy, CanLea CoreFileUploader.clearTmpFiles(this.newDiscussion.files); if (this.formElement) { - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); } return true; diff --git a/src/addons/mod/lesson/components/index/index.ts b/src/addons/mod/lesson/components/index/index.ts index 125d6f009..25c9c6400 100644 --- a/src/addons/mod/lesson/components/index/index.ts +++ b/src/addons/mod/lesson/components/index/index.ts @@ -24,6 +24,7 @@ import { IonContent, IonInput } from '@ionic/angular'; import { CoreGroupInfo, CoreGroups } from '@services/groups'; import { CoreNavigator } from '@services/navigator'; import { CoreDomUtils } from '@services/utils/dom'; +import { CoreForms } from '@singletons/form'; import { CoreTextUtils } from '@services/utils/text'; import { CoreTimeUtils } from '@services/utils/time'; import { CoreUtils } from '@services/utils/utils'; @@ -645,7 +646,7 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo this.refreshIcon = CoreConstants.ICON_REFRESH; this.syncIcon = CoreConstants.ICON_SYNC; - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, true, this.siteId); + CoreForms.triggerFormSubmittedEvent(this.formElement, true, this.siteId); } } diff --git a/src/addons/mod/lesson/components/password-modal/password-modal.ts b/src/addons/mod/lesson/components/password-modal/password-modal.ts index 871316793..a163b454e 100644 --- a/src/addons/mod/lesson/components/password-modal/password-modal.ts +++ b/src/addons/mod/lesson/components/password-modal/password-modal.ts @@ -16,7 +16,7 @@ import { Component, ViewChild, ElementRef } from '@angular/core'; import { IonInput } from '@ionic/angular'; import { CoreSites } from '@services/sites'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CoreForms } from '@singletons/form'; import { ModalController } from '@singletons'; /** @@ -40,7 +40,7 @@ export class AddonModLessonPasswordModalComponent { e.preventDefault(); e.stopPropagation(); - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); ModalController.dismiss(password.value); } @@ -49,7 +49,7 @@ export class AddonModLessonPasswordModalComponent { * Close modal. */ closeModal(): void { - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); ModalController.dismiss(); } diff --git a/src/addons/mod/lesson/pages/player/player.page.ts b/src/addons/mod/lesson/pages/player/player.page.ts index e6d39e5d8..f030eb7f3 100644 --- a/src/addons/mod/lesson/pages/player/player.page.ts +++ b/src/addons/mod/lesson/pages/player/player.page.ts @@ -53,6 +53,7 @@ import { } from '../../services/lesson-helper'; import { AddonModLessonOffline } from '../../services/lesson-offline'; import { AddonModLessonSync } from '../../services/lesson-sync'; +import { CoreFormFields, CoreForms } from '@singletons/form'; /** * Page that allows attempting and reviewing a lesson. @@ -90,7 +91,7 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy, CanLeave { processDataButtons: ProcessDataButton[] = []; // Buttons to display after processing a page. loaded?: boolean; // Whether data has been loaded. displayMenu?: boolean; // Whether the lesson menu should be displayed. - originalData?: Record; // Original question data. It is used to check if data has changed. + originalData?: CoreFormFields; // Original question data. It is used to check if data has changed. reviewPageId?: number; // Page to open if the user wants to review the attempt. courseId!: number; // The course ID the lesson belongs to. lessonPages?: AddonModLessonPageWSData[]; // Lesson pages (for the lesson menu). @@ -164,7 +165,7 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy, CanLeave { } } - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); return true; } @@ -605,7 +606,7 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy, CanLeave { * @param formSubmitted Whether a form was submitted. * @return Promise resolved when done. */ - protected async processPage(data: Record, formSubmitted?: boolean): Promise { + protected async processPage(data: CoreFormFields, formSubmitted?: boolean): Promise { this.loaded = false; const options: AddonModLessonProcessPageOptions = { @@ -630,7 +631,7 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy, CanLeave { ); if (formSubmitted) { - CoreDomUtils.triggerFormSubmittedEvent( + CoreForms.triggerFormSubmittedEvent( this.formElement, result.sent, CoreSites.getCurrentSiteId(), diff --git a/src/addons/mod/lesson/services/lesson-helper.ts b/src/addons/mod/lesson/services/lesson-helper.ts index f7035f99d..cebbb9f88 100644 --- a/src/addons/mod/lesson/services/lesson-helper.ts +++ b/src/addons/mod/lesson/services/lesson-helper.ts @@ -16,6 +16,7 @@ import { Injectable } from '@angular/core'; import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; import { CoreDomUtils } from '@services/utils/dom'; +import { CoreFormFields } from '@singletons/form'; import { CoreTextUtils } from '@services/utils/text'; import { CoreTimeUtils } from '@services/utils/time'; import { makeSingleton, Translate } from '@singletons'; @@ -550,7 +551,7 @@ export class AddonModLessonHelperProvider { * @param data Data to prepare. * @return Data to send. */ - prepareQuestionData(question: AddonModLessonQuestion, data: Record): Record { + prepareQuestionData(question: AddonModLessonQuestion, data: CoreFormFields): CoreFormFields { if (question.template == 'essay') { const textarea = ( question).textarea; diff --git a/src/addons/mod/lesson/services/lesson-offline.ts b/src/addons/mod/lesson/services/lesson-offline.ts index 41b7f836a..4a4297372 100644 --- a/src/addons/mod/lesson/services/lesson-offline.ts +++ b/src/addons/mod/lesson/services/lesson-offline.ts @@ -14,6 +14,7 @@ import { Injectable } from '@angular/core'; import { CoreSites } from '@services/sites'; +import { CoreFormFields } from '@singletons/form'; import { CoreTextUtils } from '@services/utils/text'; import { CoreTimeUtils } from '@services/utils/time'; import { CoreUtils } from '@services/utils/utils'; @@ -484,7 +485,7 @@ export class AddonModLessonOfflineProvider { courseId: number, retake: number, page: AddonModLessonPageWSData, - data: Record, + data: CoreFormFields, newPageId: number, answerId?: number, correct?: boolean, @@ -552,7 +553,7 @@ export const AddonModLessonOffline = makeSingleton(AddonModLessonOfflineProvider * Attempt DB record with parsed data. */ export type AddonModLessonPageAttemptRecord = Omit & { - data: Record | null; + data: CoreFormFields | null; useranswer: unknown | null; }; diff --git a/src/addons/mod/quiz/components/preflight-modal/preflight-modal.ts b/src/addons/mod/quiz/components/preflight-modal/preflight-modal.ts index 5a9dd4c12..2bc91c409 100644 --- a/src/addons/mod/quiz/components/preflight-modal/preflight-modal.ts +++ b/src/addons/mod/quiz/components/preflight-modal/preflight-modal.ts @@ -18,6 +18,7 @@ import { IonContent } from '@ionic/angular'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; +import { CoreForms } from '@singletons/form'; import { ModalController, Translate } from '@singletons'; import { AddonModQuizAccessRuleDelegate } from '../../services/access-rules-delegate'; import { AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '../../services/quiz'; @@ -126,7 +127,7 @@ export class AddonModQuizPreflightModalComponent implements OnInit { CoreDomUtils.showErrorModal('core.errorinvalidform', true); } } else { - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, false, this.siteId); + CoreForms.triggerFormSubmittedEvent(this.formElement, false, this.siteId); ModalController.dismiss(this.preflightForm.value); } @@ -136,7 +137,7 @@ export class AddonModQuizPreflightModalComponent implements OnInit { * Close modal. */ closeModal(): void { - CoreDomUtils.triggerFormCancelledEvent(this.formElement, this.siteId); + CoreForms.triggerFormCancelledEvent(this.formElement, this.siteId); ModalController.dismiss(); } diff --git a/src/addons/mod/quiz/pages/player/player.page.ts b/src/addons/mod/quiz/pages/player/player.page.ts index d956922f9..f6925f43f 100644 --- a/src/addons/mod/quiz/pages/player/player.page.ts +++ b/src/addons/mod/quiz/pages/player/player.page.ts @@ -44,6 +44,7 @@ import { import { AddonModQuizAttempt, AddonModQuizHelper } from '../../services/quiz-helper'; import { AddonModQuizSync } from '../../services/quiz-sync'; import { CanLeave } from '@guards/can-leave'; +import { CoreForms } from '@singletons/form'; /** * Page that allows attempting a quiz. @@ -160,7 +161,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave { await CoreDomUtils.showConfirm(Translate.instant('addon.mod_quiz.confirmleavequizonerror')); - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); } finally { modal.dismiss(); } @@ -672,7 +673,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave { this.autoSave.hideAutoSaveError(); if (this.formElement) { - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, !this.offline, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormSubmittedEvent(this.formElement, !this.offline, CoreSites.getCurrentSiteId()); } return CoreQuestionHelper.clearTmpData(this.questions, this.component, this.quiz!.coursemodule); diff --git a/src/addons/notes/components/add/add-modal.ts b/src/addons/notes/components/add/add-modal.ts index 6ab234f07..d784b1605 100644 --- a/src/addons/notes/components/add/add-modal.ts +++ b/src/addons/notes/components/add/add-modal.ts @@ -17,6 +17,7 @@ import { Component, ViewChild, ElementRef, Input } from '@angular/core'; import { CoreApp } from '@services/app'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; +import { CoreForms } from '@singletons/form'; import { ModalController } from '@singletons'; /** @@ -53,7 +54,7 @@ export class AddonNotesAddComponent { this.userId = this.userId || CoreSites.getCurrentSiteUserId(); const sent = await AddonNotes.addNote(this.userId, this.courseId, this.type, this.text); - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, sent, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormSubmittedEvent(this.formElement, sent, CoreSites.getCurrentSiteId()); ModalController.dismiss({ type: this.type, sent: true }).finally(() => { CoreDomUtils.showToast(sent ? 'addon.notes.eventnotecreated' : 'core.datastoredoffline', true, 3000); @@ -70,7 +71,7 @@ export class AddonNotesAddComponent { * Close modal. */ closeModal(): void { - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); ModalController.dismiss({ type: this.type }); } diff --git a/src/addons/userprofilefield/checkbox/services/handlers/checkbox.ts b/src/addons/userprofilefield/checkbox/services/handlers/checkbox.ts index 3611f612b..887770465 100644 --- a/src/addons/userprofilefield/checkbox/services/handlers/checkbox.ts +++ b/src/addons/userprofilefield/checkbox/services/handlers/checkbox.ts @@ -17,6 +17,7 @@ import { Injectable, Type } from '@angular/core'; import { AuthEmailSignupProfileField } from '@features/login/services/login-helper'; import { CoreUserProfileField } from '@features/user/services/user'; import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '@features/user/services/user-profile-field-delegate'; +import { CoreFormFields } from '@singletons/form'; import { makeSingleton } from '@singletons'; import { AddonUserProfileFieldCheckboxComponent } from '../../component/checkbox'; @@ -51,7 +52,7 @@ export class AddonUserProfileFieldCheckboxHandlerService implements CoreUserProf field: AuthEmailSignupProfileField | CoreUserProfileField, signup: boolean, registerAuth: string, - formValues: Record, + formValues: CoreFormFields, ): Promise { const name = 'profile_field_' + field.shortname; diff --git a/src/addons/userprofilefield/datetime/services/handlers/datetime.ts b/src/addons/userprofilefield/datetime/services/handlers/datetime.ts index ba0bd7d67..413ad1ccd 100644 --- a/src/addons/userprofilefield/datetime/services/handlers/datetime.ts +++ b/src/addons/userprofilefield/datetime/services/handlers/datetime.ts @@ -17,6 +17,7 @@ import { Injectable, Type } from '@angular/core'; import { AuthEmailSignupProfileField } from '@features/login/services/login-helper'; import { CoreUserProfileField } from '@features/user/services/user'; import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '@features/user/services/user-profile-field-delegate'; +import { CoreFormFields } from '@singletons/form'; import { CoreTimeUtils } from '@services/utils/time'; import { makeSingleton } from '@singletons'; import { AddonUserProfileFieldDatetimeComponent } from '../../component/datetime'; @@ -52,7 +53,7 @@ export class AddonUserProfileFieldDatetimeHandlerService implements CoreUserProf field: AuthEmailSignupProfileField | CoreUserProfileField, signup: boolean, registerAuth: string, - formValues: Record, + formValues: CoreFormFields, ): Promise { const name = 'profile_field_' + field.shortname; diff --git a/src/addons/userprofilefield/menu/services/handlers/menu.ts b/src/addons/userprofilefield/menu/services/handlers/menu.ts index 9379b1b2f..ad111bd7e 100644 --- a/src/addons/userprofilefield/menu/services/handlers/menu.ts +++ b/src/addons/userprofilefield/menu/services/handlers/menu.ts @@ -17,6 +17,7 @@ import { Injectable, Type } from '@angular/core'; import { AuthEmailSignupProfileField } from '@features/login/services/login-helper'; import { CoreUserProfileField } from '@features/user/services/user'; import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '@features/user/services/user-profile-field-delegate'; +import { CoreFormFields } from '@singletons/form'; import { makeSingleton } from '@singletons'; import { AddonUserProfileFieldMenuComponent } from '../../component/menu'; @@ -51,7 +52,7 @@ export class AddonUserProfileFieldMenuHandlerService implements CoreUserProfileF field: AuthEmailSignupProfileField | CoreUserProfileField, signup: boolean, registerAuth: string, - formValues: Record, + formValues: CoreFormFields, ): Promise { const name = 'profile_field_' + field.shortname; diff --git a/src/addons/userprofilefield/text/services/handlers/text.ts b/src/addons/userprofilefield/text/services/handlers/text.ts index 28335b0d2..ac1edda13 100644 --- a/src/addons/userprofilefield/text/services/handlers/text.ts +++ b/src/addons/userprofilefield/text/services/handlers/text.ts @@ -20,6 +20,7 @@ import { CoreTextUtils } from '@services/utils/text'; import { AuthEmailSignupProfileField } from '@features/login/services/login-helper'; import { CoreUserProfileField } from '@features/user/services/user'; import { makeSingleton } from '@singletons'; +import { CoreFormFields } from '@singletons/form'; /** * Text user profile field handlers. @@ -52,7 +53,7 @@ export class AddonUserProfileFieldTextHandlerService implements CoreUserProfileF field: AuthEmailSignupProfileField | CoreUserProfileField, signup: boolean, registerAuth: string, - formValues: Record, + formValues: CoreFormFields, ): Promise { const name = 'profile_field_' + field.shortname; diff --git a/src/addons/userprofilefield/textarea/services/handlers/textarea.ts b/src/addons/userprofilefield/textarea/services/handlers/textarea.ts index a3aff7885..3a6823027 100644 --- a/src/addons/userprofilefield/textarea/services/handlers/textarea.ts +++ b/src/addons/userprofilefield/textarea/services/handlers/textarea.ts @@ -20,6 +20,7 @@ import { CoreTextUtils } from '@services/utils/text'; import { AuthEmailSignupProfileField } from '@features/login/services/login-helper'; import { CoreUserProfileField } from '@features/user/services/user'; import { makeSingleton } from '@singletons'; +import { CoreFormFields } from '@singletons/form'; /** * Textarea user profile field handlers. @@ -52,7 +53,7 @@ export class AddonUserProfileFieldTextareaHandlerService implements CoreUserProf field: AuthEmailSignupProfileField | CoreUserProfileField, signup: boolean, registerAuth: string, - formValues: Record, + formValues: CoreFormFields, ): Promise { const name = 'profile_field_' + field.shortname; diff --git a/src/core/components/local-file/local-file.ts b/src/core/components/local-file/local-file.ts index a8a15c27f..9cab8887d 100644 --- a/src/core/components/local-file/local-file.ts +++ b/src/core/components/local-file/local-file.ts @@ -24,6 +24,7 @@ import { CoreMimetypeUtils } from '@services/utils/mimetype'; import { CoreTextUtils } from '@services/utils/text'; import { CoreTimeUtils } from '@services/utils/time'; import { CoreUtils } from '@services/utils/utils'; +import { CoreForms } from '@singletons/form'; /** * Component to handle a local file. Only files inside the app folder can be managed. @@ -149,7 +150,7 @@ export class CoreLocalFileComponent implements OnInit { if (newName == this.file!.name) { // Name hasn't changed, stop. this.editMode = false; - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); return; } @@ -169,7 +170,7 @@ export class CoreLocalFileComponent implements OnInit { // File doesn't exist, move it. const fileEntry = await CoreFile.moveFile(this.relativePath!, newPath); - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); this.editMode = false; this.file = fileEntry; diff --git a/src/core/components/send-message-form/send-message-form.ts b/src/core/components/send-message-form/send-message-form.ts index 728643f46..aaa69d383 100644 --- a/src/core/components/send-message-form/send-message-form.ts +++ b/src/core/components/send-message-form/send-message-form.ts @@ -19,8 +19,8 @@ import { CoreEvents } from '@singletons/events'; import { CoreSites } from '@services/sites'; import { CoreUtils } from '@services/utils/utils'; import { CoreTextUtils } from '@services/utils/text'; -import { CoreDomUtils } from '@services/utils/dom'; import { CoreConstants } from '@/core/constants'; +import { CoreForms } from '@singletons/form'; /** * Component to display a "send message form". @@ -90,7 +90,7 @@ export class CoreSendMessageFormComponent implements OnInit { this.message = ''; // Reset the form. - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); value = CoreTextUtils.replaceNewLines(value, '
'); this.onSubmit.emit(value); diff --git a/src/core/core.module.ts b/src/core/core.module.ts index 5a5663887..3ccf73400 100644 --- a/src/core/core.module.ts +++ b/src/core/core.module.ts @@ -48,6 +48,7 @@ import { CoreGeolocationProvider } from '@services/geolocation'; import { CoreNavigatorService } from '@services/navigator'; import { CoreScreenService } from '@services/screen'; import { CoreCustomURLSchemesProvider } from '@services/urlschemes'; +import { CoreForms } from '@singletons/form'; export const CORE_SERVICES: Type[] = [ CoreAppProvider, @@ -70,6 +71,7 @@ export const CORE_SERVICES: Type[] = [ CoreSyncProvider, CoreUpdateManagerProvider, CoreDomUtilsProvider, + CoreForms, CoreIframeUtilsProvider, CoreMimetypeUtilsProvider, CoreTextUtilsProvider, diff --git a/src/core/features/comments/components/add/add-modal.ts b/src/core/features/comments/components/add/add-modal.ts index 1808431d6..31a5db47c 100644 --- a/src/core/features/comments/components/add/add-modal.ts +++ b/src/core/features/comments/components/add/add-modal.ts @@ -17,6 +17,7 @@ import { CoreComments } from '@features/comments/services/comments'; import { CoreApp } from '@services/app'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; +import { CoreForms } from '@singletons/form'; import { ModalController } from '@singletons'; /** @@ -62,7 +63,7 @@ export class CoreCommentsAddComponent { this.area, ); - CoreDomUtils.triggerFormSubmittedEvent( + CoreForms.triggerFormSubmittedEvent( this.formElement, !!commentsResponse, CoreSites.getCurrentSiteId(), @@ -87,7 +88,7 @@ export class CoreCommentsAddComponent { * Close modal. */ closeModal(): void { - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); ModalController.dismiss(); } diff --git a/src/core/features/courses/components/self-enrol-password/self-enrol-password.ts b/src/core/features/courses/components/self-enrol-password/self-enrol-password.ts index cceb77551..de7e30a90 100644 --- a/src/core/features/courses/components/self-enrol-password/self-enrol-password.ts +++ b/src/core/features/courses/components/self-enrol-password/self-enrol-password.ts @@ -15,7 +15,7 @@ import { Component, ViewChild, ElementRef } from '@angular/core'; import { ModalController, NavParams } from '@ionic/angular'; import { CoreSites } from '@services/sites'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CoreForms } from '@singletons/form'; /** * Modal that displays a form to enter a password to self enrol in a course. @@ -40,7 +40,7 @@ export class CoreCoursesSelfEnrolPasswordComponent { * Close help modal. */ close(): void { - CoreDomUtils.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); this.modalCtrl.dismiss(); } @@ -55,7 +55,7 @@ export class CoreCoursesSelfEnrolPasswordComponent { e.preventDefault(); e.stopPropagation(); - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); this.modalCtrl.dismiss(this.password); } diff --git a/src/core/features/login/pages/credentials/credentials.ts b/src/core/features/login/pages/credentials/credentials.ts index ea27e9a0a..61cdeb2d5 100644 --- a/src/core/features/login/pages/credentials/credentials.ts +++ b/src/core/features/login/pages/credentials/credentials.ts @@ -24,6 +24,7 @@ import { Translate } from '@singletons'; import { CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes/site'; import { CoreEvents } from '@singletons/events'; import { CoreNavigator } from '@services/navigator'; +import { CoreForms } from '@singletons/form'; /** * Page to enter the user credentials. @@ -249,7 +250,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { } finally { modal.dismiss(); - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, true); + CoreForms.triggerFormSubmittedEvent(this.formElement, true); } } diff --git a/src/core/features/login/pages/email-signup/email-signup.ts b/src/core/features/login/pages/email-signup/email-signup.ts index b662e0550..0d6f53851 100644 --- a/src/core/features/login/pages/email-signup/email-signup.ts +++ b/src/core/features/login/pages/email-signup/email-signup.ts @@ -32,6 +32,7 @@ import { CoreLoginHelper, } from '@features/login/services/login-helper'; import { CoreNavigator } from '@services/navigator'; +import { CoreForms } from '@singletons/form'; /** * Page to signup using email. @@ -333,7 +334,7 @@ export class CoreLoginEmailSignupPage implements OnInit { if (result.success) { - CoreDomUtils.triggerFormSubmittedEvent(this.signupFormElement, true); + CoreForms.triggerFormSubmittedEvent(this.signupFormElement, true); // Show alert and ho back. const message = Translate.instant('core.login.emailconfirmsent', { $a: params.email }); @@ -407,7 +408,7 @@ export class CoreLoginEmailSignupPage implements OnInit { try { const result = await CoreWS.callAjax('core_auth_is_minor', params, { siteUrl: this.siteUrl }); - CoreDomUtils.triggerFormSubmittedEvent(this.ageFormElement, true); + CoreForms.triggerFormSubmittedEvent(this.ageFormElement, true); if (!result.status) { if (this.countryControl.value) { diff --git a/src/core/features/login/pages/forgotten-password/forgotten-password.ts b/src/core/features/login/pages/forgotten-password/forgotten-password.ts index e6e8eabb6..e6aa8a6b0 100644 --- a/src/core/features/login/pages/forgotten-password/forgotten-password.ts +++ b/src/core/features/login/pages/forgotten-password/forgotten-password.ts @@ -20,6 +20,7 @@ import { CoreLoginHelper } from '@features/login/services/login-helper'; import { Translate, Platform } from '@singletons'; import { CoreWSExternalWarning } from '@services/ws'; import { CoreNavigator } from '@services/navigator'; +import { CoreForms } from '@singletons/form'; /** * Page to recover a forgotten password. @@ -97,7 +98,7 @@ export class CoreLoginForgottenPasswordPage implements OnInit { CoreDomUtils.showErrorModal(response.notice); } else { // Success. - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, true); + CoreForms.triggerFormSubmittedEvent(this.formElement, true); CoreDomUtils.showAlert(Translate.instant('core.success'), response.notice); CoreNavigator.back(); diff --git a/src/core/features/login/pages/reconnect/reconnect.ts b/src/core/features/login/pages/reconnect/reconnect.ts index 3016f7984..c6ce18c5e 100644 --- a/src/core/features/login/pages/reconnect/reconnect.ts +++ b/src/core/features/login/pages/reconnect/reconnect.ts @@ -25,6 +25,7 @@ import { CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes import { CoreEvents } from '@singletons/events'; import { CoreError } from '@classes/errors/error'; import { CoreNavigator } from '@services/navigator'; +import { CoreForms } from '@singletons/form'; /** * Page to enter the user password to reconnect to a site. @@ -200,7 +201,7 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy { await CoreSites.updateSiteToken(this.siteUrl, this.username, data.token, data.privateToken); - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, true); + CoreForms.triggerFormSubmittedEvent(this.formElement, true); // Update site info too. await CoreSites.updateSiteInfoByUrl(this.siteUrl, this.username); diff --git a/src/core/features/login/pages/site/site.ts b/src/core/features/login/pages/site/site.ts index 9ea6a324d..0bbdc4939 100644 --- a/src/core/features/login/pages/site/site.ts +++ b/src/core/features/login/pages/site/site.ts @@ -32,6 +32,7 @@ import { CoreLoginSiteOnboardingComponent } from '@features/login/components/sit import { CoreNavigator } from '@services/navigator'; import { CoreCustomURLSchemes, CoreCustomURLSchemesHandleError } from '@services/urlschemes'; import { CoreTextUtils } from '@services/utils/text'; +import { CoreForms } from '@singletons/form'; /** * Page that displays a "splash screen" while the app is being initialized. @@ -322,7 +323,7 @@ export class CoreLoginSitePage implements OnInit { await CoreSites.newSite(data.siteUrl, data.token, data.privateToken); - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, true); + CoreForms.triggerFormSubmittedEvent(this.formElement, true); await CoreNavigator.navigateToSiteHome(); @@ -349,7 +350,7 @@ export class CoreLoginSitePage implements OnInit { protected async login(response: CoreSiteCheckResponse, foundSite?: CoreLoginSiteInfoExtended): Promise { await CoreUtils.ignoreErrors(CoreSites.checkApplication(response)); - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, true); + CoreForms.triggerFormSubmittedEvent(this.formElement, true); if (response.warning) { CoreDomUtils.showErrorModal(response.warning, true, 4000); diff --git a/src/core/features/search/components/search-box/search-box.ts b/src/core/features/search/components/search-box/search-box.ts index 4b9e6ab76..66fc2c0d9 100644 --- a/src/core/features/search/components/search-box/search-box.ts +++ b/src/core/features/search/components/search-box/search-box.ts @@ -15,11 +15,11 @@ import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core'; import { CoreSites } from '@services/sites'; -import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; import { CoreSearchHistory } from '../../services/search-history.service'; import { Translate } from '@singletons'; import { CoreSearchHistoryDBRecord } from '../../services/search-history-db'; +import { CoreForms } from '@singletons/form'; /** * Component to display a "search box". @@ -98,7 +98,7 @@ export class CoreSearchBoxComponent implements OnInit { this.saveSearchToHistory(this.searchText); } - CoreDomUtils.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); + CoreForms.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); this.historyShown = false; this.searched = this.searchText; diff --git a/src/core/features/siteplugins/classes/call-ws-directive.ts b/src/core/features/siteplugins/classes/call-ws-directive.ts index 90ae3ab2a..978f1af25 100644 --- a/src/core/features/siteplugins/classes/call-ws-directive.ts +++ b/src/core/features/siteplugins/classes/call-ws-directive.ts @@ -16,10 +16,10 @@ import { Input, OnInit, OnDestroy, ElementRef, Output, EventEmitter, Directive } import { Subscription } from 'rxjs'; import { CoreSiteWSPreSets } from '@classes/site'; -import { CoreDomUtils } from '@services/utils/dom'; import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content'; import { CoreSitePlugins } from '../services/siteplugins'; import { CoreLogger } from '@singletons/logger'; +import { CoreFormFields, CoreForms } from '@singletons/form'; /** * Base class for directives that need to call a WS. @@ -90,7 +90,7 @@ export class CoreSitePluginsCallWSBaseDirective implements OnInit, OnDestroy { * * @return Params. */ - protected getParamsForWS(): Record { + protected getParamsForWS(): CoreFormFields { let params = this.params || {}; if (this.parentContent) { @@ -98,7 +98,7 @@ export class CoreSitePluginsCallWSBaseDirective implements OnInit, OnDestroy { } if (this.form && document.forms[this.form]) { - params = Object.assign(params, CoreDomUtils.getDataFromForm(document.forms[this.form])); + params = Object.assign(params, CoreForms.getDataFromForm(document.forms[this.form])); } return params; diff --git a/src/core/features/siteplugins/classes/handlers/user-profile-field-handler.ts b/src/core/features/siteplugins/classes/handlers/user-profile-field-handler.ts index d051e0f49..5ffab7ef5 100644 --- a/src/core/features/siteplugins/classes/handlers/user-profile-field-handler.ts +++ b/src/core/features/siteplugins/classes/handlers/user-profile-field-handler.ts @@ -18,6 +18,7 @@ import { AuthEmailSignupProfileField } from '@features/login/services/login-help import { CoreSitePluginsUserProfileFieldComponent } from '@features/siteplugins/components/user-profile-field/user-profile-field'; import { CoreUserProfileField } from '@features/user/services/user'; import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '@features/user/services/user-profile-field-delegate'; +import { CoreFormFields } from '@singletons/form'; import { CoreSitePluginsBaseHandler } from './base-handler'; /** @@ -43,7 +44,7 @@ export class CoreSitePluginsUserProfileFieldHandler extends CoreSitePluginsBaseH field: AuthEmailSignupProfileField | CoreUserProfileField, signup: boolean, registerAuth: string, - formValues: Record, + formValues: CoreFormFields, ): Promise { // No getData function implemented, use a default behaviour. const name = 'profile_field_' + field.shortname; diff --git a/src/core/features/siteplugins/directives/new-content.ts b/src/core/features/siteplugins/directives/new-content.ts index 02a9c7909..6ed25dbad 100644 --- a/src/core/features/siteplugins/directives/new-content.ts +++ b/src/core/features/siteplugins/directives/new-content.ts @@ -17,10 +17,10 @@ import { Md5 } from 'ts-md5'; import { CoreSiteWSPreSets } from '@classes/site'; import { CoreNavigator } from '@services/navigator'; -import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content'; import { CoreSitePlugins } from '../services/siteplugins'; +import { CoreForms } from '@singletons/form'; /** * Directive to display a new site plugin content when clicked. This new content can be displayed in a new page or in the @@ -84,7 +84,7 @@ export class CoreSitePluginsNewContentDirective implements OnInit { } if (this.form && document.forms[this.form]) { - args = Object.assign(args, CoreDomUtils.getDataFromForm(document.forms[this.form])); + args = Object.assign(args, CoreForms.getDataFromForm(document.forms[this.form])); } let jsData = this.jsData || {}; diff --git a/src/core/services/utils/dom.ts b/src/core/services/utils/dom.ts index c22550e67..606fb9df5 100644 --- a/src/core/services/utils/dom.ts +++ b/src/core/services/utils/dom.ts @@ -20,7 +20,6 @@ import { Md5 } from 'ts-md5'; import { CoreApp } from '@services/app'; import { CoreConfig } from '@services/config'; -import { CoreEventFormAction, CoreEvents } from '@singletons/events'; import { CoreFile } from '@services/file'; import { CoreWSExternalWarning } from '@services/ws'; import { CoreTextUtils, CoreTextErrorObject } from '@services/utils/text'; @@ -29,7 +28,7 @@ import { CoreUtils } from '@services/utils/utils'; import { CoreConstants } from '@/core/constants'; import { CoreIonLoadingElement } from '@classes/ion-loading'; import { CoreCanceledError } from '@classes/errors/cancelederror'; -import { CoreError } from '@classes/errors/error'; +import { CoreAnyError, CoreError } from '@classes/errors/error'; import { CoreSilentError } from '@classes/errors/silenterror'; import { makeSingleton, @@ -45,6 +44,7 @@ import { CoreFileSizeSum } from '@services/plugin-file-delegate'; import { CoreNetworkError } from '@classes/errors/network-error'; import { CoreBSTooltipComponent } from '@components/bs-tooltip/bs-tooltip'; import { CoreViewerImageComponent } from '@features/viewer/components/image/image'; +import { CoreFormFields, CoreForms } from '../../singletons/form'; /* * "Utils" service with helper functions for UI, DOM elements and HTML code. @@ -349,7 +349,7 @@ export class CoreDomUtilsProvider { return urls; } - // Extract the URL form each match. + // Extract the URL from each match. matches.forEach((match) => { const submatches = match.match(/url\(\s*['"]?([^'"]*)['"]?\s*\)/im); if (submatches?.[1]) { @@ -445,36 +445,10 @@ export class CoreDomUtilsProvider { * * @param form The form to get the data from. * @return Object with the data. The keys are the names of the inputs. + * @deprecated since 3.9.5. Function has been moved to CoreForms. */ - getDataFromForm(form: HTMLFormElement): Record { - if (!form || !form.elements) { - return {}; - } - - const data = {}; - - for (let i = 0; i < form.elements.length; i++) { - const element = form.elements[i]; - const name = element.name || ''; - - // Ignore submit inputs. - if (!name || element.type == 'submit' || element.tagName == 'BUTTON') { - continue; - } - - // Get the value. - if (element.type == 'checkbox') { - data[name] = !!element.checked; - } else if (element.type == 'radio') { - if (element.checked) { - data[name] = element.value; - } - } else { - data[name] = element.value; - } - } - - return data; + getDataFromForm(form: HTMLFormElement): CoreFormFields { + return CoreForms.getDataFromForm(form); } /** @@ -752,7 +726,7 @@ export class CoreDomUtilsProvider { * @param error Error to check. * @return Whether it's a canceled error. */ - isCanceledError(error: CoreError | CoreTextErrorObject | string | null): boolean { + isCanceledError(error: CoreAnyError): boolean { return error instanceof CoreCanceledError; } @@ -862,8 +836,10 @@ export class CoreDomUtilsProvider { * * @return Promise resolved with boolean: true if enabled, false otherwise. */ - isRichTextEditorEnabled(): Promise { - return CoreConfig.get(CoreConstants.SETTINGS_RICH_TEXT_EDITOR, true).then((enabled) => !!enabled); + async isRichTextEditorEnabled(): Promise { + const enabled = await CoreConfig.get(CoreConstants.SETTINGS_RICH_TEXT_EDITOR, true); + + return !!enabled; } /** @@ -1412,7 +1388,7 @@ export class CoreDomUtilsProvider { * @return Promise resolved with the alert modal. */ async showErrorModalDefault( - error: CoreError | CoreTextErrorObject | string | null, + error: CoreAnyError, defaultError: string, needsTranslate?: boolean, autocloseTime?: number, @@ -1741,7 +1717,7 @@ export class CoreDomUtilsProvider { * @param element The element to search in. * @return Promise resolved with a boolean: whether there was any image to load. */ - waitForImages(element: HTMLElement): Promise { + async waitForImages(element: HTMLElement): Promise { const imgs = Array.from(element.querySelectorAll('img')); const promises: Promise[] = []; let hasImgToLoad = false; @@ -1764,7 +1740,9 @@ export class CoreDomUtilsProvider { } }); - return Promise.all(promises).then(() => hasImgToLoad); + await Promise.all(promises); + + return hasImgToLoad; } /** @@ -1785,16 +1763,10 @@ export class CoreDomUtilsProvider { * * @param form Form element. * @param siteId The site affected. If not provided, no site affected. + * @deprecated since 3.9.5. Function has been moved to CoreForms. */ triggerFormCancelledEvent(formRef: ElementRef | HTMLFormElement | undefined, siteId?: string): void { - if (!formRef) { - return; - } - - CoreEvents.trigger(CoreEvents.FORM_ACTION, { - action: CoreEventFormAction.CANCEL, - form: formRef.nativeElement, - }, siteId); + CoreForms.triggerFormCancelledEvent(formRef, siteId); } /** @@ -1803,17 +1775,10 @@ export class CoreDomUtilsProvider { * @param form Form element. * @param online Whether the action was done in offline or not. * @param siteId The site affected. If not provided, no site affected. + * @deprecated since 3.9.5. Function has been moved to CoreForms. */ triggerFormSubmittedEvent(formRef: ElementRef | HTMLFormElement | undefined, online?: boolean, siteId?: string): void { - if (!formRef) { - return; - } - - CoreEvents.trigger(CoreEvents.FORM_ACTION, { - action: CoreEventFormAction.SUBMIT, - form: formRef.nativeElement || formRef, - online: !!online, - }, siteId); + CoreForms.triggerFormSubmittedEvent(formRef, online, siteId); } } diff --git a/src/core/services/utils/utils.ts b/src/core/services/utils/utils.ts index 3833530be..d043557d1 100644 --- a/src/core/services/utils/utils.ts +++ b/src/core/services/utils/utils.ts @@ -130,6 +130,33 @@ export class CoreUtilsProvider { return result; } + /** + * Converts an array of objects to an indexed array, using a property of each entry as the key. + * Every entry will contain an array of the found objects of the property identifier. + * E.g. [{id: 10, name: 'A'}, {id: 10, name: 'B'}] => {10: [ {id: 10, name: 'A'}, {id: 10, name: 'B'} ] } + * + * @param array The array to convert. + * @param propertyName The name of the property to use as the key. If not provided, the whole item will be used. + * @param result Object where to put the properties. If not defined, a new object will be created. + * @return The object. + */ + arrayToObjectMultiple( + array: T[] = [], + propertyName?: string, + result: Record = {}, + ): Record { + for (const entry of array) { + const key = propertyName ? entry[propertyName] : entry; + if (typeof result[key] == 'undefined') { + result[key] = []; + } + + result[key].push(entry); + } + + return result; + } + /** * Compare two objects. This function won't compare functions and proto properties, it's a basic compare. * Also, this will only check if itemA's properties are in itemB with same value. This function will still diff --git a/src/core/singletons/form.ts b/src/core/singletons/form.ts new file mode 100644 index 000000000..b28d861f5 --- /dev/null +++ b/src/core/singletons/form.ts @@ -0,0 +1,98 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { ElementRef } from '@angular/core'; +import { CoreEventFormAction, CoreEvents } from '@singletons/events'; + +/** + * Singleton with helper functions for Forms. + */ +export class CoreForms { + + /** + * Get the data from a form. It will only collect elements that have a name. + * + * @param form The form to get the data from. + * @return Object with the data. The keys are the names of the inputs. + */ + static getDataFromForm(form: HTMLFormElement): CoreFormFields { + if (!form || !form.elements) { + return {}; + } + + const data: CoreFormFields = {}; + + for (let i = 0; i < form.elements.length; i++) { + const element = form.elements[i]; + const name = element.name || ''; + + // Ignore submit inputs. + if (!name || element.type == 'submit' || element.tagName == 'BUTTON') { + continue; + } + + // Get the value. + if (element.type == 'checkbox') { + data[name] = !!element.checked; + } else if (element.type == 'radio') { + if (element.checked) { + data[name] = element.value; + } + } else { + data[name] = element.value; + } + } + + return data; + } + + /** + * Trigger form cancelled event. + * + * @param form Form element. + * @param siteId The site affected. If not provided, no site affected. + */ + static triggerFormCancelledEvent(formRef: ElementRef | HTMLFormElement | undefined, siteId?: string): void { + if (!formRef) { + return; + } + + CoreEvents.trigger(CoreEvents.FORM_ACTION, { + action: CoreEventFormAction.CANCEL, + form: formRef.nativeElement, + }, siteId); + } + + /** + * Trigger form submitted event. + * + * @param form Form element. + * @param online Whether the action was done in offline or not. + * @param siteId The site affected. If not provided, no site affected. + */ + static triggerFormSubmittedEvent(formRef: ElementRef | HTMLFormElement | undefined, online?: boolean, siteId?: string): void { + if (!formRef) { + return; + } + + CoreEvents.trigger(CoreEvents.FORM_ACTION, { + action: CoreEventFormAction.SUBMIT, + form: formRef.nativeElement || formRef, + online: !!online, + }, siteId); + } + +} + +export type CoreFormFields = Record;