forked from CIT/Vmeda.Online
		
	MOBILE-3640 database: Add fields components
This commit is contained in:
		
							parent
							
								
									2991873dfe
								
							
						
					
					
						commit
						8febbe3ea7
					
				
							
								
								
									
										116
									
								
								src/addons/mod/data/classes/field-plugin-component.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/addons/mod/data/classes/field-plugin-component.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,116 @@
 | 
			
		||||
// (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 { Input, Output, OnInit, OnChanges, SimpleChange, EventEmitter, Component } from '@angular/core';
 | 
			
		||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { AddonModDataData, AddonModDataEntryField, AddonModDataField, AddonModDataTemplateMode } from '../services/data';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Base class for component to render a field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    template: '',
 | 
			
		||||
})
 | 
			
		||||
export abstract class AddonModDataFieldPluginComponent implements OnInit, OnChanges {
 | 
			
		||||
 | 
			
		||||
    @Input() mode!: AddonModDataTemplateMode; // The render mode.
 | 
			
		||||
    @Input() field!: AddonModDataField; // The field to render.
 | 
			
		||||
    @Input() value?: Partial<AddonModDataEntryField>; // The value of the field.
 | 
			
		||||
    @Input() database?: AddonModDataData; // Database object.
 | 
			
		||||
    @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<number>; // Action to perform.
 | 
			
		||||
 | 
			
