diff --git a/src/addons/mod/data/classes/field-plugin-component.ts b/src/addons/mod/data/classes/field-plugin-component.ts index 9c0a79948..c48a136a8 100644 --- a/src/addons/mod/data/classes/field-plugin-component.ts +++ b/src/addons/mod/data/classes/field-plugin-component.ts @@ -32,10 +32,11 @@ export abstract class AddonModDataFieldPluginComponent implements OnInit, OnChan @Input() error?: string; // Error when editing. @Input() form?: FormGroup; // Form where to add the form control. Just required for edit and search modes. @Input() searchFields?: CoreFormFields; // The search value of all fields. - @Output() gotoEntry: EventEmitter; // Action to perform. + @Output() gotoEntry = new EventEmitter(); // Action to perform. + // Output called when the field is initialized with a value and it didn't have one already. + @Output() onFieldInit = new EventEmitter(); constructor(protected fb: FormBuilder) { - this.gotoEntry = new EventEmitter(); } /** @@ -114,3 +115,11 @@ export abstract class AddonModDataFieldPluginComponent implements OnInit, OnChan } } + +/** + * Data for an initialized field. + */ +export type AddonModDataEntryFieldInitialized = Partial & { + fieldid: number; + content: string; +}; diff --git a/src/addons/mod/data/components/field-plugin/field-plugin.ts b/src/addons/mod/data/components/field-plugin/field-plugin.ts index 74ed1e710..b1feba23d 100644 --- a/src/addons/mod/data/components/field-plugin/field-plugin.ts +++ b/src/addons/mod/data/components/field-plugin/field-plugin.ts @@ -16,6 +16,7 @@ import { Component, OnInit, OnChanges, ViewChild, Input, Output, SimpleChange, T import { FormGroup } from '@angular/forms'; import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component'; import { CoreFormFields } from '@singletons/form'; +import { AddonModDataEntryFieldInitialized } from '../../classes/field-plugin-component'; import { AddonModDataData, AddonModDataField, AddonModDataTemplateMode } from '../../services/data'; import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate'; @@ -37,7 +38,9 @@ export class AddonModDataFieldPluginComponent implements OnInit, OnChanges { @Input() error?: string; // Error when editing. @Input() form?: FormGroup; // Form where to add the form control. Just required for edit and search modes. @Input() searchFields?: CoreFormFields; // The search value of all fields. - @Output() gotoEntry = new EventEmitter(); // Action to perform. + @Output() gotoEntry = new EventEmitter(); // Action to perform. + // Output called when the field is initialized with a value and it didn't have one already. + @Output() onFieldInit = new EventEmitter(); fieldComponent?: Type; // Component to render the plugin. pluginData?: AddonDataFieldPluginComponentData; // Data to pass to the component. @@ -65,9 +68,10 @@ export class AddonModDataFieldPluginComponent implements OnInit, OnChanges { value: this.value, database: this.database, error: this.error, - gotoEntry: this.gotoEntry, form: this.form, searchFields: this.searchFields, + gotoEntry: this.gotoEntry, + onFieldInit: this.onFieldInit, }; } } finally { @@ -99,5 +103,6 @@ export type AddonDataFieldPluginComponentData = { error?: string; // Error when editing. form?: FormGroup; // Form where to add the form control. Just required for edit and search modes. searchFields?: CoreFormFields; // The search value of all fields. - gotoEntry: EventEmitter; + gotoEntry: EventEmitter; + onFieldInit: EventEmitter; }; diff --git a/src/addons/mod/data/fields/date/component/date.ts b/src/addons/mod/data/fields/date/component/date.ts index 5fa517dd7..ad539abf5 100644 --- a/src/addons/mod/data/fields/date/component/date.ts +++ b/src/addons/mod/data/fields/date/component/date.ts @@ -68,7 +68,16 @@ export class AddonModDataFieldDateComponent extends AddonModDataFieldPluginCompo } - this.addControl('f_' + this.field.id, CoreTimeUtils.toDatetimeFormat(date.getTime())); + const seconds = Math.floor(date.getTime() / 1000); + + this.addControl('f_' + this.field.id, CoreTimeUtils.toDatetimeFormat(seconds * 1000)); + + if (!this.searchMode && !this.value?.content) { + this.onFieldInit.emit({ + fieldid: this.field.id, + content: String(seconds), + }); + } } } diff --git a/src/addons/mod/data/pages/edit/edit.ts b/src/addons/mod/data/pages/edit/edit.ts index 068d83431..d93b58cae 100644 --- a/src/addons/mod/data/pages/edit/edit.ts +++ b/src/addons/mod/data/pages/edit/edit.ts @@ -41,6 +41,7 @@ import { } from '../../services/data'; import { AddonModDataHelper } from '../../services/data-helper'; import { CoreDom } from '@singletons/dom'; +import { AddonModDataEntryFieldInitialized } from '../../classes/field-plugin-component'; /** * Page that displays the view edit page. @@ -62,6 +63,7 @@ export class AddonModDataEditPage implements OnInit { protected forceLeave = false; // To allow leaving the page without checking for changes. protected initialSelectedGroup?: number; protected isEditing = false; + protected originalData: AddonModDataEntryFields = {}; entry?: AddonModDataEntry; fields: Record = {}; @@ -83,6 +85,7 @@ export class AddonModDataEditPage implements OnInit { contents: AddonModDataEntryFields; errors?: Record; form: FormGroup; + onFieldInit: (data: AddonModDataEntryFieldInitialized) => void; }; errors: Record = {}; @@ -128,7 +131,7 @@ export class AddonModDataEditPage implements OnInit { const inputData = this.editForm.value; - let changed = AddonModDataHelper.hasEditDataChanged(inputData, this.fieldsArray, this.entry.contents); + let changed = AddonModDataHelper.hasEditDataChanged(inputData, this.fieldsArray, this.originalData); changed = changed || (!this.isEditing && this.initialSelectedGroup != this.selectedGroup); if (changed) { @@ -162,6 +165,7 @@ export class AddonModDataEditPage implements OnInit { const entry = await AddonModDataHelper.fetchEntry(this.database, this.fieldsArray, this.entryId || 0); this.entry = entry.entry; + this.originalData = CoreUtils.clone(this.entry.contents); if (this.entryId) { // Load correct group. @@ -401,6 +405,7 @@ export class AddonModDataEditPage implements OnInit { form: this.editForm, database: this.database, errors: this.errors, + onFieldInit: this.onFieldInit.bind(this), }; let template = AddonModDataHelper.getTemplate(this.database!, AddonModDataTemplateType.ADD, this.fieldsArray); @@ -414,7 +419,7 @@ export class AddonModDataEditPage implements OnInit { // Replace field by a generic directive. const render = ''; + [error]="errors[' + field.id + ']" (onFieldInit)="onFieldInit($event)">'; template = template.replace(replaceRegEx, render); // Replace the field id tag. @@ -435,6 +440,27 @@ export class AddonModDataEditPage implements OnInit { return template; } + /** + * A certain value has been initialized. + * + * @param data Data. + */ + onFieldInit(data: AddonModDataEntryFieldInitialized): void { + if (!this.originalData[data.fieldid]) { + this.originalData[data.fieldid] = { + id: 0, + recordid: this.entry?.id ?? 0, + fieldid: data.fieldid, + content: data.content, + content1: data.content1 ?? null, + content2: data.content2 ?? null, + content3: data.content3 ?? null, + content4: data.content4 ?? null, + files: data.files ?? [], + }; + } + } + /** * Return to the entry list (previous page) discarding temp data. * diff --git a/src/addons/mod/data/services/data-helper.ts b/src/addons/mod/data/services/data-helper.ts index 64703aedb..e11bc25d9 100644 --- a/src/addons/mod/data/services/data-helper.ts +++ b/src/addons/mod/data/services/data-helper.ts @@ -213,8 +213,8 @@ export class AddonModDataHelperProvider { // Replace field by a generic directive. const render = ''; + '].contents[' + field.id + ']" mode="' + mode + '" [database]="database" (gotoEntry)="gotoEntry($event)">' + + ''; template = template.replace(replaceRegex, render); }); diff --git a/src/addons/mod/data/services/data.ts b/src/addons/mod/data/services/data.ts index 8c7e4e993..297f4204e 100644 --- a/src/addons/mod/data/services/data.ts +++ b/src/addons/mod/data/services/data.ts @@ -1134,10 +1134,10 @@ export type AddonModDataEntryField = { fieldid: number; // The field type of the content. recordid: number; // The record this content belongs to. content: string; // Contents. - content1: string; // Contents. - content2: string; // Contents. - content3: string; // Contents. - content4: string; // Contents. + content1: string | null; // Contents. + content2: string | null; // Contents. + content3: string | null; // Contents. + content4: string | null; // Contents. files: CoreFileEntry[]; };