MOBILE-3640 core: New CoreForms utility class

main
Pau Ferrer Ocaña 2021-03-23 09:48:58 +01:00
parent 21fd1f00d7
commit 992f1ca1ad
40 changed files with 262 additions and 140 deletions

View File

@ -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;
}

View File

@ -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<string, unknown> {
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']);
}
/**

View File

@ -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<string, unknown> {
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<string, unknown>): Promise<AddonModAssignSavePluginData> {
protected prepareSubmissionData(inputData: CoreFormFields): Promise<AddonModAssignSavePluginData> {
// 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,

View File

@ -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<string, unknown>,
inputData: CoreFormFields,
): void {
if (!submission) {
return;
@ -362,7 +363,7 @@ export class AddonModAssignHelperProvider {
async getSubmissionSizeForEdit(
assign: AddonModAssignAssign,
submission: AddonModAssignSubmission,
inputData: Record<string, unknown>,
inputData: CoreFormFields,
): Promise<number> {
let totalSize = 0;
@ -537,7 +538,7 @@ export class AddonModAssignHelperProvider {
async hasSubmissionDataChanged(
assign: AddonModAssignAssign,
submission: AddonModAssignSubmission | undefined,
inputData: Record<string, unknown>,
inputData: CoreFormFields,
): Promise<boolean> {
if (!submission) {
return false;
@ -580,7 +581,7 @@ export class AddonModAssignHelperProvider {
siteId?: string,
): Promise<AddonModAssignSavePluginData> {
const pluginData: Record<string, unknown> = {};
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<string, unknown>,
inputData: CoreFormFields,
offline = false,
): Promise<AddonModAssignSavePluginData> {

View File

@ -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<string, unknown>;
export type AddonModAssignSavePluginData = CoreFormFields;
/**
* Params of mod_assign_submit_for_grading WS.

View File

@ -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<string, unknown> | Promise<Record<string, unknown> | undefined> | undefined;
): CoreFormFields | Promise<CoreFormFields | undefined> | undefined;
/**
* Get files used by this plugin.
@ -102,7 +103,7 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler {
assign: AddonModAssignAssign,
submission: AddonModAssignSubmission,
plugin: AddonModAssignPlugin,
inputData: Record<string, unknown>,
inputData: CoreFormFields,
userId: number,
): boolean | Promise<boolean>;
@ -165,7 +166,7 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler {
assignId: number,
userId: number,
plugin: AddonModAssignPlugin,
data: Record<string, unknown>,
data: CoreFormFields,
siteId?: string,
): void | Promise<void>;
}
@ -276,7 +277,7 @@ export class AddonModAssignFeedbackDelegateService extends CoreDelegate<AddonMod
assign: AddonModAssignAssign,
submission: AddonModAssignSubmission | AddonModAssignSubmissionFormatted,
plugin: AddonModAssignPlugin,
inputData: Record<string, unknown>,
inputData: CoreFormFields,
userId: number,
): Promise<boolean | undefined> {
return await this.executeFunctionOnEnabled(
@ -371,7 +372,7 @@ export class AddonModAssignFeedbackDelegateService extends CoreDelegate<AddonMod
assignId: number,
userId: number,
plugin: AddonModAssignPlugin,
inputData: Record<string, unknown>,
inputData: CoreFormFields,
siteId?: string,
): Promise<void> {
return await this.executeFunctionOnEnabled(

View File

@ -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<string, unknown>,
inputData: CoreFormFields,
): void;
/**
@ -173,7 +174,7 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler {
assign: AddonModAssignAssign,
submission: AddonModAssignSubmission,
plugin: AddonModAssignPlugin,
inputData: Record<string, unknown>,
inputData: CoreFormFields,
): number | Promise<number>;
/**
@ -189,7 +190,7 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler {
assign: AddonModAssignAssign,
submission: AddonModAssignSubmission,
plugin: AddonModAssignPlugin,
inputData: Record<string, unknown>,
inputData: CoreFormFields,
): boolean | Promise<boolean>;
/**
@ -233,7 +234,7 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler {
assign: AddonModAssignAssign,
submission: AddonModAssignSubmission,
plugin: AddonModAssignPlugin,
inputData: Record<string, unknown>,
inputData: CoreFormFields,
pluginData: AddonModAssignSavePluginData,
offline?: boolean,
userId?: number,
@ -304,7 +305,7 @@ export class AddonModAssignSubmissionDelegateService extends CoreDelegate<AddonM
assign: AddonModAssignAssign,
submission: AddonModAssignSubmission,
plugin: AddonModAssignPlugin,
inputData: Record<string, unknown>,
inputData: CoreFormFields,
): void {
return this.executeFunctionOnEnabled(plugin.type, 'clearTmpData', [assign, submission, plugin, inputData]);
}
@ -424,7 +425,7 @@ export class AddonModAssignSubmissionDelegateService extends CoreDelegate<AddonM
assign: AddonModAssignAssign,
submission: AddonModAssignSubmission,
plugin: AddonModAssignPlugin,
inputData: Record<string, unknown>,
inputData: CoreFormFields,
): Promise<number | undefined> {
return await this.executeFunctionOnEnabled(
plugin.type,
@ -446,7 +447,7 @@ export class AddonModAssignSubmissionDelegateService extends CoreDelegate<AddonM
assign: AddonModAssignAssign,
submission: AddonModAssignSubmission,
plugin: AddonModAssignPlugin,
inputData: Record<string, unknown>,
inputData: CoreFormFields,
): Promise<boolean | undefined> {
return await this.executeFunctionOnEnabled(
plugin.type,
@ -521,7 +522,7 @@ export class AddonModAssignSubmissionDelegateService extends CoreDelegate<AddonM
assign: AddonModAssignAssign,
submission: AddonModAssignSubmission,
plugin: AddonModAssignPlugin,
inputData: Record<string, unknown>,
inputData: CoreFormFields,
pluginData: AddonModAssignSavePluginData,
offline?: boolean,
userId?: number,

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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<string, unknown>; // 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<string, unknown>, formSubmitted?: boolean): Promise<void> {
protected async processPage(data: CoreFormFields, formSubmitted?: boolean): Promise<void> {
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(),

View File

@ -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<string, unknown>): Record<string, unknown> {
prepareQuestionData(question: AddonModLessonQuestion, data: CoreFormFields): CoreFormFields {
if (question.template == 'essay') {
const textarea = (<AddonModLessonEssayQuestion> question).textarea;

View File

@ -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<string, unknown>,
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<AddonModLessonPageAttemptDBRecord, 'data'|'useranswer'> & {
data: Record<string, unknown> | null;
data: CoreFormFields | null;
useranswer: unknown | null;
};

View File

@ -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();
}

View File

@ -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);

View File

@ -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 });
}

View File

@ -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<string, unknown>,
formValues: CoreFormFields,
): Promise<CoreUserProfileFieldHandlerData | undefined> {
const name = 'profile_field_' + field.shortname;

View File

@ -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<string, unknown>,
formValues: CoreFormFields,
): Promise<CoreUserProfileFieldHandlerData | undefined> {
const name = 'profile_field_' + field.shortname;

View File

@ -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<string, unknown>,
formValues: CoreFormFields,
): Promise<CoreUserProfileFieldHandlerData | undefined> {
const name = 'profile_field_' + field.shortname;

View File

@ -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<string, unknown>,
formValues: CoreFormFields,
): Promise<CoreUserProfileFieldHandlerData | undefined> {
const name = 'profile_field_' + field.shortname;

View File

@ -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<string, unknown>,
formValues: CoreFormFields,
): Promise<CoreUserProfileFieldHandlerData | undefined> {
const name = 'profile_field_' + field.shortname;

View File

@ -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;

View File

@ -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, '<br>');
this.onSubmit.emit(value);

View File

@ -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<unknown>[] = [
CoreAppProvider,
@ -70,6 +71,7 @@ export const CORE_SERVICES: Type<unknown>[] = [
CoreSyncProvider,
CoreUpdateManagerProvider,
CoreDomUtilsProvider,
CoreForms,
CoreIframeUtilsProvider,
CoreMimetypeUtilsProvider,
CoreTextUtilsProvider,

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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<IsMinorWSResult>('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) {

View File

@ -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();

View File

@ -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);

View File

@ -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<void> {
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);

View File

@ -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;

View File

@ -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<string, unknown> {
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;

View File

@ -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<string, unknown>,
formValues: CoreFormFields,
): Promise<CoreUserProfileFieldHandlerData> {
// No getData function implemented, use a default behaviour.
const name = 'profile_field_' + field.shortname;

View File

@ -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 || {};

View File

@ -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<string, unknown> {
if (!form || !form.elements) {
return {};
}
const data = {};
for (let i = 0; i < form.elements.length; i++) {
const element = <HTMLInputElement> 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<boolean> {
return CoreConfig.get(CoreConstants.SETTINGS_RICH_TEXT_EDITOR, true).then((enabled) => !!enabled);
async isRichTextEditorEnabled(): Promise<boolean> {
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<boolean> {
async waitForImages(element: HTMLElement): Promise<boolean> {
const imgs = Array.from(element.querySelectorAll('img'));
const promises: Promise<void>[] = [];
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);
}
}

View File

@ -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<T>(
array: T[] = [],
propertyName?: string,
result: Record<string, T[]> = {},
): Record<string, T[]> {
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

View File

@ -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 = <HTMLInputElement> 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<T = unknown> = Record<string, T>;