		||||
    constructor(protected fb: FormBuilder) {
 | 
			
		||||
        this.gotoEntry = new EventEmitter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add the form control for the search mode.
 | 
			
		||||
     *
 | 
			
		||||
     * @param fieldName Control field name.
 | 
			
		||||
     * @param value Initial set value.
 | 
			
		||||
     */
 | 
			
		||||
    protected addControl(fieldName: string, value?: unknown): void {
 | 
			
		||||
        if (!this.form) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.searchMode) {
 | 
			
		||||
            this.form.addControl(fieldName, this.fb.control(this.searchFields?.[fieldName] || undefined));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.editMode) {
 | 
			
		||||
            this.form.addControl(fieldName, this.fb.control(value, this.field.required ? Validators.required : null));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Component being initialized.
 | 
			
		||||
     */
 | 
			
		||||
    ngOnInit(): void {
 | 
			
		||||
        this.init();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Initialize field.
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Component being changed.
 | 
			
		||||
     */
 | 
			
		||||
    ngOnChanges(changes: { [name: string]: SimpleChange }): void {
 | 
			
		||||
        if ((this.showMode || this.listMode) && changes.value) {
 | 
			
		||||
            this.updateValue(changes.value.currentValue);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update value being shown.
 | 
			
		||||
     */
 | 
			
		||||
    protected updateValue(value?: Partial<AddonModDataEntryField>): void {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Magic mode getters */
 | 
			
		||||
    get listMode(): boolean {
 | 
			
		||||
        return this.mode == AddonModDataTemplateMode.LIST;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get showMode(): boolean {
 | 
			
		||||
        return this.mode == AddonModDataTemplateMode.SHOW;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get displayMode(): boolean {
 | 
			
		||||
        return this.listMode || this.showMode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get editMode(): boolean {
 | 
			
		||||
        return this.mode == AddonModDataTemplateMode.EDIT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get searchMode(): boolean {
 | 
			
		||||
        return this.mode == AddonModDataTemplateMode.SEARCH;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get inputMode(): boolean {
 | 
			
		||||
        return this.searchMode || this.editMode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,5 @@
 | 
			
		||||
<core-dynamic-component [component]="fieldComponent" [data]="pluginData">
 | 
			
		||||
    <!-- This content will be replaced by the component if found. -->
 | 
			
		||||
    <core-loading [hideUntil]="fieldLoaded">
 | 
			
		||||
    </core-loading>
 | 
			
		||||
</core-dynamic-component>
 | 
			
		||||
							
								
								
									
										103
									
								
								src/addons/mod/data/components/field-plugin/field-plugin.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/addons/mod/data/components/field-plugin/field-plugin.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,103 @@
 | 
			
		||||
// (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 { Component, OnInit, OnChanges, ViewChild, Input, Output, SimpleChange, Type, EventEmitter } from '@angular/core';
 | 
			
		||||
import { FormGroup } from '@angular/forms';
 | 
			
		||||
import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { AddonModDataData, AddonModDataField, AddonModDataTemplateMode } from '../../services/data';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component that displays a database field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-plugin',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-plugin.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldPluginComponent implements OnInit, OnChanges {
 | 
			
		||||
 | 
			
		||||
    @ViewChild(CoreDynamicComponent) dynamicComponent?: CoreDynamicComponent;
 | 
			
		||||
 | 
			
		||||
    @Input() mode!: AddonModDataTemplateMode; // The render mode.
 | 
			
		||||
    @Input() field!: AddonModDataField; // The field to render.
 | 
			
		||||
    @Input() value?: unknown; // The value of the field.
 | 
			
		||||
    @Input() database?: AddonModDataData; // Database object.
 | 
			
		||||
    @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.
 | 
			
		||||
 | 
			
		||||
    fieldComponent?: Type<unknown>; // Component to render the plugin.
 | 
			
		||||
    pluginData?: AddonDataFieldPluginComponentData; // Data to pass to the component.
 | 
			
		||||
    fieldLoaded = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Component being initialized.
 | 
			
		||||
     */
 | 
			
		||||
    async ngOnInit(): Promise<void> {
 | 
			
		||||
        if (!this.field) {
 | 
			
		||||
            this.fieldLoaded = true;
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try{
 | 
			
		||||
            // Check if the plugin has defined its own component to render itself.
 | 
			
		||||
            this.fieldComponent = await AddonModDataFieldsDelegate.getComponentForField(this.field);
 | 
			
		||||
 | 
			
		||||
            if (this.fieldComponent) {
 | 
			
		||||
                // Prepare the data to pass to the component.
 | 
			
		||||
                this.pluginData = {
 | 
			
		||||
                    mode: this.mode,
 | 
			
		||||
                    field: this.field,
 | 
			
		||||
                    value: this.value,
 | 
			
		||||
                    database: this.database,
 | 
			
		||||
                    error: this.error,
 | 
			
		||||
                    gotoEntry: this.gotoEntry,
 | 
			
		||||
                    form: this.form,
 | 
			
		||||
                    searchFields: this.searchFields,
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
        } finally {
 | 
			
		||||
            this.fieldLoaded = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Component being changed.
 | 
			
		||||
     */
 | 
			
		||||
    ngOnChanges(changes: { [name: string]: SimpleChange }): void {
 | 
			
		||||
        if (this.fieldLoaded && this.pluginData) {
 | 
			
		||||
            if (this.mode == AddonModDataTemplateMode.EDIT && changes.error) {
 | 
			
		||||
                this.pluginData.error = changes.error.currentValue;
 | 
			
		||||
            }
 | 
			
		||||
            if ((this.mode == AddonModDataTemplateMode.SHOW || this.mode == AddonModDataTemplateMode.LIST) && changes.value) {
 | 
			
		||||
                this.pluginData.value = changes.value.currentValue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type AddonDataFieldPluginComponentData = {
 | 
			
		||||
    mode: AddonModDataTemplateMode; // The render mode.
 | 
			
		||||
    field: AddonModDataField; // The field to render.
 | 
			
		||||
    value?: unknown; // The value of the field.
 | 
			
		||||
    database?: AddonModDataData; // Database object.
 | 
			
		||||
    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<unknown>;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										42
									
								
								src/addons/mod/data/fields/checkbox/checkbox.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/addons/mod/data/fields/checkbox/checkbox.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// (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 { APP_INITIALIZER, NgModule } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldCheckboxComponent } from './component/checkbox';
 | 
			
		||||
import { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
import { AddonModDataFieldCheckboxHandler } from './services/handler';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AddonModDataFieldCheckboxComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            deps: [],
 | 
			
		||||
            useFactory: () => () => {
 | 
			
		||||
                AddonModDataFieldsDelegate.registerHandler(AddonModDataFieldCheckboxHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        AddonModDataFieldCheckboxComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldCheckboxModule {}
 | 
			
		||||
@ -0,0 +1,16 @@
 | 
			
		||||
<span *ngIf="inputMode && form" [formGroup]="form">
 | 
			
		||||
    <span *ngIf="editMode" [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
			
		||||
    <ion-select [formControlName]="'f_'+field.id" multiple="true" [placeholder]="'addon.mod_data.menuchoose' | translate"
 | 
			
		||||
        [interfaceOptions]="{header: field.name}" interface="alert">
 | 
			
		||||
        <ion-select-option *ngFor="let option of options" [value]="option.value">{{option.key}}</ion-select-option>
 | 
			
		||||
    </ion-select>
 | 
			
		||||
    <core-input-errors *ngIf="error && editMode" [control]="form.controls['f_'+field.id]" [errorText]="error"></core-input-errors>
 | 
			
		||||
 | 
			
		||||
    <ion-item *ngIf="searchMode">
 | 
			
		||||
        <ion-label>{{ 'addon.mod_data.selectedrequired' | translate }}</ion-label>
 | 
			
		||||
        <ion-checkbox slot="end" [formControlName]="'f_'+field.id+'_allreq'" [(ngModel)]="searchFields!['f_'+field.id+'_allreq']">
 | 
			
		||||
        </ion-checkbox>
 | 
			
		||||
    </ion-item>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<core-format-text *ngIf="displayMode && value && value.content" [text]="value.content" [filter]="false"></core-format-text>
 | 
			
		||||
							
								
								
									
										70
									
								
								src/addons/mod/data/fields/checkbox/component/checkbox.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/addons/mod/data/fields/checkbox/component/checkbox.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,70 @@
 | 
			
		||||
// (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 { AddonModDataEntryField } from '@addons/mod/data/services/data';
 | 
			
		||||
import { Component } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render data checkbox field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-checkbox',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-checkbox.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldCheckboxComponent extends AddonModDataFieldPluginComponent {
 | 
			
		||||
 | 
			
		||||
    options: {
 | 
			
		||||
        key: string;
 | 
			
		||||
        value: string;
 | 
			
		||||
    }[] = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        if (this.displayMode) {
 | 
			
		||||
            this.updateValue(this.value);
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.options = this.field.param1.split(/\r?\n/).map((option) => ({ key: option, value: option }));
 | 
			
		||||
 | 
			
		||||
        const values: string[] = [];
 | 
			
		||||
        if (this.editMode && this.value && this.value.content) {
 | 
			
		||||
            this.value.content.split('##').forEach((value) => {
 | 
			
		||||
                const x = this.options.findIndex((option) => value == option.key);
 | 
			
		||||
                if (x >= 0) {
 | 
			
		||||
                    values.push(value);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.searchMode) {
 | 
			
		||||
            this.addControl('f_' + this.field.id + '_allreq');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.addControl('f_' + this.field.id, values);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected updateValue(value?: Partial<AddonModDataEntryField>): void {
 | 
			
		||||
        this.value = value || {};
 | 
			
		||||
        this.value.content = value?.content?.split('##').join('<br>');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										131
									
								
								src/addons/mod/data/fields/checkbox/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								src/addons/mod/data/fields/checkbox/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,131 @@
 | 
			
		||||
// (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 {
 | 
			
		||||
    AddonModDataEntryField,
 | 
			
		||||
    AddonModDataField,
 | 
			
		||||
    AddonModDataSearchEntriesAdvancedFieldFormatted,
 | 
			
		||||
    AddonModDataSubfieldData,
 | 
			
		||||
} from '@addons/mod/data/services/data';
 | 
			
		||||
import { AddonModDataFieldHandler } from '@addons/mod/data/services/data-fields-delegate';
 | 
			
		||||
import { Injectable, Type } from '@angular/core';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldCheckboxComponent } from '../component/checkbox';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for checkbox data field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonModDataFieldCheckboxHandlerService implements AddonModDataFieldHandler {
 | 
			
		||||
 | 
			
		||||
    name = 'AddonModDataFieldCheckboxHandler';
 | 
			
		||||
    type = 'checkbox';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getComponent(): Type<unknown> {
 | 
			
		||||
        return AddonModDataFieldCheckboxComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldSearchData(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string[]>,
 | 
			
		||||
    ): AddonModDataSearchEntriesAdvancedFieldFormatted[] {
 | 
			
		||||
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        const reqName = 'f_' + field.id + '_allreq';
 | 
			
		||||
 | 
			
		||||
        if (inputData[fieldName]) {
 | 
			
		||||
            const values: AddonModDataSearchEntriesAdvancedFieldFormatted[] = [];
 | 
			
		||||
 | 
			
		||||
            values.push({
 | 
			
		||||
                name: fieldName,
 | 
			
		||||
                value: inputData[fieldName],
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            if (inputData[reqName]) {
 | 
			
		||||
                values.push({
 | 
			
		||||
                    name: reqName,
 | 
			
		||||
                    value: true,
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return values;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditData(field: AddonModDataField, inputData: CoreFormFields<string[]>): AddonModDataSubfieldData[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        return [{
 | 
			
		||||
            fieldid: field.id,
 | 
			
		||||
            value: inputData[fieldName] || [],
 | 
			
		||||
        }];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    hasFieldDataChanged(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string[]>,
 | 
			
		||||
        originalFieldData: AddonModDataEntryField,
 | 
			
		||||
    ): boolean {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        const content = originalFieldData?.content || '';
 | 
			
		||||
 | 
			
		||||
        return inputData[fieldName].join('##') != content;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check and get field requeriments.
 | 
			
		||||
     *
 | 
			
		||||
     * @param field Defines the field to be rendered.
 | 
			
		||||
     * @param inputData Data entered in the edit form.
 | 
			
		||||
     * @return String with the notification or false.
 | 
			
		||||
     */
 | 
			
		||||
    getFieldsNotifications(field: AddonModDataField, inputData: AddonModDataSubfieldData[]): string | undefined {
 | 
			
		||||
        if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string[]>): AddonModDataEntryField {
 | 
			
		||||
        originalContent.content = (offlineContent[''] && offlineContent[''].join('##')) || '';
 | 
			
		||||
 | 
			
		||||
        return originalContent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async isEnabled(): Promise<boolean> {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export const AddonModDataFieldCheckboxHandler = makeSingleton(AddonModDataFieldCheckboxHandlerService);
 | 
			
		||||
@ -0,0 +1,16 @@
 | 
			
		||||
<span *ngIf="inputMode && form" [formGroup]="form">
 | 
			
		||||
    <span *ngIf="editMode" [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
			
		||||
    <ion-datetime [formControlName]="'f_'+field.id" [placeholder]="'core.date' | translate"
 | 
			
		||||
        [disabled]="searchMode && !searchFields!['f_'+field.id+'_z']" [displayFormat]="format"></ion-datetime>
 | 
			
		||||
    <core-input-errors *ngIf="error && editMode" [control]="form.controls['f_'+field.id]" [errorText]="error"></core-input-errors>
 | 
			
		||||
 | 
			
		||||
    <ion-item *ngIf="searchMode">
 | 
			
		||||
        <ion-label>{{ 'addon.mod_data.usedate' | translate }}</ion-label>
 | 
			
		||||
        <ion-checkbox slot="end" [formControlName]="'f_'+field.id+'_z'" [(ngModel)]="searchFields!['f_'+field.id+'_z']">
 | 
			
		||||
        </ion-checkbox>
 | 
			
		||||
    </ion-item>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<span *ngIf="displayMode && displayDate">
 | 
			
		||||
    {{ displayDate | coreFormatDate:'strftimedate' }}
 | 
			
		||||
</span>
 | 
			
		||||
							
								
								
									
										70
									
								
								src/addons/mod/data/fields/date/component/date.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/addons/mod/data/fields/date/component/date.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,70 @@
 | 
			
		||||
// (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 { Component } from '@angular/core';
 | 
			
		||||
import { CoreTimeUtils } from '@services/utils/time';
 | 
			
		||||
import { Translate } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render data date field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-date',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-date.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldDateComponent extends AddonModDataFieldPluginComponent {
 | 
			
		||||
 | 
			
		||||
    format!: string;
 | 
			
		||||
    displayDate?: number;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        if (this.displayMode) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let date: Date;
 | 
			
		||||
 | 
			
		||||
        // Calculate format to use.
 | 
			
		||||
        this.format = CoreTimeUtils.fixFormatForDatetime(CoreTimeUtils.convertPHPToMoment(
 | 
			
		||||
            Translate.instant('core.strftimedate'),
 | 
			
		||||
        ));
 | 
			
		||||
 | 
			
		||||
        if (this.searchMode) {
 | 
			
		||||
            this.addControl('f_' + this.field.id + '_z');
 | 
			
		||||
 | 
			
		||||
            date = this.searchFields!['f_' + this.field.id + '_y']
 | 
			
		||||
                ? new Date(this.searchFields!['f_' + this.field.id + '_y'] + '-' +
 | 
			
		||||
                    this.searchFields!['f_' + this.field.id + '_m'] + '-' + this.searchFields!['f_' + this.field.id + '_d'])
 | 
			
		||||
                : new Date();
 | 
			
		||||
 | 
			
		||||
            this.searchFields!['f_' + this.field.id] = CoreTimeUtils.toDatetimeFormat(date.getTime());
 | 
			
		||||
        } else {
 | 
			
		||||
            date = this.value?.content
 | 
			
		||||
                ? new Date(parseInt(this.value.content, 10) * 1000)
 | 
			
		||||
                : new Date();
 | 
			
		||||
 | 
			
		||||
            this.displayDate = this.value?.content
 | 
			
		||||
                ? parseInt(this.value.content, 10) * 1000
 | 
			
		||||
                : undefined;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.addControl('f_' + this.field.id, CoreTimeUtils.toDatetimeFormat(date.getTime()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/addons/mod/data/fields/date/date.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/addons/mod/data/fields/date/date.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// (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 { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
import { AddonModDataFieldDateComponent } from './component/date';
 | 
			
		||||
import { AddonModDataFieldDateHandler } from './services/handler';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AddonModDataFieldDateComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            deps: [],
 | 
			
		||||
            useFactory: () => () => {
 | 
			
		||||
                AddonModDataFieldsDelegate.registerHandler(AddonModDataFieldDateHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        AddonModDataFieldDateComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldDateModule {}
 | 
			
		||||
							
								
								
									
										165
									
								
								src/addons/mod/data/fields/date/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								src/addons/mod/data/fields/date/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,165 @@
 | 
			
		||||
// (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 {
 | 
			
		||||
    AddonModDataEntryField,
 | 
			
		||||
    AddonModDataField,
 | 
			
		||||
    AddonModDataSearchEntriesAdvancedFieldFormatted,
 | 
			
		||||
    AddonModDataSubfieldData,
 | 
			
		||||
} from '@addons/mod/data/services/data';
 | 
			
		||||
import { AddonModDataFieldHandler } from '@addons/mod/data/services/data-fields-delegate';
 | 
			
		||||
import { Injectable, Type } from '@angular/core';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { CoreTimeUtils } from '@services/utils/time';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldDateComponent } from '../component/date';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for date data field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonModDataFieldDateHandlerService implements AddonModDataFieldHandler {
 | 
			
		||||
 | 
			
		||||
    name = 'AddonModDataFieldDateHandler';
 | 
			
		||||
    type = 'date';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getComponent(): Type<unknown>{
 | 
			
		||||
        return AddonModDataFieldDateComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldSearchData(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
    ): AddonModDataSearchEntriesAdvancedFieldFormatted[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        const enabledName = 'f_' + field.id + '_z';
 | 
			
		||||
 | 
			
		||||
        if (inputData[enabledName] && typeof inputData[fieldName] == 'string') {
 | 
			
		||||
            const date = inputData[fieldName].substr(0, 10).split('-');
 | 
			
		||||
 | 
			
		||||
            return [
 | 
			
		||||
                {
 | 
			
		||||
                    name: fieldName + '_y',
 | 
			
		||||
                    value: date[0],
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    name: fieldName + '_m',
 | 
			
		||||
                    value: date[1],
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    name: fieldName + '_d',
 | 
			
		||||
                    value: date[2],
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    name: enabledName,
 | 
			
		||||
                    value: 1,
 | 
			
		||||
                },
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditData(field: AddonModDataField, inputData: CoreFormFields<string>): AddonModDataSubfieldData[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        if (typeof inputData[fieldName] != 'string') {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const date = inputData[fieldName].substr(0, 10).split('-');
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                subfield: 'year',
 | 
			
		||||
                value:  date[0],
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                subfield: 'month',
 | 
			
		||||
                value: date[1],
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                subfield: 'day',
 | 
			
		||||
                value: date[2],
 | 
			
		||||
            },
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    hasFieldDataChanged(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
        originalFieldData: AddonModDataEntryField,
 | 
			
		||||
    ): boolean {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        const input = inputData[fieldName] && inputData[fieldName].substr(0, 10) || '';
 | 
			
		||||
 | 
			
		||||
        const content = (originalFieldData && originalFieldData?.content &&
 | 
			
		||||
                CoreTimeUtils.toDatetimeFormat(parseInt(originalFieldData.content, 10) * 1000).substr(0, 10)) || '';
 | 
			
		||||
 | 
			
		||||
        return input != content;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldsNotifications(field: AddonModDataField, inputData: AddonModDataSubfieldData[]): string | undefined {
 | 
			
		||||
        if (field.required &&
 | 
			
		||||
                (!inputData || inputData.length < 2 || !inputData[0].value || !inputData[1].value || !inputData[2].value)) {
 | 
			
		||||
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string>): AddonModDataEntryField {
 | 
			
		||||
        if (offlineContent['day']) {
 | 
			
		||||
            let date = Date.UTC(
 | 
			
		||||
                parseInt(offlineContent['year'], 10),
 | 
			
		||||
                parseInt(offlineContent['month'], 10) - 1,
 | 
			
		||||
                parseInt(offlineContent['day'], 10),
 | 
			
		||||
            );
 | 
			
		||||
            date = Math.floor(date / 1000);
 | 
			
		||||
 | 
			
		||||
            originalContent.content = String(date) || '';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return originalContent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async isEnabled(): Promise<boolean> {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export const AddonModDataFieldDateHandler = makeSingleton(AddonModDataFieldDateHandlerService);
 | 
			
		||||
							
								
								
									
										45
									
								
								src/addons/mod/data/fields/field.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/addons/mod/data/fields/field.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
			
		||||
// (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 { NgModule } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldCheckboxModule } from './checkbox/checkbox.module';
 | 
			
		||||
import { AddonModDataFieldDateModule } from './date/date.module';
 | 
			
		||||
import { AddonModDataFieldFileModule } from './file/file.module';
 | 
			
		||||
import { AddonModDataFieldLatlongModule } from './latlong/latlong.module';
 | 
			
		||||
import { AddonModDataFieldMenuModule } from './menu/menu.module';
 | 
			
		||||
import { AddonModDataFieldMultimenuModule } from './multimenu/multimenu.module';
 | 
			
		||||
import { AddonModDataFieldNumberModule } from './number/number.module';
 | 
			
		||||
import { AddonModDataFieldPictureModule } from './picture/picture.module';
 | 
			
		||||
import { AddonModDataFieldRadiobuttonModule } from './radiobutton/radiobutton.module';
 | 
			
		||||
import { AddonModDataFieldTextModule } from './text/text.module';
 | 
			
		||||
import { AddonModDataFieldTextareaModule } from './textarea/textarea.module';
 | 
			
		||||
import { AddonModDataFieldUrlModule } from './url/url.module';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    imports: [
 | 
			
		||||
        AddonModDataFieldCheckboxModule,
 | 
			
		||||
        AddonModDataFieldDateModule,
 | 
			
		||||
        AddonModDataFieldFileModule,
 | 
			
		||||
        AddonModDataFieldLatlongModule,
 | 
			
		||||
        AddonModDataFieldMenuModule,
 | 
			
		||||
        AddonModDataFieldMultimenuModule,
 | 
			
		||||
        AddonModDataFieldNumberModule,
 | 
			
		||||
        AddonModDataFieldPictureModule,
 | 
			
		||||
        AddonModDataFieldRadiobuttonModule,
 | 
			
		||||
        AddonModDataFieldTextModule,
 | 
			
		||||
        AddonModDataFieldTextareaModule,
 | 
			
		||||
        AddonModDataFieldUrlModule,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldModule { }
 | 
			
		||||
@ -0,0 +1,17 @@
 | 
			
		||||
<span *ngIf="editMode && form">
 | 
			
		||||
    <span [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
			
		||||
    <core-attachments [files]="files" [maxSize]="maxSizeBytes" maxSubmissions="1" [component]="component"
 | 
			
		||||
        [componentId]="componentId" [allowOffline]="true">
 | 
			
		||||
    </core-attachments>
 | 
			
		||||
    <core-input-errors *ngIf="error" [errorText]="error"></core-input-errors>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<span *ngIf="searchMode && form" [formGroup]="form">
 | 
			
		||||
    <ion-input type="text" [formControlName]="'f_'+field.id" [placeholder]="field.name"></ion-input>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<ng-container *ngIf="displayMode">
 | 
			
		||||
    <div lines="none">
 | 
			
		||||
        <core-files [files]="files" [component]="component" [componentId]="componentId" [alwaysDownload]="true"></core-files>
 | 
			
		||||
    </div>
 | 
			
		||||
</ng-container>
 | 
			
		||||
							
								
								
									
										81
									
								
								src/addons/mod/data/fields/file/component/file.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/addons/mod/data/fields/file/component/file.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,81 @@
 | 
			
		||||
// (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 { Component } from '@angular/core';
 | 
			
		||||
import { AddonModDataEntryField, AddonModDataProvider } from '@addons/mod/data/services/data';
 | 
			
		||||
import { AddonModDataFieldPluginComponent } from '@addons/mod/data/classes/field-plugin-component';
 | 
			
		||||
import { CoreFileSession } from '@services/file-session';
 | 
			
		||||
import { CoreWSExternalFile } from '@services/ws';
 | 
			
		||||
import { FileEntry } from '@ionic-native/file';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render data file field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-file',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-file.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldFileComponent extends AddonModDataFieldPluginComponent {
 | 
			
		||||
 | 
			
		||||
    files: (CoreWSExternalFile | FileEntry)[] = [];
 | 
			
		||||
    component?: string;
 | 
			
		||||
    componentId?: number;
 | 
			
		||||
    maxSizeBytes?: number;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the files from the input value.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value Input value.
 | 
			
		||||
     * @return List of files.
 | 
			
		||||
     */
 | 
			
		||||
    protected getFiles(value?: Partial<AddonModDataEntryField>): (CoreWSExternalFile | FileEntry)[] {
 | 
			
		||||
        let files = value?.files || [];
 | 
			
		||||
 | 
			
		||||
        // Reduce to first element.
 | 
			
		||||
        if (files.length > 0) {
 | 
			
		||||
            files = [files[0]];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return files;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        if (this.searchMode) {
 | 
			
		||||
            this.addControl('f_' + this.field.id);
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.component = AddonModDataProvider.COMPONENT;
 | 
			
		||||
        this.componentId = this.database!.coursemodule;
 | 
			
		||||
 | 
			
		||||
        this.updateValue(this.value);
 | 
			
		||||
 | 
			
		||||
        if (this.editMode) {
 | 
			
		||||
            this.maxSizeBytes = parseInt(this.field.param3, 10);
 | 
			
		||||
            CoreFileSession.setFiles(this.component, this.database!.id + '_' + this.field.id, this.files);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected updateValue(value?: Partial<AddonModDataEntryField>): void {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
        this.files = this.getFiles(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/addons/mod/data/fields/file/file.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/addons/mod/data/fields/file/file.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// (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 { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
import { AddonModDataFieldFileComponent } from './component/file';
 | 
			
		||||
import { AddonModDataFieldFileHandler } from './services/handler';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AddonModDataFieldFileComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            deps: [],
 | 
			
		||||
            useFactory: () => () => {
 | 
			
		||||
                AddonModDataFieldsDelegate.registerHandler(AddonModDataFieldFileHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        AddonModDataFieldFileComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldFileModule {}
 | 
			
		||||
							
								
								
									
										136
									
								
								src/addons/mod/data/fields/file/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/addons/mod/data/fields/file/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,136 @@
 | 
			
		||||
// (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 {
 | 
			
		||||
    AddonModDataEntryField,
 | 
			
		||||
    AddonModDataField,
 | 
			
		||||
    AddonModDataProvider,
 | 
			
		||||
    AddonModDataSearchEntriesAdvancedFieldFormatted,
 | 
			
		||||
    AddonModDataSubfieldData,
 | 
			
		||||
} from '@addons/mod/data/services/data';
 | 
			
		||||
import { AddonModDataFieldHandler } from '@addons/mod/data/services/data-fields-delegate';
 | 
			
		||||
import { Injectable, Type } from '@angular/core';
 | 
			
		||||
import { CoreFileUploader, CoreFileUploaderStoreFilesResult } from '@features/fileuploader/services/fileuploader';
 | 
			
		||||
import { FileEntry } from '@ionic-native/file';
 | 
			
		||||
import { CoreFileSession } from '@services/file-session';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { CoreWSExternalFile } from '@services/ws';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldFileComponent } from '../component/file';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for file data field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonModDataFieldFileHandlerService implements AddonModDataFieldHandler {
 | 
			
		||||
 | 
			
		||||
    name = 'AddonModDataFieldFileHandler';
 | 
			
		||||
    type = 'file';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getComponent(): Type<unknown>{
 | 
			
		||||
        return AddonModDataFieldFileComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldSearchData(field: AddonModDataField, inputData: CoreFormFields): AddonModDataSearchEntriesAdvancedFieldFormatted[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        if (inputData[fieldName]) {
 | 
			
		||||
            return [{
 | 
			
		||||
                name: fieldName,
 | 
			
		||||
                value: inputData[fieldName],
 | 
			
		||||
            }];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditData(field: AddonModDataField): AddonModDataSubfieldData[] {
 | 
			
		||||
        const files = this.getFieldEditFiles(field);
 | 
			
		||||
 | 
			
		||||
        return [{
 | 
			
		||||
            fieldid: field.id,
 | 
			
		||||
            subfield: 'file',
 | 
			
		||||
            files: files,
 | 
			
		||||
        }];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditFiles(field: AddonModDataField): (CoreWSExternalFile | FileEntry)[] {
 | 
			
		||||
        return CoreFileSession.getFiles(AddonModDataProvider.COMPONENT,  field.dataid + '_' + field.id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    hasFieldDataChanged(field: AddonModDataField, inputData: CoreFormFields, originalFieldData: AddonModDataEntryField): boolean {
 | 
			
		||||
        const files = CoreFileSession.getFiles(AddonModDataProvider.COMPONENT,  field.dataid + '_' + field.id) || [];
 | 
			
		||||
        let originalFiles = (originalFieldData && originalFieldData.files) || [];
 | 
			
		||||
 | 
			
		||||
        if (originalFiles.length) {
 | 
			
		||||
            originalFiles = [originalFiles[0]];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return CoreFileUploader.areFileListDifferent(files, originalFiles);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldsNotifications(field: AddonModDataField, inputData: AddonModDataSubfieldData[]): string | undefined {
 | 
			
		||||
        if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    overrideData(
 | 
			
		||||
        originalContent: AddonModDataEntryField,
 | 
			
		||||
        offlineContent: CoreFormFields,
 | 
			
		||||
        offlineFiles?: FileEntry[],
 | 
			
		||||
    ): AddonModDataEntryField {
 | 
			
		||||
        const uploadedFilesResult: CoreFileUploaderStoreFilesResult = <CoreFileUploaderStoreFilesResult>offlineContent?.file;
 | 
			
		||||
 | 
			
		||||
        if (uploadedFilesResult && uploadedFilesResult.offline > 0 && offlineFiles && offlineFiles?.length > 0) {
 | 
			
		||||
            originalContent.content = offlineFiles[0].name;
 | 
			
		||||
            originalContent.files = [offlineFiles[0]];
 | 
			
		||||
        } else if (uploadedFilesResult && uploadedFilesResult.online && uploadedFilesResult.online.length > 0) {
 | 
			
		||||
            originalContent.content = uploadedFilesResult.online[0].filename || '';
 | 
			
		||||
            originalContent.files = [uploadedFilesResult.online[0]];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return originalContent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async isEnabled(): Promise<boolean> {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export const AddonModDataFieldFileHandler = makeSingleton(AddonModDataFieldFileHandlerService);
 | 
			
		||||
@ -0,0 +1,27 @@
 | 
			
		||||
<span *ngIf="inputMode && form" [formGroup]="form">
 | 
			
		||||
    <ion-input *ngIf="searchMode" type="text" [placeholder]="field.name" [formControlName]="'f_'+field.id"></ion-input>
 | 
			
		||||
 | 
			
		||||
    <ng-container *ngIf="editMode">
 | 
			
		||||
        <span [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
			
		||||
        <div class="addon-data-latlong">
 | 
			
		||||
            <ion-input type="text" [formControlName]="'f_'+field.id+'_0'" maxlength="10"></ion-input>
 | 
			
		||||
            <span class="placeholder-icon" item-right>°N</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="addon-data-latlong">
 | 
			
		||||
            <ion-input type="text" [formControlName]="'f_'+field.id+'_1'" maxlength="10"></ion-input>
 | 
			
		||||
            <span class="placeholder-icon" item-right>°E</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="addon-data-latlong">
 | 
			
		||||
            <ion-button (click)="getLocation($event)">
 | 
			
		||||
                <ion-icon name="fas-crosshairs" slot="start"></ion-icon>
 | 
			
		||||
                {{ 'addon.mod_data.mylocation' | translate }}
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <core-input-errors *ngIf="error" [control]="form.controls['f_'+field.id]" [errorText]="error"></core-input-errors>
 | 
			
		||||
    </ng-container>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<span *ngIf="displayMode && value">
 | 
			
		||||
    <a [href]="getLatLongLink(north, east)">{{ formatLatLong(north, east) }}</a>
 | 
			
		||||
</span>
 | 
			
		||||
							
								
								
									
										164
									
								
								src/addons/mod/data/fields/latlong/component/latlong.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								src/addons/mod/data/fields/latlong/component/latlong.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,164 @@
 | 
			
		||||
// (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 { AddonModDataFieldPluginComponent } from '@addons/mod/data/classes/field-plugin-component';
 | 
			
		||||
import { AddonModDataEntryField } from '@addons/mod/data/services/data';
 | 
			
		||||
import { Component } from '@angular/core';
 | 
			
		||||
import { FormBuilder } from '@angular/forms';
 | 
			
		||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
 | 
			
		||||
import { CoreAnyError } from '@classes/errors/error';
 | 
			
		||||
import { CoreApp } from '@services/app';
 | 
			
		||||
import { CoreGeolocation, CoreGeolocationError, CoreGeolocationErrorReason } from '@services/geolocation';
 | 
			
		||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render data latlong field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-latlong',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-latlong.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldLatlongComponent extends AddonModDataFieldPluginComponent {
 | 
			
		||||
 | 
			
		||||
    north?: number;
 | 
			
		||||
    east?: number;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        fb: FormBuilder,
 | 
			
		||||
        protected sanitizer: DomSanitizer,
 | 
			
		||||
    ) {
 | 
			
		||||
        super(fb);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Format latitude and longitude in a simple text.
 | 
			
		||||
     *
 | 
			
		||||
     * @param north Degrees north.
 | 
			
		||||
     * @param east Degrees East.
 | 
			
		||||
     * @return Readable Latitude and logitude.
 | 
			
		||||
     */
 | 
			
		||||
    formatLatLong(north?: number, east?: number): string {
 | 
			
		||||
        if (typeof north !== 'undefined' || typeof east !== 'undefined') {
 | 
			
		||||
            north = north || 0;
 | 
			
		||||
            east = east || 0;
 | 
			
		||||
            const northFixed = Math.abs(north).toFixed(4);
 | 
			
		||||
            const eastFixed = Math.abs(east).toFixed(4);
 | 
			
		||||
 | 
			
		||||
            return northFixed + (north < 0 ? '°S' : '°N') + ' ' + eastFixed + (east < 0 ? '°W' : '°E');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return '';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get link to maps from latitude and longitude.
 | 
			
		||||
     *
 | 
			
		||||
     * @param north Degrees north.
 | 
			
		||||
     * @param east Degrees East.
 | 
			
		||||
     * @return Link to maps depending on platform.
 | 
			
		||||
     */
 | 
			
		||||
    getLatLongLink(north?: number, east?: number): SafeUrl {
 | 
			
		||||
        let url = '';
 | 
			
		||||
        if (typeof north !== 'undefined' || typeof east !== 'undefined') {
 | 
			
		||||
            const northFixed = north ? north.toFixed(4) : '0.0000';
 | 
			
		||||
            const eastFixed = east ? east.toFixed(4) : '0.0000';
 | 
			
		||||
 | 
			
		||||
            if (CoreApp.isIOS()) {
 | 
			
		||||
                url = 'http://maps.apple.com/?ll=' + northFixed + ',' + eastFixed + '&near=' + northFixed + ',' + eastFixed;
 | 
			
		||||
            } else {
 | 
			
		||||
                url = 'geo:' + northFixed + ',' + eastFixed;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return this.sanitizer.bypassSecurityTrustUrl(url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        if (this.value) {
 | 
			
		||||
            this.updateValue(this.value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.editMode) {
 | 
			
		||||
            this.addControl('f_' + this.field.id + '_0', this.north);
 | 
			
		||||
            this.addControl('f_' + this.field.id + '_1', this.east);
 | 
			
		||||
        } else if (this.searchMode) {
 | 
			
		||||
            this.addControl('f_' + this.field.id);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected updateValue(value?: Partial<AddonModDataEntryField>): void {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
        this.north = (value && parseFloat(value.content!)) || undefined;
 | 
			
		||||
        this.east = (value && parseFloat(value.content1!)) || undefined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get user location.
 | 
			
		||||
     *
 | 
			
		||||
     * @param $event The event.
 | 
			
		||||
     */
 | 
			
		||||
    async getLocation(event: Event): Promise<void> {
 | 
			
		||||
        event.preventDefault();
 | 
			
		||||
 | 
			
		||||
        const modal = await CoreDomUtils.showModalLoading('addon.mod_data.gettinglocation', true);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            const coordinates = await CoreGeolocation.getCoordinates();
 | 
			
		||||
 | 
			
		||||
            this.form?.controls['f_' + this.field.id + '_0'].setValue(coordinates.latitude);
 | 
			
		||||
            this.form?.controls['f_' + this.field.id + '_1'].setValue(coordinates.longitude);
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            this.showLocationErrorModal(error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        modal.dismiss();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Show the appropriate error modal for the given error getting the location.
 | 
			
		||||
     *
 | 
			
		||||
     * @param error Location error.
 | 
			
		||||
     */
 | 
			
		||||
    protected showLocationErrorModal(error: CoreAnyError): void {
 | 
			
		||||
        if (error instanceof CoreGeolocationError) {
 | 
			
		||||
            CoreDomUtils.showErrorModal(this.getGeolocationErrorMessage(error), true);
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        CoreDomUtils.showErrorModalDefault(error,  'Error getting location');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get error message from a geolocation error.
 | 
			
		||||
     *
 | 
			
		||||
     * @param error Geolocation error.
 | 
			
		||||
     */
 | 
			
		||||
    protected getGeolocationErrorMessage(error: CoreGeolocationError): string {
 | 
			
		||||
        // tslint:disable-next-line: switch-default
 | 
			
		||||
        switch (error.reason) {
 | 
			
		||||
            case CoreGeolocationErrorReason.PermissionDenied:
 | 
			
		||||
                return 'addon.mod_data.locationpermissiondenied';
 | 
			
		||||
            case CoreGeolocationErrorReason.LocationNotEnabled:
 | 
			
		||||
                return 'addon.mod_data.locationnotenabled';
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/addons/mod/data/fields/latlong/latlong.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/addons/mod/data/fields/latlong/latlong.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// (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 { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
import { AddonModDataFieldLatlongComponent } from './component/latlong';
 | 
			
		||||
import { AddonModDataFieldLatlongHandler } from './services/handler';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AddonModDataFieldLatlongComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            deps: [],
 | 
			
		||||
            useFactory: () => () => {
 | 
			
		||||
                AddonModDataFieldsDelegate.registerHandler(AddonModDataFieldLatlongHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        AddonModDataFieldLatlongComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldLatlongModule {}
 | 
			
		||||
							
								
								
									
										138
									
								
								src/addons/mod/data/fields/latlong/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								src/addons/mod/data/fields/latlong/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,138 @@
 | 
			
		||||
// (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 {
 | 
			
		||||
    AddonModDataEntryField,
 | 
			
		||||
    AddonModDataField,
 | 
			
		||||
    AddonModDataSearchEntriesAdvancedFieldFormatted,
 | 
			
		||||
    AddonModDataSubfieldData,
 | 
			
		||||
} from '@addons/mod/data/services/data';
 | 
			
		||||
import { AddonModDataFieldHandler } from '@addons/mod/data/services/data-fields-delegate';
 | 
			
		||||
import { Injectable, Type } from '@angular/core';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldLatlongComponent } from '../component/latlong';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for latlong data field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonModDataFieldLatlongHandlerService implements AddonModDataFieldHandler {
 | 
			
		||||
 | 
			
		||||
    name = 'AddonModDataFieldLatlongHandler';
 | 
			
		||||
    type = 'latlong';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getComponent(): Type<unknown>{
 | 
			
		||||
        return AddonModDataFieldLatlongComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldSearchData(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
    ): AddonModDataSearchEntriesAdvancedFieldFormatted[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        if (inputData[fieldName]) {
 | 
			
		||||
            return [{
 | 
			
		||||
                name: fieldName,
 | 
			
		||||
                value: inputData[fieldName],
 | 
			
		||||
            }];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditData(field: AddonModDataField, inputData: CoreFormFields<string>): AddonModDataSubfieldData[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                subfield: '0',
 | 
			
		||||
                value: inputData[fieldName + '_0'] || '',
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                subfield: '1',
 | 
			
		||||
                value: inputData[fieldName + '_1'] || '',
 | 
			
		||||
            },
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    hasFieldDataChanged(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
        originalFieldData: AddonModDataEntryField,
 | 
			
		||||
    ): boolean {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        const lat = inputData[fieldName + '_0'] || '';
 | 
			
		||||
        const long = inputData[fieldName + '_1'] || '';
 | 
			
		||||
        const originalLat = (originalFieldData && originalFieldData.content) || '';
 | 
			
		||||
        const originalLong = (originalFieldData && originalFieldData.content1) || '';
 | 
			
		||||
 | 
			
		||||
        return lat != originalLat || long != originalLong;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldsNotifications(field: AddonModDataField, inputData: AddonModDataSubfieldData[]): string | undefined {
 | 
			
		||||
        let valueCount = 0;
 | 
			
		||||
 | 
			
		||||
        // The lat long class has two values that need to be checked.
 | 
			
		||||
        inputData.forEach((value) => {
 | 
			
		||||
            if (typeof value.value != 'undefined' && value.value != '') {
 | 
			
		||||
                valueCount++;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // If we get here then only one field has been filled in.
 | 
			
		||||
        if (valueCount == 1) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.latlongboth');
 | 
			
		||||
        } else if (field.required && valueCount == 0) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string>): AddonModDataEntryField {
 | 
			
		||||
        originalContent.content = offlineContent[0] || '';
 | 
			
		||||
        originalContent.content1 = offlineContent[1] || '';
 | 
			
		||||
 | 
			
		||||
        return originalContent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async isEnabled(): Promise<boolean> {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export const AddonModDataFieldLatlongHandler = makeSingleton(AddonModDataFieldLatlongHandlerService);
 | 
			
		||||
@ -0,0 +1,11 @@
 | 
			
		||||
<span *ngIf="inputMode && form" [formGroup]="form">
 | 
			
		||||
    <span *ngIf="editMode" [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
			
		||||
    <ion-select [formControlName]="'f_'+field.id" [placeholder]="'addon.mod_data.menuchoose' | translate"
 | 
			
		||||
        [interfaceOptions]="{header: field.name}" interface="action-sheet">
 | 
			
		||||
        <ion-select-option value="">{{ 'addon.mod_data.menuchoose' | translate }}</ion-select-option>
 | 
			
		||||
        <ion-select-option *ngFor="let option of options" [value]="option">{{option}}</ion-select-option>
 | 
			
		||||
    </ion-select>
 | 
			
		||||
    <core-input-errors *ngIf="error && editMode" [control]="form.controls['f_'+field.id]" [errorText]="error"></core-input-errors>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<span *ngIf="displayMode && value && value.content">{{ value.content }}</span>
 | 
			
		||||
							
								
								
									
										47
									
								
								src/addons/mod/data/fields/menu/component/menu.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/addons/mod/data/fields/menu/component/menu.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
// (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 { Component } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render data menu field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-menu',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-menu.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldMenuComponent extends AddonModDataFieldPluginComponent {
 | 
			
		||||
 | 
			
		||||
    options: string[] = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Initialize field.
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        if (this.displayMode) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.options = this.field.param1.split('\n');
 | 
			
		||||
 | 
			
		||||
        let val: string | undefined;
 | 
			
		||||
        if (this.editMode && this.value) {
 | 
			
		||||
            val = this.value.content;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.addControl('f_' + this.field.id, val);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/addons/mod/data/fields/menu/menu.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/addons/mod/data/fields/menu/menu.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// (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 { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
import { AddonModDataFieldMenuComponent } from './component/menu';
 | 
			
		||||
import { AddonModDataFieldMenuHandler } from './services/handler';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AddonModDataFieldMenuComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            deps: [],
 | 
			
		||||
            useFactory: () => () => {
 | 
			
		||||
                AddonModDataFieldsDelegate.registerHandler(AddonModDataFieldMenuHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        AddonModDataFieldMenuComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldMenuModule {}
 | 
			
		||||
							
								
								
									
										116
									
								
								src/addons/mod/data/fields/menu/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/addons/mod/data/fields/menu/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,116 @@
 | 
			
		||||
// (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 {
 | 
			
		||||
    AddonModDataEntryField,
 | 
			
		||||
    AddonModDataField,
 | 
			
		||||
    AddonModDataSearchEntriesAdvancedFieldFormatted,
 | 
			
		||||
    AddonModDataSubfieldData,
 | 
			
		||||
} from '@addons/mod/data/services/data';
 | 
			
		||||
import { AddonModDataFieldHandler } from '@addons/mod/data/services/data-fields-delegate';
 | 
			
		||||
import { Injectable, Type } from '@angular/core';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldMenuComponent } from '../component/menu';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for menu data field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonModDataFieldMenuHandlerService implements AddonModDataFieldHandler {
 | 
			
		||||
 | 
			
		||||
    name = 'AddonModDataFieldMenuHandler';
 | 
			
		||||
    type = 'menu';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getComponent(): Type<unknown>{
 | 
			
		||||
        return AddonModDataFieldMenuComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldSearchData(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
    ): AddonModDataSearchEntriesAdvancedFieldFormatted[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        if (inputData[fieldName]) {
 | 
			
		||||
            return [{
 | 
			
		||||
                name: fieldName,
 | 
			
		||||
                value: inputData[fieldName],
 | 
			
		||||
            }];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditData(field: AddonModDataField, inputData: CoreFormFields<string>): AddonModDataSubfieldData[] {
 | 
			
		||||
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        if (inputData[fieldName]) {
 | 
			
		||||
            return [{
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                value: inputData[fieldName],
 | 
			
		||||
            }];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hasFieldDataChanged(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
        originalFieldData: AddonModDataEntryField,
 | 
			
		||||
    ): boolean {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        const input = inputData[fieldName] || '';
 | 
			
		||||
        const content = originalFieldData?.content || '';
 | 
			
		||||
 | 
			
		||||
        return input != content;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldsNotifications(field: AddonModDataField, inputData: AddonModDataSubfieldData[]): string | undefined {
 | 
			
		||||
        if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string>): AddonModDataEntryField {
 | 
			
		||||
        originalContent.content = offlineContent[''] || '';
 | 
			
		||||
 | 
			
		||||
        return originalContent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async isEnabled(): Promise<boolean> {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export const AddonModDataFieldMenuHandler = makeSingleton(AddonModDataFieldMenuHandlerService);
 | 
			
		||||
@ -0,0 +1,17 @@
 | 
			
		||||
<span *ngIf="inputMode && form" [formGroup]="form">
 | 
			
		||||
    <span *ngIf="editMode" [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
			
		||||
    <ion-select [formControlName]="'f_'+field.id" multiple="true" [placeholder]="'addon.mod_data.menuchoose' | translate"
 | 
			
		||||
        [interfaceOptions]="{header: field.name}" interface="alert">
 | 
			
		||||
        <ion-select-option *ngFor="let option of options" [value]="option.value">{{option.key}}</ion-select-option>
 | 
			
		||||
    </ion-select>
 | 
			
		||||
    <core-input-errors *ngIf="error && editMode" [control]="form.controls['f_'+field.id]" [errorText]="error"></core-input-errors>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <ion-item *ngIf="searchMode">
 | 
			
		||||
        <ion-label>{{ 'addon.mod_data.selectedrequired' | translate }}</ion-label>
 | 
			
		||||
        <ion-checkbox slot="end" [formControlName]="'f_'+field.id+'_allreq'" [(ngModel)]="searchFields!['f_'+field.id+'_allreq']">
 | 
			
		||||
        </ion-checkbox>
 | 
			
		||||
    </ion-item>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<core-format-text *ngIf="displayMode && value && value.content" [text]="value.content" [filter]="false"></core-format-text>
 | 
			
		||||
							
								
								
									
										70
									
								
								src/addons/mod/data/fields/multimenu/component/multimenu.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/addons/mod/data/fields/multimenu/component/multimenu.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,70 @@
 | 
			
		||||
// (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 { AddonModDataEntryField } from '@addons/mod/data/services/data';
 | 
			
		||||
import { Component } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render data multimenu field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-multimenu',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-multimenu.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldMultimenuComponent extends AddonModDataFieldPluginComponent {
 | 
			
		||||
 | 
			
		||||
    options: {
 | 
			
		||||
        key: string;
 | 
			
		||||
        value: string;
 | 
			
		||||
    }[] = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        if (this.displayMode) {
 | 
			
		||||
            this.updateValue(this.value);
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.options = this.field.param1.split(/\r?\n/).map((option) => ({ key: option, value: option }));
 | 
			
		||||
 | 
			
		||||
        const values: string[] = [];
 | 
			
		||||
        if (this.editMode && this.value?.content) {
 | 
			
		||||
            this.value.content.split('##').forEach((value) => {
 | 
			
		||||
                const x = this.options.findIndex((option) => value == option.key);
 | 
			
		||||
                if (x >= 0) {
 | 
			
		||||
                    values.push(value);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.searchMode) {
 | 
			
		||||
            this.addControl('f_' + this.field.id + '_allreq');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.addControl('f_' + this.field.id, values);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected updateValue(value?: Partial<AddonModDataEntryField>): void {
 | 
			
		||||
        this.value = value || {};
 | 
			
		||||
        this.value.content = value?.content && value.content.split('##').join('<br>');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/addons/mod/data/fields/multimenu/multimenu.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/addons/mod/data/fields/multimenu/multimenu.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// (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 { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
import { AddonModDataFieldMultimenuComponent } from './component/multimenu';
 | 
			
		||||
import { AddonModDataFieldMultimenuHandler } from './services/handler';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AddonModDataFieldMultimenuComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            deps: [],
 | 
			
		||||
            useFactory: () => () => {
 | 
			
		||||
                AddonModDataFieldsDelegate.registerHandler(AddonModDataFieldMultimenuHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        AddonModDataFieldMultimenuComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldMultimenuModule {}
 | 
			
		||||
							
								
								
									
										127
									
								
								src/addons/mod/data/fields/multimenu/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								src/addons/mod/data/fields/multimenu/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,127 @@
 | 
			
		||||
// (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 {
 | 
			
		||||
    AddonModDataEntryField,
 | 
			
		||||
    AddonModDataField,
 | 
			
		||||
    AddonModDataSearchEntriesAdvancedFieldFormatted,
 | 
			
		||||
    AddonModDataSubfieldData,
 | 
			
		||||
} from '@addons/mod/data/services/data';
 | 
			
		||||
import { AddonModDataFieldHandler } from '@addons/mod/data/services/data-fields-delegate';
 | 
			
		||||
import { Injectable, Type } from '@angular/core';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldMultimenuComponent } from '../component/multimenu';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for multimenu data field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonModDataFieldMultimenuHandlerService implements AddonModDataFieldHandler {
 | 
			
		||||
 | 
			
		||||
    name = 'AddonModDataFieldMultimenuHandler';
 | 
			
		||||
    type = 'multimenu';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getComponent(): Type<unknown>{
 | 
			
		||||
        return AddonModDataFieldMultimenuComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldSearchData(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string[]>,
 | 
			
		||||
    ): AddonModDataSearchEntriesAdvancedFieldFormatted[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        const reqName = 'f_' + field.id + '_allreq';
 | 
			
		||||
 | 
			
		||||
        if (inputData[fieldName]) {
 | 
			
		||||
 | 
			
		||||
            const values: AddonModDataSearchEntriesAdvancedFieldFormatted[] = [];
 | 
			
		||||
            values.push({
 | 
			
		||||
                name: fieldName,
 | 
			
		||||
                value: inputData[fieldName],
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            if (inputData[reqName]) {
 | 
			
		||||
                values.push({
 | 
			
		||||
                    name: reqName,
 | 
			
		||||
                    value: true,
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return values;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditData(field: AddonModDataField, inputData: CoreFormFields<string[]>): AddonModDataSubfieldData[] {
 | 
			
		||||
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        return [{
 | 
			
		||||
            fieldid: field.id,
 | 
			
		||||
            value: inputData[fieldName] || [],
 | 
			
		||||
        }];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    hasFieldDataChanged(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string[]>,
 | 
			
		||||
        originalFieldData: AddonModDataEntryField,
 | 
			
		||||
    ): boolean {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        const content = originalFieldData?.content || '';
 | 
			
		||||
 | 
			
		||||
        return inputData[fieldName].join('##') != content;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldsNotifications(field: AddonModDataField, inputData: AddonModDataSubfieldData[]): string | undefined {
 | 
			
		||||
        if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string[]>): AddonModDataEntryField {
 | 
			
		||||
        originalContent.content = (offlineContent[''] && offlineContent[''].join('##')) || '';
 | 
			
		||||
 | 
			
		||||
        return originalContent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async isEnabled(): Promise<boolean> {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export const AddonModDataFieldMultimenuHandler = makeSingleton(AddonModDataFieldMultimenuHandlerService);
 | 
			
		||||
@ -0,0 +1,7 @@
 | 
			
		||||
<span *ngIf="inputMode && form" [formGroup]="form">
 | 
			
		||||
    <span *ngIf="editMode" [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
			
		||||
    <ion-input type="number" [formControlName]="'f_'+field.id" [placeholder]="field.name"></ion-input>
 | 
			
		||||
    <core-input-errors *ngIf="error && editMode" [control]="form.controls['f_'+field.id]" [errorText]="error"></core-input-errors>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<span *ngIf="displayMode && value && value.content">{{ value.content }}</span>
 | 
			
		||||
							
								
								
									
										44
									
								
								src/addons/mod/data/fields/number/component/number.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/addons/mod/data/fields/number/component/number.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
			
		||||
// (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 { Component } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render data number field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-number',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-number.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldNumberComponent extends AddonModDataFieldPluginComponent{
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        if (this.displayMode) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let value: number | string | undefined;
 | 
			
		||||
        if (this.editMode && this.value) {
 | 
			
		||||
            const v = parseFloat(this.value.content || '');
 | 
			
		||||
            value = isNaN(v) ? '' : v;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.addControl('f_' + this.field.id, value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/addons/mod/data/fields/number/number.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/addons/mod/data/fields/number/number.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// (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 { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
import { AddonModDataFieldNumberComponent } from './component/number';
 | 
			
		||||
import { AddonModDataFieldNumberHandler } from './services/handler';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AddonModDataFieldNumberComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            deps: [],
 | 
			
		||||
            useFactory: () => () => {
 | 
			
		||||
                AddonModDataFieldsDelegate.registerHandler(AddonModDataFieldNumberHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        AddonModDataFieldNumberComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldNumberModule {}
 | 
			
		||||
							
								
								
									
										63
									
								
								src/addons/mod/data/fields/number/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/addons/mod/data/fields/number/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
			
		||||
// (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 { AddonModDataEntryField, AddonModDataField, AddonModDataSubfieldData } from '@addons/mod/data/services/data';
 | 
			
		||||
import { Injectable, Type } from '@angular/core';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldTextHandlerService } from '../../text/services/handler';
 | 
			
		||||
import { AddonModDataFieldNumberComponent } from '../component/number';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for number data field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonModDataFieldNumberHandlerService extends AddonModDataFieldTextHandlerService {
 | 
			
		||||
 | 
			
		||||
    name = 'AddonModDataFieldNumberHandler';
 | 
			
		||||
    type = 'number';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getComponent(): Type<unknown>{
 | 
			
		||||
        return AddonModDataFieldNumberComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    hasFieldDataChanged(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields,
 | 
			
		||||
        originalFieldData: AddonModDataEntryField,
 | 
			
		||||
    ): boolean {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        const input = inputData[fieldName] || '';
 | 
			
		||||
        const content = originalFieldData?.content || '';
 | 
			
		||||
 | 
			
		||||
        return input != content;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldsNotifications(field: AddonModDataField, inputData: AddonModDataSubfieldData[]): string | undefined {
 | 
			
		||||
        if (field.required && (!inputData || !inputData.length || inputData[0].value == '')) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export const AddonModDataFieldNumberHandler = makeSingleton(AddonModDataFieldNumberHandlerService);
 | 
			
		||||
@ -0,0 +1,22 @@
 | 
			
		||||
<span *ngIf="editMode && form" [formGroup]="form">
 | 
			
		||||
    <span [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
			
		||||
    <core-attachments [files]="files" [maxSize]="maxSizeBytes" maxSubmissions="1" [component]="component"
 | 
			
		||||
        [componentId]="componentId" [allowOffline]="true" acceptedTypes="image">
 | 
			
		||||
    </core-attachments>
 | 
			
		||||
    <core-input-errors *ngIf="error" [errorText]="error"></core-input-errors>
 | 
			
		||||
 | 
			
		||||
    <ion-label position="stacked">{{ 'addon.mod_data.alttext' | translate }}</ion-label>
 | 
			
		||||
    <ion-input type="text" [formControlName]="'f_'+field.id+'_alttext'" [placeholder]=" 'addon.mod_data.alttext' | translate" >
 | 
			
		||||
    </ion-input>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<span *ngIf="searchMode && form" [formGroup]="form">
 | 
			
		||||
    <ion-input type="text" [formControlName]="'f_'+field.id" [placeholder]="field.name"></ion-input>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<span *ngIf="listMode && imageUrl" (click)="gotoEntry.emit(entryId)">
 | 
			
		||||
    <img [src]="imageUrl" [alt]="title" class="core-media-adapt-width listMode_picture" core-external-content/>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<img *ngIf="showMode && imageUrl" [src]="imageUrl" [alt]="title" class="core-media-adapt-width listMode_picture"
 | 
			
		||||
    [attr.width]="width" [attr.height]="height" core-external-content/>
 | 
			
		||||
							
								
								
									
										142
									
								
								src/addons/mod/data/fields/picture/component/picture.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								src/addons/mod/data/fields/picture/component/picture.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,142 @@
 | 
			
		||||
// (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 { AddonModDataEntryField, AddonModDataProvider } from '@addons/mod/data/services/data';
 | 
			
		||||
import { Component } from '@angular/core';
 | 
			
		||||
import { FileEntry } from '@ionic-native/file';
 | 
			
		||||
import { CoreFileSession } from '@services/file-session';
 | 
			
		||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
			
		||||
import { CoreWSExternalFile } from '@services/ws';
 | 
			
		||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render data picture field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-picture',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-picture.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldPictureComponent extends AddonModDataFieldPluginComponent {
 | 
			
		||||
 | 
			
		||||
    files: (CoreWSExternalFile | FileEntry)[] = [];
 | 
			
		||||
    component?: string;
 | 
			
		||||
    componentId?: number;
 | 
			
		||||
    maxSizeBytes?: number;
 | 
			
		||||
 | 
			
		||||
    image?: CoreWSExternalFile | FileEntry;
 | 
			
		||||
    entryId?: number;
 | 
			
		||||
    imageUrl?: string;
 | 
			
		||||
    title?: string;
 | 
			
		||||
    width?: string;
 | 
			
		||||
    height?: string;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the files from the input value.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value Input value.
 | 
			
		||||
     * @return List of files.
 | 
			
		||||
     */
 | 
			
		||||
    protected getFiles(value?: Partial<AddonModDataEntryField>): (CoreWSExternalFile | FileEntry)[] {
 | 
			
		||||
        let files = value?.files || [];
 | 
			
		||||
 | 
			
		||||
        // Reduce to first element.
 | 
			
		||||
        if (files.length > 0) {
 | 
			
		||||
            files = [files[0]];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return files;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Find file in a list.
 | 
			
		||||
     *
 | 
			
		||||
     * @param files File list where to search.
 | 
			
		||||
     * @param filenameSeek Filename to search.
 | 
			
		||||
     * @return File found or false.
 | 
			
		||||
     */
 | 
			
		||||
    protected findFile(
 | 
			
		||||
        files: (CoreWSExternalFile | FileEntry)[],
 | 
			
		||||
        filenameSeek: string,
 | 
			
		||||
    ): CoreWSExternalFile | FileEntry | undefined {
 | 
			
		||||
        return files.find((file) => ('name' in file ? file.name : file.filename) == filenameSeek) || undefined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        if (this.searchMode) {
 | 
			
		||||
            this.addControl('f_' + this.field.id);
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.component = AddonModDataProvider.COMPONENT;
 | 
			
		||||
        this.componentId = this.database!.coursemodule;
 | 
			
		||||
 | 
			
		||||
        this.updateValue(this.value);
 | 
			
		||||
 | 
			
		||||
        if (this.editMode) {
 | 
			
		||||
            this.maxSizeBytes = parseInt(this.field.param3, 10);
 | 
			
		||||
            CoreFileSession.setFiles(this.component, this.database!.id + '_' + this.field.id, this.files);
 | 
			
		||||
 | 
			
		||||
            const alttext = (this.value && this.value.content1) || '';
 | 
			
		||||
            this.addControl('f_' + this.field.id + '_alttext', alttext);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected updateValue(value?: Partial<AddonModDataEntryField>): void {
 | 
			
		||||
 | 
			
		||||
        // Edit mode, the list shouldn't change so there is no need to watch it.
 | 
			
		||||
        const files = value?.files || [];
 | 
			
		||||
 | 
			
		||||
        // Get image or thumb.
 | 
			
		||||
        if (files.length > 0) {
 | 
			
		||||
            const filenameSeek = this.listMode
 | 
			
		||||
                ? 'thumb_' + value?.content
 | 
			
		||||
                : value?.content;
 | 
			
		||||
            this.image = this.findFile(files, filenameSeek || '');
 | 
			
		||||
 | 
			
		||||
            if (!this.image && this.listMode) {
 | 
			
		||||
                this.image = this.findFile(files, value?.content || '');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (this.image) {
 | 
			
		||||
                this.files = [this.image];
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            this.image = undefined;
 | 
			
		||||
            this.files = [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this.editMode) {
 | 
			
		||||
            this.entryId = (value && value.recordid) || undefined;
 | 
			
		||||
            this.title = (value && value.content1) || '';
 | 
			
		||||
            this.imageUrl = undefined;
 | 
			
		||||
            setTimeout(() => {
 | 
			
		||||
                if (this.image) {
 | 
			
		||||
                    this.imageUrl = 'name' in this.image
 | 
			
		||||
                        ? this.image.toURL() // Is Offline.
 | 
			
		||||
                        : this.image.fileurl;
 | 
			
		||||
                }
 | 
			
		||||
            }, 1);
 | 
			
		||||
 | 
			
		||||
            this.width  = CoreDomUtils.formatPixelsSize(this.field.param1);
 | 
			
		||||
            this.height = CoreDomUtils.formatPixelsSize(this.field.param2);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/addons/mod/data/fields/picture/picture.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/addons/mod/data/fields/picture/picture.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// (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 { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
import { AddonModDataFieldPictureComponent } from './component/picture';
 | 
			
		||||
import { AddonModDataFieldPictureHandler } from './services/handler';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AddonModDataFieldPictureComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            deps: [],
 | 
			
		||||
            useFactory: () => () => {
 | 
			
		||||
                AddonModDataFieldsDelegate.registerHandler(AddonModDataFieldPictureHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        AddonModDataFieldPictureComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldPictureModule {}
 | 
			
		||||
							
								
								
									
										181
									
								
								src/addons/mod/data/fields/picture/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								src/addons/mod/data/fields/picture/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,181 @@
 | 
			
		||||
// (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 {
 | 
			
		||||
    AddonModDataEntryField,
 | 
			
		||||
    AddonModDataField,
 | 
			
		||||
    AddonModDataProvider,
 | 
			
		||||
    AddonModDataSearchEntriesAdvancedFieldFormatted,
 | 
			
		||||
    AddonModDataSubfieldData,
 | 
			
		||||
} from '@addons/mod/data/services/data';
 | 
			
		||||
import { AddonModDataFieldHandler } from '@addons/mod/data/services/data-fields-delegate';
 | 
			
		||||
import { Injectable, Type } from '@angular/core';
 | 
			
		||||
import { CoreFileUploader, CoreFileUploaderStoreFilesResult } from '@features/fileuploader/services/fileuploader';
 | 
			
		||||
import { FileEntry } from '@ionic-native/file';
 | 
			
		||||
import { CoreFileSession } from '@services/file-session';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { CoreWSExternalFile } from '@services/ws';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldPictureComponent } from '../component/picture';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for picture data field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonModDataFieldPictureHandlerService implements AddonModDataFieldHandler {
 | 
			
		||||
 | 
			
		||||
    name = 'AddonModDataFieldPictureHandler';
 | 
			
		||||
    type = 'picture';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getComponent(): Type<unknown>{
 | 
			
		||||
        return AddonModDataFieldPictureComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldSearchData(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
    ): AddonModDataSearchEntriesAdvancedFieldFormatted[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        if (inputData[fieldName]) {
 | 
			
		||||
            return [{
 | 
			
		||||
                name: fieldName,
 | 
			
		||||
                value: inputData[fieldName],
 | 
			
		||||
            }];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditData(field: AddonModDataField, inputData: CoreFormFields<string>): AddonModDataSubfieldData[] {
 | 
			
		||||
        const files = this.getFieldEditFiles(field);
 | 
			
		||||
        const fieldName = 'f_' + field.id + '_alttext';
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                subfield: 'file',
 | 
			
		||||
                files: files,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                subfield: 'alttext',
 | 
			
		||||
                value: inputData[fieldName],
 | 
			
		||||
            },
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditFiles(field: AddonModDataField): (CoreWSExternalFile | FileEntry)[] {
 | 
			
		||||
        return CoreFileSession.getFiles(AddonModDataProvider.COMPONENT,  field.dataid + '_' + field.id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    hasFieldDataChanged(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
        originalFieldData: AddonModDataEntryField,
 | 
			
		||||
    ): boolean {
 | 
			
		||||
        const fieldName = 'f_' + field.id + '_alttext';
 | 
			
		||||
        const altText = inputData[fieldName] || '';
 | 
			
		||||
        const originalAltText = originalFieldData?.content1 || '';
 | 
			
		||||
        if (altText != originalAltText) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const files = this.getFieldEditFiles(field) || [];
 | 
			
		||||
        let originalFiles = originalFieldData?.files || [];
 | 
			
		||||
 | 
			
		||||
        // Get image.
 | 
			
		||||
        if (originalFiles.length > 0) {
 | 
			
		||||
            const filenameSeek = originalFieldData?.content || '';
 | 
			
		||||
            const file = originalFiles.find((file) => ('name' in file ? file.name : file.filename) == filenameSeek);
 | 
			
		||||
            if (file) {
 | 
			
		||||
                originalFiles = [file];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return CoreFileUploader.areFileListDifferent(files, originalFiles);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldsNotifications(field: AddonModDataField, inputData: AddonModDataSubfieldData[]): string | undefined {
 | 
			
		||||
        if (!field.required) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!inputData || !inputData.length) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const found = inputData.some((input) => {
 | 
			
		||||
            if (typeof input.subfield != 'undefined' && input.subfield == 'file') {
 | 
			
		||||
                return !!input.value;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (!found) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    overrideData(
 | 
			
		||||
        originalContent: AddonModDataEntryField,
 | 
			
		||||
        offlineContent: CoreFormFields,
 | 
			
		||||
        offlineFiles?: FileEntry[],
 | 
			
		||||
    ): AddonModDataEntryField {
 | 
			
		||||
        const uploadedFilesResult: CoreFileUploaderStoreFilesResult = <CoreFileUploaderStoreFilesResult>offlineContent?.file;
 | 
			
		||||
 | 
			
		||||
        if (uploadedFilesResult && uploadedFilesResult.offline > 0 && offlineFiles && offlineFiles?.length > 0) {
 | 
			
		||||
            originalContent.content = offlineFiles[0].name;
 | 
			
		||||
            originalContent.files = [offlineFiles[0]];
 | 
			
		||||
        } else if (uploadedFilesResult && uploadedFilesResult.online && uploadedFilesResult.online.length > 0) {
 | 
			
		||||
            originalContent.content = uploadedFilesResult.online[0].filename || '';
 | 
			
		||||
            originalContent.files = [uploadedFilesResult.online[0]];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        originalContent.content1 = <string>offlineContent.alttext || '';
 | 
			
		||||
 | 
			
		||||
        return originalContent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async isEnabled(): Promise<boolean> {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export const AddonModDataFieldPictureHandler = makeSingleton(AddonModDataFieldPictureHandlerService);
 | 
			
		||||
@ -0,0 +1,11 @@
 | 
			
		||||
<span *ngIf="inputMode && form" [formGroup]="form">
 | 
			
		||||
    <span *ngIf="editMode" [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
			
		||||
    <ion-select [formControlName]="'f_'+field.id" [placeholder]="'addon.mod_data.menuchoose' | translate"
 | 
			
		||||
        [interfaceOptions]="{header: field.name}" interface="alert">
 | 
			
		||||
        <ion-select-option value="">{{ 'addon.mod_data.menuchoose' | translate }}</ion-select-option>
 | 
			
		||||
        <ion-select-option *ngFor="let option of options" [value]="option">{{option}}</ion-select-option>
 | 
			
		||||
    </ion-select>
 | 
			
		||||
    <core-input-errors *ngIf="error && editMode" [control]="form.controls['f_'+field.id]" [errorText]="error"></core-input-errors>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<span *ngIf="displayMode && value && value.content">{{ value.content }}</span>
 | 
			
		||||
@ -0,0 +1,46 @@
 | 
			
		||||
// (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 { Component } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render data radiobutton field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-radiobutton',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-radiobutton.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldRadiobuttonComponent extends AddonModDataFieldPluginComponent {
 | 
			
		||||
 | 
			
		||||
    options: string[] = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Initialize field.
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        if (this.displayMode) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.options = this.field.param1.split('\n');
 | 
			
		||||
 | 
			
		||||
        let val: string | undefined;
 | 
			
		||||
        if (this.editMode && this.value) {
 | 
			
		||||
            val = this.value.content;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.addControl('f_' + this.field.id, val);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/addons/mod/data/fields/radiobutton/radiobutton.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/addons/mod/data/fields/radiobutton/radiobutton.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// (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 { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
import { AddonModDataFieldRadiobuttonComponent } from './component/radiobutton';
 | 
			
		||||
import { AddonModDataFieldRadiobuttonHandler } from './services/handler';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AddonModDataFieldRadiobuttonComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            deps: [],
 | 
			
		||||
            useFactory: () => () => {
 | 
			
		||||
                AddonModDataFieldsDelegate.registerHandler(AddonModDataFieldRadiobuttonHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        AddonModDataFieldRadiobuttonComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldRadiobuttonModule {}
 | 
			
		||||
							
								
								
									
										114
									
								
								src/addons/mod/data/fields/radiobutton/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/addons/mod/data/fields/radiobutton/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,114 @@
 | 
			
		||||
// (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 {
 | 
			
		||||
    AddonModDataEntryField,
 | 
			
		||||
    AddonModDataField,
 | 
			
		||||
    AddonModDataSearchEntriesAdvancedFieldFormatted,
 | 
			
		||||
    AddonModDataSubfieldData,
 | 
			
		||||
} from '@addons/mod/data/services/data';
 | 
			
		||||
import { AddonModDataFieldHandler } from '@addons/mod/data/services/data-fields-delegate';
 | 
			
		||||
import { Injectable, Type } from '@angular/core';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldRadiobuttonComponent } from '../component/radiobutton';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for checkbox data field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonModDataFieldRadiobuttonHandlerService implements AddonModDataFieldHandler {
 | 
			
		||||
 | 
			
		||||
    name = 'AddonModDataFieldRadiobuttonHandler';
 | 
			
		||||
    type = 'radiobutton';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getComponent(): Type<unknown>{
 | 
			
		||||
        return AddonModDataFieldRadiobuttonComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldSearchData(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
    ): AddonModDataSearchEntriesAdvancedFieldFormatted[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        if (inputData[fieldName]) {
 | 
			
		||||
            return [{
 | 
			
		||||
                name: fieldName,
 | 
			
		||||
                value: inputData[fieldName],
 | 
			
		||||
            }];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditData(field: AddonModDataField, inputData: CoreFormFields<string>): AddonModDataSubfieldData[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        return [{
 | 
			
		||||
            fieldid: field.id,
 | 
			
		||||
            value: inputData[fieldName] || '',
 | 
			
		||||
        }];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    hasFieldDataChanged(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
        originalFieldData: AddonModDataEntryField,
 | 
			
		||||
    ): boolean {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        const input = inputData[fieldName] || '';
 | 
			
		||||
        const content = originalFieldData?.content || '';
 | 
			
		||||
 | 
			
		||||
        return input != content;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldsNotifications(field: AddonModDataField, inputData: AddonModDataSubfieldData[]): string | undefined {
 | 
			
		||||
        if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string>): AddonModDataEntryField {
 | 
			
		||||
        originalContent.content = offlineContent[''] || '';
 | 
			
		||||
 | 
			
		||||
        return originalContent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async isEnabled(): Promise<boolean> {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export const AddonModDataFieldRadiobuttonHandler = makeSingleton(AddonModDataFieldRadiobuttonHandlerService);
 | 
			
		||||
@ -0,0 +1,7 @@
 | 
			
		||||
<span *ngIf="inputMode && form" [formGroup]="form">
 | 
			
		||||
    <span *ngIf="editMode" [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
			
		||||
    <ion-input type="text" [formControlName]="'f_'+field.id" [placeholder]="field.name"></ion-input>
 | 
			
		||||
    <core-input-errors *ngIf="error && editMode" [control]="form.controls['f_'+field.id]" [errorText]="error"></core-input-errors>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<span *ngIf="displayMode && value && value.content">{{ value.content }}</span>
 | 
			
		||||
							
								
								
									
										43
									
								
								src/addons/mod/data/fields/text/component/text.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/addons/mod/data/fields/text/component/text.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
// (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 { Component } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render data text field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-text',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-text.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldTextComponent extends AddonModDataFieldPluginComponent {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        if (this.displayMode) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let value: string | undefined;
 | 
			
		||||
        if (this.editMode && this.value) {
 | 
			
		||||
            value = this.value.content;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.addControl('f_' + this.field.id, value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										117
									
								
								src/addons/mod/data/fields/text/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								src/addons/mod/data/fields/text/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,117 @@
 | 
			
		||||
// (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 {
 | 
			
		||||
    AddonModDataEntryField,
 | 
			
		||||
    AddonModDataField,
 | 
			
		||||
    AddonModDataSearchEntriesAdvancedFieldFormatted,
 | 
			
		||||
    AddonModDataSubfieldData,
 | 
			
		||||
} from '@addons/mod/data/services/data';
 | 
			
		||||
import { AddonModDataFieldHandler } from '@addons/mod/data/services/data-fields-delegate';
 | 
			
		||||
import { Injectable, Type } from '@angular/core';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldTextComponent } from '../component/text';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for number data field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonModDataFieldTextHandlerService implements AddonModDataFieldHandler {
 | 
			
		||||
 | 
			
		||||
    name = 'AddonModDataFieldTextHandler';
 | 
			
		||||
    type = 'text';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getComponent(): Type<unknown>{
 | 
			
		||||
        return AddonModDataFieldTextComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldSearchData(field: AddonModDataField, inputData: CoreFormFields): AddonModDataSearchEntriesAdvancedFieldFormatted[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        if (inputData[fieldName]) {
 | 
			
		||||
            return [{
 | 
			
		||||
                name: fieldName,
 | 
			
		||||
                value: inputData[fieldName],
 | 
			
		||||
            }];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditData(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
        originalFieldData: AddonModDataEntryField, // eslint-disable-line @typescript-eslint/no-unused-vars
 | 
			
		||||
    ): AddonModDataSubfieldData[] {
 | 
			
		||||
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        return [{
 | 
			
		||||
            fieldid: field.id,
 | 
			
		||||
            value: inputData[fieldName] || '',
 | 
			
		||||
        }];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    hasFieldDataChanged(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
        originalFieldData: AddonModDataEntryField,
 | 
			
		||||
    ): boolean {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        const input = inputData[fieldName] || '';
 | 
			
		||||
        const content = originalFieldData?.content || '';
 | 
			
		||||
 | 
			
		||||
        return input != content;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldsNotifications(field: AddonModDataField, inputData: AddonModDataSubfieldData[]): string | undefined {
 | 
			
		||||
        if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string>): AddonModDataEntryField {
 | 
			
		||||
        originalContent.content = offlineContent[''] || '';
 | 
			
		||||
 | 
			
		||||
        return originalContent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    async isEnabled(): Promise<boolean> {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export const AddonModDataFieldTextHandler = makeSingleton(AddonModDataFieldTextHandlerService);
 | 
			
		||||
							
								
								
									
										42
									
								
								src/addons/mod/data/fields/text/text.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/addons/mod/data/fields/text/text.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// (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 { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
import { AddonModDataFieldTextComponent } from './component/text';
 | 
			
		||||
import { AddonModDataFieldTextHandler } from './services/handler';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AddonModDataFieldTextComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            deps: [],
 | 
			
		||||
            useFactory: () => () => {
 | 
			
		||||
                AddonModDataFieldsDelegate.registerHandler(AddonModDataFieldTextHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        AddonModDataFieldTextComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldTextModule {}
 | 
			
		||||
@ -0,0 +1,14 @@
 | 
			
		||||
<span *ngIf="inputMode && form" [formGroup]="form">
 | 
			
		||||
    <ion-input *ngIf="searchMode" type="text" [placeholder]="field.name" [formControlName]="'f_'+field.id"></ion-input>
 | 
			
		||||
 | 
			
		||||
    <span *ngIf="editMode" [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
			
		||||
    <core-rich-text-editor *ngIf="editMode" item-content [control]="form.controls['f_'+field.id]" [placeholder]="field.name"
 | 
			
		||||
        [formControlName]="'f_'+field.id" [component]="component" [componentId]="componentId" [autoSave]="true"
 | 
			
		||||
        contextLevel="module" [contextInstanceId]="componentId" [elementId]="'field_'+field.id" ngDefaultControl>
 | 
			
		||||
    </core-rich-text-editor>
 | 
			
		||||
    <core-input-errors *ngIf="error && editMode" [control]="form.controls['f_'+field.id]" [errorText]="error"></core-input-errors>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<core-format-text *ngIf="displayMode && value" [text]="format(value)" [component]="component" [componentId]="componentId"
 | 
			
		||||
    contextLevel="module" [contextInstanceId]="componentId" [courseId]="database!.course">
 | 
			
		||||
</core-format-text>
 | 
			
		||||
							
								
								
									
										65
									
								
								src/addons/mod/data/fields/textarea/component/textarea.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/addons/mod/data/fields/textarea/component/textarea.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
			
		||||
// (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 { Component } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
 | 
			
		||||
import { AddonModDataEntryField, AddonModDataProvider } from '@addons/mod/data/services/data';
 | 
			
		||||
import { CoreTextUtils } from '@services/utils/text';
 | 
			
		||||
import { CoreWSExternalFile } from '@services/ws';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render data number field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-textarea',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-textarea.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldTextareaComponent extends AddonModDataFieldPluginComponent {
 | 
			
		||||
 | 
			
		||||
    component?: string;
 | 
			
		||||
    componentId?: number;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Format value to be shown. Replacing plugin file Urls.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value Value to replace.
 | 
			
		||||
     * @return Replaced string to be rendered.
 | 
			
		||||
     */
 | 
			
		||||
    format(value?: Partial<AddonModDataEntryField>): string {
 | 
			
		||||
        const files: CoreWSExternalFile[] = (value && <CoreWSExternalFile[]>value.files) || [];
 | 
			
		||||
 | 
			
		||||
        return value ? CoreTextUtils.replacePluginfileUrls(value.content || '', files) : '';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Initialize field.
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        this.component = AddonModDataProvider.COMPONENT;
 | 
			
		||||
        this.componentId = this.database?.coursemodule;
 | 
			
		||||
 | 
			
		||||
        if (this.displayMode) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let text: string | undefined;
 | 
			
		||||
        // Check if rich text editor is enabled.
 | 
			
		||||
        if (this.editMode) {
 | 
			
		||||
            text = this.format(this.value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.addControl('f_' + this.field.id, text);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										127
									
								
								src/addons/mod/data/fields/textarea/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								src/addons/mod/data/fields/textarea/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,127 @@
 | 
			
		||||
// (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 { AddonModDataEntryField, AddonModDataField, AddonModDataSubfieldData } from '@addons/mod/data/services/data';
 | 
			
		||||
import { Injectable, Type } from '@angular/core';
 | 
			
		||||
import { FileEntry } from '@ionic-native/file';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { CoreTextUtils } from '@services/utils/text';
 | 
			
		||||
import { CoreWSExternalFile } from '@services/ws';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldTextHandlerService } from '../../text/services/handler';
 | 
			
		||||
import { AddonModDataFieldTextareaComponent } from '../component/textarea';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for textarea data field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonModDataFieldTextareaHandlerService extends AddonModDataFieldTextHandlerService {
 | 
			
		||||
 | 
			
		||||
    name = 'AddonModDataFieldTextareaHandler';
 | 
			
		||||
    type = 'textarea';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getComponent(): Type<unknown>{
 | 
			
		||||
        return AddonModDataFieldTextareaComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditData(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields<string>,
 | 
			
		||||
        originalFieldData: AddonModDataEntryField,
 | 
			
		||||
    ): AddonModDataSubfieldData[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
        const files = this.getFieldEditFiles(field, inputData, originalFieldData);
 | 
			
		||||
 | 
			
		||||
        let text = CoreTextUtils.restorePluginfileUrls(inputData[fieldName] || '', <CoreWSExternalFile[]>files);
 | 
			
		||||
        // Add some HTML to the text if needed.
 | 
			
		||||
        text = CoreTextUtils.formatHtmlLines(text);
 | 
			
		||||
 | 
			
		||||
        // WS does not properly check if HTML content is blank when the field is required.
 | 
			
		||||
        if (CoreTextUtils.htmlIsBlank(text)) {
 | 
			
		||||
            text = '';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                value: text,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                subfield: 'content1',
 | 
			
		||||
                value: 1,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                subfield: 'itemid',
 | 
			
		||||
                files: files,
 | 
			
		||||
            },
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditFiles(
 | 
			
		||||
        field: AddonModDataField,
 | 
			
		||||
        inputData: CoreFormFields,
 | 
			
		||||
        originalFieldData: AddonModDataEntryField,
 | 
			
		||||
    ): (CoreWSExternalFile | FileEntry)[] {
 | 
			
		||||
        return (originalFieldData && originalFieldData.files) || [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldsNotifications(field: AddonModDataField, inputData: AddonModDataSubfieldData[]): string | undefined {
 | 
			
		||||
        if (!field.required) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!inputData || !inputData.length) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const value = inputData.find((value) => value.subfield == '');
 | 
			
		||||
 | 
			
		||||
        if (!value || CoreTextUtils.htmlIsBlank(<string>value.value || '')) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    overrideData(originalContent: AddonModDataEntryField, offlineContent: CoreFormFields<string>): AddonModDataEntryField {
 | 
			
		||||
        originalContent.content = offlineContent[''] || '';
 | 
			
		||||
        if (originalContent.content.length > 0 && originalContent.files && originalContent.files.length > 0) {
 | 
			
		||||
            // Take the original files since we cannot edit them on the app.
 | 
			
		||||
            originalContent.content = CoreTextUtils.replacePluginfileUrls(
 | 
			
		||||
                originalContent.content,
 | 
			
		||||
                <CoreWSExternalFile[]>originalContent.files,
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return originalContent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export const AddonModDataFieldTextareaHandler = makeSingleton(AddonModDataFieldTextareaHandlerService);
 | 
			
		||||
							
								
								
									
										44
									
								
								src/addons/mod/data/fields/textarea/textarea.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/addons/mod/data/fields/textarea/textarea.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
			
		||||
// (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 { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
 | 
			
		||||
import { CoreEditorComponentsModule } from '@features/editor/components/components.module';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
import { AddonModDataFieldTextareaComponent } from './component/textarea';
 | 
			
		||||
import { AddonModDataFieldTextareaHandler } from './services/handler';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AddonModDataFieldTextareaComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
        CoreEditorComponentsModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            deps: [],
 | 
			
		||||
            useFactory: () => () => {
 | 
			
		||||
                AddonModDataFieldsDelegate.registerHandler(AddonModDataFieldTextareaHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        AddonModDataFieldTextareaComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldTextareaModule {}
 | 
			
		||||
@ -0,0 +1,10 @@
 | 
			
		||||
<span *ngIf="inputMode && form" [formGroup]="form">
 | 
			
		||||
    <span *ngIf="editMode" [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
			
		||||
    <ion-input type="url" [formControlName]="'f_'+field.id" [placeholder]="field.name"></ion-input>
 | 
			
		||||
    <core-input-errors *ngIf="error && editMode" [control]="form.controls['f_'+field.id]" [errorText]="error"></core-input-errors>
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
<ng-container *ngIf="displayMode && value && value.content">
 | 
			
		||||
    <a *ngIf="autoLink" [href]="value.content" core-link capture="true">{{ displayValue }}</a>
 | 
			
		||||
    <span *ngIf="!autoLink">{{ displayValue }}</span>
 | 
			
		||||
</ng-container>
 | 
			
		||||
							
								
								
									
										78
									
								
								src/addons/mod/data/fields/url/component/url.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/addons/mod/data/fields/url/component/url.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
			
		||||
// (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 { AddonModDataEntryField } from '@addons/mod/data/services/data';
 | 
			
		||||
import { Component } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render data url field.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'addon-mod-data-field-url',
 | 
			
		||||
    templateUrl: 'addon-mod-data-field-url.html',
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldUrlComponent extends AddonModDataFieldPluginComponent {
 | 
			
		||||
 | 
			
		||||
    autoLink = false;
 | 
			
		||||
    displayValue = '';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected init(): void {
 | 
			
		||||
        if (this.displayMode) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let value: string | undefined;
 | 
			
		||||
        if (this.editMode && this.value) {
 | 
			
		||||
            value = this.value.content;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.addControl('f_' + this.field.id, value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Calculate data for show or list mode.
 | 
			
		||||
     */
 | 
			
		||||
    protected calculateShowListData(): void {
 | 
			
		||||
        if (!this.value || !this.value.content) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const url = this.value.content;
 | 
			
		||||
        const text = this.field.param2 || this.value.content1; // Param2 forces the text to display.
 | 
			
		||||
 | 
			
		||||
        this.autoLink = parseInt(this.field.param1, 10) === 1;
 | 
			
		||||
 | 
			
		||||
        if (this.autoLink) {
 | 
			
		||||
            this.displayValue = text || url;
 | 
			
		||||
        } else {
 | 
			
		||||
            // No auto link, always display the URL.
 | 
			
		||||
            this.displayValue = url;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    protected updateValue(value?: Partial<AddonModDataEntryField>): void {
 | 
			
		||||
        super.updateValue(value);
 | 
			
		||||
 | 
			
		||||
        if (this.displayMode) {
 | 
			
		||||
            this.calculateShowListData();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								src/addons/mod/data/fields/url/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/addons/mod/data/fields/url/services/handler.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
			
		||||
// (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 { AddonModDataField, AddonModDataSubfieldData } from '@addons/mod/data/services/data';
 | 
			
		||||
import { Injectable, Type } from '@angular/core';
 | 
			
		||||
import { CoreFormFields } from '@singletons/form';
 | 
			
		||||
import { Translate, makeSingleton } from '@singletons';
 | 
			
		||||
import { AddonModDataFieldTextHandlerService } from '../../text/services/handler';
 | 
			
		||||
import { AddonModDataFieldUrlComponent } from '../component/url';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for url data field plugin.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonModDataFieldUrlHandlerService extends AddonModDataFieldTextHandlerService {
 | 
			
		||||
 | 
			
		||||
    name = 'AddonModDataFieldUrlHandler';
 | 
			
		||||
    type = 'url';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getComponent(): Type<unknown>{
 | 
			
		||||
        return AddonModDataFieldUrlComponent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditData(field: AddonModDataField, inputData: CoreFormFields<string>): AddonModDataSubfieldData[] {
 | 
			
		||||
        const fieldName = 'f_' + field.id;
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                subfield: '0',
 | 
			
		||||
                value: (inputData[fieldName] && inputData[fieldName].trim()) || '',
 | 
			
		||||
            },
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldsNotifications(field: AddonModDataField, inputData: AddonModDataSubfieldData[]): string | undefined {
 | 
			
		||||
        if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
 | 
			
		||||
            return Translate.instant('addon.mod_data.errormustsupplyvalue');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
export const AddonModDataFieldUrlHandler = makeSingleton(AddonModDataFieldUrlHandlerService);
 | 
			
		||||
							
								
								
									
										42
									
								
								src/addons/mod/data/fields/url/url.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/addons/mod/data/fields/url/url.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// (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 { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
 | 
			
		||||
import { AddonModDataFieldsDelegate } from '../../services/data-fields-delegate';
 | 
			
		||||
import { AddonModDataFieldUrlComponent } from './component/url';
 | 
			
		||||
import { AddonModDataFieldUrlHandler } from './services/handler';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        AddonModDataFieldUrlComponent,
 | 
			
		||||
    ],
 | 
			
		||||
    imports: [
 | 
			
		||||
        CoreSharedModule,
 | 
			
		||||
    ],
 | 
			
		||||
    providers: [
 | 
			
		||||
        {
 | 
			
		||||
            provide: APP_INITIALIZER,
 | 
			
		||||
            multi: true,
 | 
			
		||||
            deps: [],
 | 
			
		||||
            useFactory: () => () => {
 | 
			
		||||
                AddonModDataFieldsDelegate.registerHandler(AddonModDataFieldUrlHandler.instance);
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        AddonModDataFieldUrlComponent,
 | 
			
		||||
    ],
 | 
			
		||||
})
 | 
			
		||||
export class AddonModDataFieldUrlModule {}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user