MOBILE-2338 data: Add field plugins
parent
bbc6fcdff5
commit
661dbe2260
|
@ -13,6 +13,10 @@
|
|||
<allow-navigation href="data:*" />
|
||||
<allow-navigation href="*" />
|
||||
<allow-intent href="*" />
|
||||
<allow-intent href="tel:*" />
|
||||
<allow-intent href="sms:*" />
|
||||
<allow-intent href="mailto:*" />
|
||||
<allow-intent href="geo:*" />
|
||||
<preference name="orientation" value="default" />
|
||||
<preference name="target-device" value="universal" />
|
||||
<preference name="fullscreen" value="false" />
|
||||
|
|
|
@ -38,13 +38,13 @@ export class AddonModDataFieldPluginComponent implements OnInit {
|
|||
fieldLoaded: boolean;
|
||||
|
||||
constructor(protected injector: Injector, protected dataDelegate: AddonModDataFieldsDelegate,
|
||||
protected dataProvider: AddonModDataProvider) { }
|
||||
protected dataProvider: AddonModDataProvider) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
console.error('HERE');
|
||||
if (!this.field) {
|
||||
this.fieldLoaded = true;
|
||||
|
||||
|
@ -65,6 +65,7 @@ export class AddonModDataFieldPluginComponent implements OnInit {
|
|||
error: this.error,
|
||||
viewAction: this.viewAction
|
||||
};
|
||||
|
||||
} else {
|
||||
this.fieldLoaded = true;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
{{ cssTemplate }}
|
||||
</style>
|
||||
|
||||
<core-compile-html [text]="entriesRendered"></core-compile-html>
|
||||
<core-compile-html [text]="entriesRendered" [jsData]="jsData" [extraImports]="extraImports"></core-compile-html>
|
||||
</div>
|
||||
|
||||
<ion-grid *ngIf="search.page > 0 || hasNextPage">
|
||||
|
|
|
@ -1,3 +1,28 @@
|
|||
addon-mod-data-index {
|
||||
.core-data-contents {
|
||||
overflow: visible;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
padding: $content-padding;
|
||||
background-color: white;
|
||||
border-top-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-right-width: 0;
|
||||
border-left-width: 0;
|
||||
border-style: solid;
|
||||
border-color: $list-border-color;
|
||||
|
||||
table, tbody {
|
||||
display: block;
|
||||
}
|
||||
|
||||
tr {
|
||||
@extend .row;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
td, th {
|
||||
@extend .col;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ import { AddonModDataProvider } from '../../providers/data';
|
|||
import { AddonModDataHelperProvider } from '../../providers/helper';
|
||||
import { AddonModDataOfflineProvider } from '../../providers/offline';
|
||||
import { AddonModDataSyncProvider } from '../../providers/sync';
|
||||
import { AddonModDataComponentsModule } from '../components.module';
|
||||
import * as moment from 'moment';
|
||||
|
||||
/**
|
||||
|
@ -33,6 +34,7 @@ import * as moment from 'moment';
|
|||
templateUrl: 'index.html',
|
||||
})
|
||||
export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComponent {
|
||||
|
||||
component = AddonModDataProvider.COMPONENT;
|
||||
moduleName = 'data';
|
||||
|
||||
|
@ -65,13 +67,16 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
offlineEntries: any;
|
||||
entriesRendered = '';
|
||||
cssTemplate = '';
|
||||
extraImports = [AddonModDataComponentsModule];
|
||||
jsData;
|
||||
|
||||
protected syncEventName = AddonModDataSyncProvider.AUTO_SYNCED;
|
||||
protected entryChangedObserver: any;
|
||||
protected hasComments = false;
|
||||
protected fieldsArray: any;
|
||||
|
||||
constructor(injector: Injector, private dataProvider: AddonModDataProvider, private dataHelper: AddonModDataHelperProvider,
|
||||
private dataOffline: AddonModDataOfflineProvider, @Optional() private content: Content,
|
||||
private dataOffline: AddonModDataOfflineProvider, @Optional() @Optional() content: Content,
|
||||
private dataSync: AddonModDataSyncProvider, private timeUtils: CoreTimeUtilsProvider,
|
||||
private groupsProvider: CoreGroupsProvider, private commentsProvider: CoreCommentsProvider,
|
||||
private modalCtrl: ModalController, private utils: CoreUtilsProvider) {
|
||||
|
@ -216,8 +221,8 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
fields.forEach((field) => {
|
||||
this.fields[field.id] = field;
|
||||
});
|
||||
this.fields = this.utils.objectToArray(this.fields);
|
||||
this.advancedSearch = this.dataHelper.displayAdvancedSearchFields(this.data.asearchtemplate, this.fields);
|
||||
this.fieldsArray = this.utils.objectToArray(this.fields);
|
||||
this.advancedSearch = this.dataHelper.displayAdvancedSearchFields(this.data.asearchtemplate, this.fieldsArray);
|
||||
|
||||
return this.fetchEntriesData();
|
||||
});
|
||||
|
@ -283,7 +288,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
};
|
||||
|
||||
if (offlineActions.length > 0) {
|
||||
promises.push(this.dataHelper.applyOfflineActions(entry, offlineActions, this.fields));
|
||||
promises.push(this.dataHelper.applyOfflineActions(entry, offlineActions, this.fieldsArray));
|
||||
} else {
|
||||
promises.push(Promise.resolve(entry));
|
||||
}
|
||||
|
@ -299,7 +304,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
entry.contents = contents;
|
||||
|
||||
if (typeof this.offlineActions[entry.id] != 'undefined') {
|
||||
promises.push(this.dataHelper.applyOfflineActions(entry, this.offlineActions[entry.id], this.fields));
|
||||
promises.push(this.dataHelper.applyOfflineActions(entry, this.offlineActions[entry.id], this.fieldsArray));
|
||||
} else {
|
||||
promises.push(Promise.resolve(entry));
|
||||
}
|
||||
|
@ -318,12 +323,19 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
|
||||
const actions = this.dataHelper.getActions(this.data, this.access, entry);
|
||||
|
||||
entriesHTML += this.dataHelper.displayShowFields(this.data.listtemplate, this.fields, entry, 'list',
|
||||
entriesHTML += this.dataHelper.displayShowFields(this.data.listtemplate, this.fieldsArray, entry, 'list',
|
||||
actions);
|
||||
});
|
||||
entriesHTML += this.data.listtemplatefooter || '';
|
||||
|
||||
this.entriesRendered = entriesHTML;
|
||||
|
||||
// Pass the input data to the component.
|
||||
this.jsData = {
|
||||
fields: this.fields,
|
||||
entries: this.entries,
|
||||
data: this.data
|
||||
};
|
||||
});
|
||||
} else if (!this.search.searching) {
|
||||
// Empty and no searching.
|
||||
|
@ -356,7 +368,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
|
||||
if (this.search.searchingAdvanced) {
|
||||
this.search.advanced = this.dataHelper.getSearchDataFromForm(document.forms['addon-mod_data-advanced-search-form'],
|
||||
this.fields);
|
||||
this.fieldsArray);
|
||||
this.search.searching = this.search.advanced.length > 0;
|
||||
} else {
|
||||
this.search.searching = this.search.text.length > 0;
|
||||
|
|
|
@ -32,7 +32,6 @@ export class AddonModDataFieldCheckboxComponent extends AddonModDataFieldPluginC
|
|||
|
||||
constructor(protected fb: FormBuilder, protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
|
||||
element: ElementRef) {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
|
@ -46,7 +45,7 @@ export class AddonModDataFieldCheckboxComponent extends AddonModDataFieldPluginC
|
|||
|
||||
protected render(): void {
|
||||
if (this.mode == 'show') {
|
||||
this.value.content.split('##').join('<br>');
|
||||
this.value.content = this.value.content.split('##').join('<br>');
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ export class AddonModDataFieldCheckboxHandler implements AddonModDataFieldHandle
|
|||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
console.error(AddonModDataFieldCheckboxComponent);
|
||||
return AddonModDataFieldCheckboxComponent;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<span *ngIf="mode == 'edit'" [core-mark-required]="field.required"></span>
|
||||
<ion-datetime *ngIf="mode != 'show'" [formControlName]="'f_'+field.id" [placeholder]="'core.date' | translate" [disabled]="!enable && mode == 'search'"></ion-datetime>
|
||||
<core-input-errors *ngIf="error && mode == 'edit'" [control]="form.controls['f_'+field.id]" [errorMessages]="errors"></core-input-errors>
|
||||
|
||||
<ion-item *ngIf="mode == 'search'" [formGroup]="form">
|
||||
<ion-label>{{ 'addon.mod_data.usedate' | translate }}</ion-label>
|
||||
<ion-checkbox item-end [formControlName]="'f_'+field.id+'_z'" [(ngModel)]="values['f_'+field.id+'_z']">
|
||||
</ion-checkbox>
|
||||
</ion-item>
|
||||
|
||||
<core-format-text *ngIf="mode == 'show' && value && value.content" [text]="value.content * 1000 | coreFormatDate:'dfdaymonthyear'"></core-format-text>
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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, ElementRef } from '@angular/core';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
|
||||
|
||||
/**
|
||||
* Component to render data date field.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-data-field-date',
|
||||
templateUrl: 'date.html'
|
||||
})
|
||||
export class AddonModDataFieldDateComponent extends AddonModDataFieldPluginComponent implements OnInit {
|
||||
|
||||
control: FormControl;
|
||||
values = {};
|
||||
enable: boolean;
|
||||
val: any;
|
||||
|
||||
constructor(protected fb: FormBuilder, protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
|
||||
element: ElementRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.mode = this.mode == 'list' ? 'show' : this.mode;
|
||||
this.render();
|
||||
}
|
||||
|
||||
protected render(): void {
|
||||
if (this.mode == 'show') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.mode == 'edit' && this.value) {
|
||||
this.enable = true;
|
||||
} else {
|
||||
this.value = {
|
||||
content: Math.floor(Date.now() / 1000)
|
||||
};
|
||||
this.enable = false;
|
||||
}
|
||||
|
||||
this.val = new Date(this.value.content * 1000);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldDateHandler } from './providers/handler';
|
||||
import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate';
|
||||
import { AddonModDataFieldDateComponent } from './component/date';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
import { CorePipesModule } from '@pipes/pipes.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModDataFieldDateComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule,
|
||||
CorePipesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModDataFieldDateHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModDataFieldDateComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModDataFieldDateComponent
|
||||
]
|
||||
})
|
||||
export class AddonModDataFieldDateModule {
|
||||
constructor(fieldDelegate: AddonModDataFieldsDelegate, handler: AddonModDataFieldDateHandler) {
|
||||
fieldDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector, Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldHandler } from '../../../providers/fields-delegate';
|
||||
import { AddonModDataFieldDateComponent } from '../component/date';
|
||||
|
||||
/**
|
||||
* Handler for date data field plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModDataFieldDateHandler implements AddonModDataFieldHandler {
|
||||
name = 'AddonModDataFieldDateHandler';
|
||||
type = 'date';
|
||||
|
||||
constructor(private translate: TranslateService) { }
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} field The field object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModDataFieldDateComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field search data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the search form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldSearchData(field: any, inputData: any): any {
|
||||
const fieldName = 'f_' + field.id,
|
||||
enabledName = 'f_' + field.id + '_z';
|
||||
|
||||
if (inputData[enabledName]['1']) {
|
||||
const values = [],
|
||||
date = inputData[fieldName].split('-'),
|
||||
year = date[0],
|
||||
month = date[1],
|
||||
day = date[2];
|
||||
values.push({
|
||||
name: fieldName + '_y',
|
||||
value: year
|
||||
});
|
||||
values.push({
|
||||
name: fieldName + '_m',
|
||||
value: month
|
||||
});
|
||||
values.push({
|
||||
name: fieldName + '_d',
|
||||
value: day
|
||||
});
|
||||
values.push({
|
||||
name: enabledName,
|
||||
value: 1
|
||||
});
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field edit data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldEditData(field: any, inputData: any, originalFieldData: any): any {
|
||||
const fieldName = 'f_' + field.id;
|
||||
|
||||
if (inputData[fieldName]) {
|
||||
const values = [],
|
||||
date = inputData[fieldName].split('-'),
|
||||
year = date[0],
|
||||
month = date[1],
|
||||
day = date[2];
|
||||
values.push({
|
||||
fieldid: field.id,
|
||||
subfield: 'year',
|
||||
value: year
|
||||
});
|
||||
values.push({
|
||||
fieldid: field.id,
|
||||
subfield: 'month',
|
||||
value: month
|
||||
});
|
||||
values.push({
|
||||
fieldid: field.id,
|
||||
subfield: 'day',
|
||||
value: day
|
||||
});
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field data in changed.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @param {any} originalFieldData Original field entered data.
|
||||
* @return {Promise<boolean> | boolean} If the field has changes.
|
||||
*/
|
||||
hasFieldDataChanged(field: any, inputData: any, originalFieldData: any): Promise<boolean> | boolean {
|
||||
const fieldName = 'f_' + field.id,
|
||||
input = inputData[fieldName] || '';
|
||||
|
||||
originalFieldData = (originalFieldData && originalFieldData.content &&
|
||||
new Date(originalFieldData.content * 1000).toISOString().substr(0, 10)) || '';
|
||||
|
||||
return input != originalFieldData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and get field requeriments.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {string | false} String with the notification or false.
|
||||
*/
|
||||
getFieldsNotifications(field: any, inputData: any): string | false {
|
||||
if (field.required &&
|
||||
(!inputData || inputData.length < 2 || !inputData[0].value || !inputData[1].value || !inputData[2].value)) {
|
||||
|
||||
return this.translate.instant('addon.mod_data.errormustsupplyvalue');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override field content data with offline submission.
|
||||
*
|
||||
* @param {any} originalContent Original data to be overriden.
|
||||
* @param {any} offlineContent Array with all the offline data to override.
|
||||
* @param {any} [offlineFiles] Array with all the offline files in the field.
|
||||
* @return {any} Data overriden
|
||||
*/
|
||||
overrideData(originalContent: any, offlineContent: any, offlineFiles?: any): any {
|
||||
let date = Date.UTC(offlineContent['year'] || '', offlineContent['month'] ? offlineContent['month'] - 1 : null,
|
||||
offlineContent['day'] || null);
|
||||
date = Math.floor(date / 1000);
|
||||
|
||||
originalContent.content = date || '';
|
||||
|
||||
return originalContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -14,11 +14,33 @@
|
|||
|
||||
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({
|
||||
declarations: [],
|
||||
imports: [
|
||||
AddonModDataFieldCheckboxModule
|
||||
AddonModDataFieldCheckboxModule,
|
||||
AddonModDataFieldDateModule,
|
||||
AddonModDataFieldFileModule,
|
||||
AddonModDataFieldLatlongModule,
|
||||
AddonModDataFieldMenuModule,
|
||||
AddonModDataFieldMultimenuModule,
|
||||
AddonModDataFieldNumberModule,
|
||||
AddonModDataFieldPictureModule,
|
||||
AddonModDataFieldRadiobuttonModule,
|
||||
AddonModDataFieldTextModule,
|
||||
AddonModDataFieldTextareaModule,
|
||||
AddonModDataFieldUrlModule
|
||||
],
|
||||
providers: [
|
||||
],
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<span *ngIf="mode == 'edit'" [core-mark-required]="field.required"></span>
|
||||
<core-input-errors *ngIf="error && mode == 'edit'" [errorMessages]="error"></core-input-errors>
|
||||
<input *ngIf="mode == 'search'" type="text" [placeholder]="field.name" [name]="'f_'+field.id">
|
||||
<core-attachments *ngIf="mode == 'edit'" [files]="files" [maxSize]="maxSizeBytes" maxSubmissions="1" [component]="component" [componentId]="componentId" [allowOffline]="true"></core-attachments>
|
||||
|
||||
<ng-container *ngIf="mode == 'show'">
|
||||
<div *ngFor="let file of files" no-lines>
|
||||
<!-- Files already attached to the submission. -->
|
||||
<core-file *ngIf="!file.name" [file]="file" [component]="component" [componentId]="componentId" [alwaysDownload]="true"></core-file>
|
||||
|
||||
<!-- Files stored in offline to be sent later. -->
|
||||
<core-local-file *ngIf="file.name" [file]="file"></core-local-file>
|
||||
</div>
|
||||
</ng-container>
|
|
@ -0,0 +1,81 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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, ElementRef } from '@angular/core';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
|
||||
import { CoreFileSessionProvider } from '@providers/file-session';
|
||||
import { AddonModDataProvider } from '../../../providers/data';
|
||||
|
||||
/**
|
||||
* Component to render data file field.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-data-field-file',
|
||||
templateUrl: 'file.html'
|
||||
})
|
||||
export class AddonModDataFieldFileComponent extends AddonModDataFieldPluginComponent implements OnInit {
|
||||
|
||||
control: FormControl;
|
||||
files = [];
|
||||
component: string;
|
||||
componentId: number;
|
||||
maxSizeBytes: number;
|
||||
|
||||
constructor(protected fb: FormBuilder, protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
|
||||
element: ElementRef, private fileSessionprovider: CoreFileSessionProvider) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.mode = this.mode == 'list' ? 'show' : this.mode;
|
||||
this.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the files from the input value.
|
||||
*
|
||||
* @param {any} value Input value.
|
||||
* @return {any} List of files.
|
||||
*/
|
||||
protected getFiles(value: any): any {
|
||||
let files = (value && value.files) || [];
|
||||
|
||||
// Reduce to first element.
|
||||
if (files.length > 0) {
|
||||
files = [files[0]];
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
protected render(): void {
|
||||
if (this.mode == 'show' || this.mode == 'edit') {
|
||||
this.component = AddonModDataProvider.COMPONENT;
|
||||
this.componentId = this.database.coursemodule;
|
||||
|
||||
this.files = this.getFiles(this.value);
|
||||
|
||||
if (this.mode != 'show') {
|
||||
// Edit mode, the list shouldn't change so there is no need to watch it.
|
||||
this.maxSizeBytes = parseInt(this.field.param3, 10);
|
||||
this.fileSessionprovider.setFiles(this.component, this.database.id + '_' + this.field.id, this.files);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldFileHandler } from './providers/handler';
|
||||
import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate';
|
||||
import { AddonModDataFieldFileComponent } from './component/file';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModDataFieldFileComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule,
|
||||
],
|
||||
providers: [
|
||||
AddonModDataFieldFileHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModDataFieldFileComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModDataFieldFileComponent
|
||||
]
|
||||
})
|
||||
export class AddonModDataFieldFileModule {
|
||||
constructor(fieldDelegate: AddonModDataFieldsDelegate, handler: AddonModDataFieldFileHandler) {
|
||||
fieldDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector, Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreFileSessionProvider } from '@providers/file-session';
|
||||
import { AddonModDataFieldHandler } from '../../../providers/fields-delegate';
|
||||
import { AddonModDataProvider } from '../../../providers/data';
|
||||
import { AddonModDataFieldFileComponent } from '../component/file';
|
||||
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
|
||||
|
||||
/**
|
||||
* Handler for file data field plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModDataFieldFileHandler implements AddonModDataFieldHandler {
|
||||
name = 'AddonModDataFieldFileHandler';
|
||||
type = 'file';
|
||||
|
||||
constructor(private translate: TranslateService, private fileSessionprovider: CoreFileSessionProvider,
|
||||
private fileUploaderProvider: CoreFileUploaderProvider) { }
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} field The field object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModDataFieldFileComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field search data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the search form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldSearchData(field: any, inputData: any): any {
|
||||
const fieldName = 'f_' + field.id;
|
||||
|
||||
if (inputData[fieldName]) {
|
||||
return [{
|
||||
name: fieldName,
|
||||
value: inputData[fieldName]
|
||||
}];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field edit data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldEditData(field: any, inputData: any, originalFieldData: any): any {
|
||||
const files = this.getFieldEditFiles(field);
|
||||
|
||||
if (files.length) {
|
||||
return [{
|
||||
fieldid: field.id,
|
||||
subfield: 'file',
|
||||
files: files
|
||||
}];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field edit files in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field..
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldEditFiles(field: any): any {
|
||||
return this.fileSessionprovider.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field data in changed.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @param {any} originalFieldData Original field entered data.
|
||||
* @return {Promise<boolean> | boolean} If the field has changes.
|
||||
*/
|
||||
hasFieldDataChanged(field: any, inputData: any, originalFieldData: any): Promise<boolean> | boolean {
|
||||
const files = this.fileSessionprovider.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id) || [];
|
||||
let originalFiles = (originalFieldData && originalFieldData.files) || [];
|
||||
|
||||
if (originalFiles.length) {
|
||||
originalFiles = [originalFiles[0]];
|
||||
}
|
||||
|
||||
return this.fileUploaderProvider.areFileListDifferent(files, originalFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and get field requeriments.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {string | false} String with the notification or false.
|
||||
*/
|
||||
getFieldsNotifications(field: any, inputData: any): string | false {
|
||||
if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
|
||||
return this.translate.instant('addon.mod_data.errormustsupplyvalue');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override field content data with offline submission.
|
||||
*
|
||||
* @param {any} originalContent Original data to be overriden.
|
||||
* @param {any} offlineContent Array with all the offline data to override.
|
||||
* @param {any} [offlineFiles] Array with all the offline files in the field.
|
||||
* @return {any} Data overriden
|
||||
*/
|
||||
overrideData(originalContent: any, offlineContent: any, offlineFiles?: any): any {
|
||||
if (offlineContent && offlineContent.file && offlineContent.file.offline > 0 && offlineFiles && offlineFiles.length > 0) {
|
||||
originalContent.content = offlineFiles[0].filename;
|
||||
originalContent.files = [offlineFiles[0]];
|
||||
} else if (offlineContent && offlineContent.file && offlineContent.file.online && offlineContent.file.online.length > 0) {
|
||||
originalContent.content = offlineContent.file.online[0].filename;
|
||||
originalContent.files = [offlineContent.file.online[0]];
|
||||
}
|
||||
|
||||
return originalContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<ion-input *ngIf="mode == 'search'" type="text" [placeholder]="field.name" [formControlName]="'f_'+field.id"></ion-input>
|
||||
|
||||
<span *ngIf="mode == 'edit'" [core-mark-required]="field.required"></span>
|
||||
|
||||
<core-input-errors *ngIf="error && mode == 'edit'" [control]="form.controls['f_'+field.id]" [errorMessages]="errors"></core-input-errors>
|
||||
|
||||
<ion-item *ngIf="mode == 'edit'" [formGroup]="form">
|
||||
<ion-input type="text" [formControlName]="'f_'+field.id+'_0'" [(ngModel)]="north" maxlength="10" core-input-errors></ion-input>
|
||||
<span class="placeholder-icon" item-right>°N</span>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="mode == 'edit'" [formGroup]="form">
|
||||
<ion-input type="text" [formControlName]="'f_'+field.id+'_1'" [(ngModel)]="east" maxlength="10" core-input-errors></ion-input>
|
||||
<span class="placeholder-icon" item-right>°E</span>
|
||||
</ion-item>
|
||||
|
||||
|
||||
<span *ngIf="mode == 'show' && value">
|
||||
<a [href]="getLatLongLink(north, east)">{{ formatLatLong(north, east) }}</a>
|
||||
</span>
|
|
@ -0,0 +1,90 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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, ElementRef } from '@angular/core';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { Platform } from 'ionic-angular';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
|
||||
|
||||
/**
|
||||
* Component to render data latlong field.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-data-field-latlong',
|
||||
templateUrl: 'latlong.html'
|
||||
})
|
||||
export class AddonModDataFieldLatlongComponent extends AddonModDataFieldPluginComponent implements OnInit {
|
||||
|
||||
control: FormControl;
|
||||
values = {};
|
||||
north: number;
|
||||
east: number;
|
||||
|
||||
constructor(protected fb: FormBuilder, protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
|
||||
element: ElementRef, private platform: Platform) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format latitude and longitude in a simple text.
|
||||
*
|
||||
* @param {number} north Degrees north.
|
||||
* @param {number} east Degrees East.
|
||||
* @return {string} Readable Latitude and logitude.
|
||||
*/
|
||||
formatLatLong(north: number, east: number): string {
|
||||
if (north !== null || east !== null) {
|
||||
const northFixed = north ? Math.abs(north).toFixed(4) : '0.0000',
|
||||
eastFixed = east ? Math.abs(east).toFixed(4) : '0.0000';
|
||||
|
||||
return northFixed + (north < 0 ? '°S' : '°N') + ' ' + eastFixed + (east < 0 ? '°W' : '°E');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link to maps from latitude and longitude.
|
||||
*
|
||||
* @param {number} north Degrees north.
|
||||
* @param {number} east Degrees East.
|
||||
* @return {string} Link to maps depending on platform.
|
||||
*/
|
||||
getLatLongLink(north: number, east: number): string {
|
||||
if (north !== null || east !== null) {
|
||||
const northFixed = north ? north.toFixed(4) : '0.0000',
|
||||
eastFixed = east ? east.toFixed(4) : '0.0000';
|
||||
|
||||
if (this.platform.is('ios')) {
|
||||
return 'http://maps.apple.com/?ll=' + northFixed + ',' + eastFixed + '&near=' + northFixed + ',' + eastFixed;
|
||||
}
|
||||
|
||||
return 'geo:' + northFixed + ',' + eastFixed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.mode = this.mode == 'list' ? 'show' : this.mode;
|
||||
this.render();
|
||||
}
|
||||
|
||||
protected render(): void {
|
||||
if (this.value) {
|
||||
this.north = (this.value && parseFloat(this.value.content)) || null;
|
||||
this.east = (this.value && parseFloat(this.value.content1)) || null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldLatlongHandler } from './providers/handler';
|
||||
import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate';
|
||||
import { AddonModDataFieldLatlongComponent } from './component/latlong';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModDataFieldLatlongComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModDataFieldLatlongHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModDataFieldLatlongComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModDataFieldLatlongComponent
|
||||
]
|
||||
})
|
||||
export class AddonModDataFieldLatlongModule {
|
||||
constructor(fieldDelegate: AddonModDataFieldsDelegate, handler: AddonModDataFieldLatlongHandler) {
|
||||
fieldDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector, Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldHandler } from '../../../providers/fields-delegate';
|
||||
import { AddonModDataFieldLatlongComponent } from '../component/latlong';
|
||||
|
||||
/**
|
||||
* Handler for latlong data field plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModDataFieldLatlongHandler implements AddonModDataFieldHandler {
|
||||
name = 'AddonModDataFieldLatlongHandler';
|
||||
type = 'latlong';
|
||||
|
||||
constructor(private translate: TranslateService) { }
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} field The field object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModDataFieldLatlongComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field search data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the search form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldSearchData(field: any, inputData: any): any {
|
||||
const fieldName = 'f_' + field.id;
|
||||
|
||||
if (inputData[fieldName]) {
|
||||
return [{
|
||||
name: fieldName,
|
||||
value: inputData[fieldName]
|
||||
}];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field edit data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldEditData(field: any, inputData: any, originalFieldData: any): any {
|
||||
const fieldName = 'f_' + field.id,
|
||||
values = [];
|
||||
|
||||
if (inputData[fieldName + '_0']) {
|
||||
values.push({
|
||||
fieldid: field.id,
|
||||
subfield: '0',
|
||||
value: inputData[fieldName + '_0']
|
||||
});
|
||||
}
|
||||
|
||||
if (inputData[fieldName + '_1']) {
|
||||
values.push({
|
||||
fieldid: field.id,
|
||||
subfield: '1',
|
||||
value: inputData[fieldName + '_1']
|
||||
});
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field data in changed.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @param {any} originalFieldData Original field entered data.
|
||||
* @return {Promise<boolean> | boolean} If the field has changes.
|
||||
*/
|
||||
hasFieldDataChanged(field: any, inputData: any, originalFieldData: any): Promise<boolean> | boolean {
|
||||
const fieldName = 'f_' + field.id,
|
||||
lat = inputData[fieldName + '_0'] || '',
|
||||
long = inputData[fieldName + '_1'] || '',
|
||||
originalLat = (originalFieldData && originalFieldData.content) || '',
|
||||
originalLong = (originalFieldData && originalFieldData.content1) || '';
|
||||
|
||||
return lat != originalLat || long != originalLong;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and get field requeriments.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {string | false} String with the notification or false.
|
||||
*/
|
||||
getFieldsNotifications(field: any, inputData: any): string | false {
|
||||
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 this.translate.instant('addon.mod_data.latlongboth');
|
||||
} else if (field.required && valueCount == 0) {
|
||||
return this.translate.instant('addon.mod_data.errormustsupplyvalue');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override field content data with offline submission.
|
||||
*
|
||||
* @param {any} originalContent Original data to be overriden.
|
||||
* @param {any} offlineContent Array with all the offline data to override.
|
||||
* @param {any} [offlineFiles] Array with all the offline files in the field.
|
||||
* @return {any} Data overriden
|
||||
*/
|
||||
overrideData(originalContent: any, offlineContent: any, offlineFiles?: any): any {
|
||||
originalContent.content = offlineContent[0] || '';
|
||||
originalContent.content1 = offlineContent[1] || '';
|
||||
|
||||
return originalContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<span *ngIf="mode == 'edit'" [core-mark-required]="field.required"></span>
|
||||
<core-input-errors *ngIf="error && mode == 'edit'" [control]="form.controls['f_'+field.id]" [errorMessages]="error"></core-input-errors>
|
||||
|
||||
<ion-select *ngIf="mode != 'show'" [formControlName]="'f_'+field.id" [placeholder]="'addon.mod_data.menuchoose' | translate" core-input-errors [(ngModel)]="val">
|
||||
<ion-option value="">{{ 'addon.mod_data.menuchoose' | translate }}</ion-option>
|
||||
<ion-option *ngFor="let option of options" [value]="option">{{option}}</ion-option>
|
||||
</ion-select>
|
||||
|
||||
<core-format-text *ngIf="mode == 'show' && value && value.content" [text]="value.content"></core-format-text>
|
|
@ -0,0 +1,57 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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, ElementRef } from '@angular/core';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
|
||||
|
||||
/**
|
||||
* Component to render data menu field.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-data-field-menu',
|
||||
templateUrl: 'menu.html'
|
||||
})
|
||||
export class AddonModDataFieldMenuComponent extends AddonModDataFieldPluginComponent implements OnInit {
|
||||
|
||||
control: FormControl;
|
||||
val: string;
|
||||
options = [];
|
||||
|
||||
constructor(protected fb: FormBuilder, protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
|
||||
element: ElementRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.mode = this.mode == 'list' ? 'show' : this.mode;
|
||||
this.render();
|
||||
}
|
||||
|
||||
protected render(): void {
|
||||
if (this.mode == 'show') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.options = this.field.param1.split('\n');
|
||||
|
||||
if (this.mode == 'edit' && this.value) {
|
||||
this.val = this.value.content;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldMenuHandler } from './providers/handler';
|
||||
import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate';
|
||||
import { AddonModDataFieldMenuComponent } from './component/menu';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModDataFieldMenuComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModDataFieldMenuHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModDataFieldMenuComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModDataFieldMenuComponent
|
||||
]
|
||||
})
|
||||
export class AddonModDataFieldMenuModule {
|
||||
constructor(fieldDelegate: AddonModDataFieldsDelegate, handler: AddonModDataFieldMenuHandler) {
|
||||
fieldDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector, Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldHandler } from '../../../providers/fields-delegate';
|
||||
import { AddonModDataFieldMenuComponent } from '../component/menu';
|
||||
|
||||
/**
|
||||
* Handler for menu data field plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModDataFieldMenuHandler implements AddonModDataFieldHandler {
|
||||
name = 'AddonModDataFieldMenuHandler';
|
||||
type = 'menu';
|
||||
|
||||
constructor(private translate: TranslateService) { }
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} field The field object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModDataFieldMenuComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field search data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the search form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldSearchData(field: any, inputData: any): any {
|
||||
const fieldName = 'f_' + field.id;
|
||||
|
||||
if (inputData[fieldName]) {
|
||||
return [{
|
||||
name: fieldName,
|
||||
value: inputData[fieldName]
|
||||
}];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field edit data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldEditData(field: any, inputData: any, originalFieldData: any): any {
|
||||
const fieldName = 'f_' + field.id;
|
||||
|
||||
if (inputData[fieldName]) {
|
||||
return [{
|
||||
fieldid: field.id,
|
||||
value: inputData[fieldName]
|
||||
}];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field data in changed.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @param {any} originalFieldData Original field entered data.
|
||||
* @return {Promise<boolean> | boolean} If the field has changes.
|
||||
*/
|
||||
hasFieldDataChanged(field: any, inputData: any, originalFieldData: any): Promise<boolean> | boolean {
|
||||
const fieldName = 'f_' + field.id,
|
||||
input = inputData[fieldName] || '';
|
||||
originalFieldData = (originalFieldData && originalFieldData.content) || '';
|
||||
|
||||
return input != originalFieldData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and get field requeriments.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {string | false} String with the notification or false.
|
||||
*/
|
||||
getFieldsNotifications(field: any, inputData: any): string | false {
|
||||
if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
|
||||
return this.translate.instant('addon.mod_data.errormustsupplyvalue');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override field content data with offline submission.
|
||||
*
|
||||
* @param {any} originalContent Original data to be overriden.
|
||||
* @param {any} offlineContent Array with all the offline data to override.
|
||||
* @param {any} [offlineFiles] Array with all the offline files in the field.
|
||||
* @return {any} Data overriden
|
||||
*/
|
||||
overrideData(originalContent: any, offlineContent: any, offlineFiles?: any): any {
|
||||
originalContent.content = offlineContent[''] || '';
|
||||
|
||||
return originalContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<span *ngIf="mode == 'edit'" [core-mark-required]="field.required"></span>
|
||||
<core-input-errors *ngIf="error && mode == 'edit'" [control]="form.controls['f_'+field.id]" [errorMessages]="error"></core-input-errors>
|
||||
|
||||
<!--<mm-multiple-select *ngIf="mode != 'show'" title="{{field.name}}" name="f_{{field.id}}" options="options"></mm-multiple-select>
|
||||
|
||||
<ion-checkbox *ngIf="mode == 'search'" name="f_{{field.id}}_allreq" ng-value="1">{{ 'addon.mod_data.selectedrequired' | translate }}</ion-checkbox>-->
|
||||
|
||||
<core-format-text *ngIf="mode == 'show' && value && value.content" [text]="value.content.split('##').join('<br>')"></core-format-text>
|
|
@ -0,0 +1,63 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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, ElementRef } from '@angular/core';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
|
||||
|
||||
/**
|
||||
* Component to render data multimenu field.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-data-field-multimenu',
|
||||
templateUrl: 'multimenu.html'
|
||||
})
|
||||
export class AddonModDataFieldMultimenuComponent extends AddonModDataFieldPluginComponent implements OnInit {
|
||||
|
||||
control: FormControl;
|
||||
options = [];
|
||||
|
||||
constructor(protected fb: FormBuilder, protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
|
||||
element: ElementRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.mode = this.mode == 'list' ? 'show' : this.mode;
|
||||
this.render();
|
||||
}
|
||||
|
||||
protected render(): void {
|
||||
if (this.mode == 'show') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.options = this.field.param1.split('\n').map((option) => {
|
||||
return { key: option, value: option };
|
||||
});
|
||||
|
||||
if (this.mode == 'edit' && this.value && this.value.content) {
|
||||
this.value.content.split('##').forEach((value) => {
|
||||
const x = this.options.findIndex((option) => value == option.key);
|
||||
if (x >= 0) {
|
||||
this.options[x].selected = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldMultimenuHandler } from './providers/handler';
|
||||
import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate';
|
||||
import { AddonModDataFieldMultimenuComponent } from './component/multimenu';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModDataFieldMultimenuComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModDataFieldMultimenuHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModDataFieldMultimenuComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModDataFieldMultimenuComponent
|
||||
]
|
||||
})
|
||||
export class AddonModDataFieldMultimenuModule {
|
||||
constructor(fieldDelegate: AddonModDataFieldsDelegate, handler: AddonModDataFieldMultimenuHandler) {
|
||||
fieldDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector, Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldHandler } from '../../../providers/fields-delegate';
|
||||
import { AddonModDataFieldMultimenuComponent } from '../component/multimenu';
|
||||
|
||||
/**
|
||||
* Handler for multimenu data field plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModDataFieldMultimenuHandler implements AddonModDataFieldHandler {
|
||||
name = 'AddonModDataFieldMultimenuHandler';
|
||||
type = 'multimenu';
|
||||
|
||||
constructor(private translate: TranslateService) { }
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} field The field object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModDataFieldMultimenuComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field search data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the search form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldSearchData(field: any, inputData: any): any {
|
||||
const fieldName = 'f_' + field.id,
|
||||
reqName = 'f_' + field.id + '_allreq';
|
||||
|
||||
if (inputData[fieldName].length > 0) {
|
||||
const options = inputData[fieldName].split('###'),
|
||||
values = [];
|
||||
|
||||
if (options.length > 0) {
|
||||
values.push({
|
||||
name: fieldName,
|
||||
value: options
|
||||
});
|
||||
|
||||
if (inputData[reqName]['1']) {
|
||||
values.push({
|
||||
name: reqName,
|
||||
value: true
|
||||
});
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field edit data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldEditData(field: any, inputData: any, originalFieldData: any): any {
|
||||
const fieldName = 'f_' + field.id;
|
||||
|
||||
if (inputData[fieldName] && inputData[fieldName].length > 0) {
|
||||
const options = inputData[fieldName].split('###');
|
||||
if (options.length > 0) {
|
||||
return [{
|
||||
fieldid: field.id,
|
||||
value: options
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field data in changed.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @param {any} originalFieldData Original field entered data.
|
||||
* @return {Promise<boolean> | boolean} If the field has changes.
|
||||
*/
|
||||
hasFieldDataChanged(field: any, inputData: any, originalFieldData: any): Promise<boolean> | boolean {
|
||||
const fieldName = 'f_' + field.id,
|
||||
input = inputData[fieldName] || '';
|
||||
originalFieldData = (originalFieldData && originalFieldData.content) || '';
|
||||
|
||||
return input != originalFieldData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and get field requeriments.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {string | false} String with the notification or false.
|
||||
*/
|
||||
getFieldsNotifications(field: any, inputData: any): string | false {
|
||||
if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
|
||||
return this.translate.instant('addon.mod_data.errormustsupplyvalue');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override field content data with offline submission.
|
||||
*
|
||||
* @param {any} originalContent Original data to be overriden.
|
||||
* @param {any} offlineContent Array with all the offline data to override.
|
||||
* @param {any} [offlineFiles] Array with all the offline files in the field.
|
||||
* @return {any} Data overriden
|
||||
*/
|
||||
overrideData(originalContent: any, offlineContent: any, offlineFiles?: any): any {
|
||||
originalContent.content = (offlineContent[''] && offlineContent[''].join('###')) || '';
|
||||
|
||||
return originalContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<span *ngIf="mode == 'edit'" [core-mark-required]="field.required"></span>
|
||||
|
||||
<core-input-errors *ngIf="error && mode == 'edit'" [control]="form.controls['f_'+field.id]" [errorMessages]="error"></core-input-errors>
|
||||
|
||||
<ion-input *ngIf="mode != 'show'" type="number" [formControlName]="'f_'+field.id" [placeholder]="field.name" [(ngModel)]="val"></ion-input>
|
||||
|
||||
<core-format-text *ngIf="mode == 'show' && value && value.content" [text]="value.content"></core-format-text>
|
|
@ -0,0 +1,54 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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, ElementRef } from '@angular/core';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
|
||||
|
||||
/**
|
||||
* Component to render data number field.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-data-field-number',
|
||||
templateUrl: 'number.html'
|
||||
})
|
||||
export class AddonModDataFieldNumberComponent extends AddonModDataFieldPluginComponent implements OnInit {
|
||||
|
||||
control: FormControl;
|
||||
val: number;
|
||||
|
||||
constructor(protected fb: FormBuilder, protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
|
||||
element: ElementRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.mode = this.mode == 'list' ? 'show' : this.mode;
|
||||
this.render();
|
||||
}
|
||||
|
||||
protected render(): void {
|
||||
if (this.mode == 'show') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.mode == 'edit' && this.value) {
|
||||
this.val = this.value && parseFloat(this.value.content);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldNumberHandler } from './providers/handler';
|
||||
import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate';
|
||||
import { AddonModDataFieldNumberComponent } from './component/number';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModDataFieldNumberComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModDataFieldNumberHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModDataFieldNumberComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModDataFieldNumberComponent
|
||||
]
|
||||
})
|
||||
export class AddonModDataFieldNumberModule {
|
||||
constructor(fieldDelegate: AddonModDataFieldsDelegate, handler: AddonModDataFieldNumberHandler) {
|
||||
fieldDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector, Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldTextHandler } from '../../text/providers/handler';
|
||||
import { AddonModDataFieldNumberComponent } from '../component/number';
|
||||
|
||||
/**
|
||||
* Handler for number data field plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModDataFieldNumberHandler extends AddonModDataFieldTextHandler {
|
||||
name = 'AddonModDataFieldNumberHandler';
|
||||
type = 'number';
|
||||
|
||||
constructor(protected translate: TranslateService) {
|
||||
super(translate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} field The field object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModDataFieldNumberComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and get field requeriments.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {string | false} String with the notification or false.
|
||||
*/
|
||||
getFieldsNotifications(field: any, inputData: any): string | false {
|
||||
if (field.required && (!inputData || !inputData.length || inputData[0].value == '')) {
|
||||
return this.translate.instant('addon.mod_data.errormustsupplyvalue');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<span *ngIf="mode == 'edit'" [core-mark-required]="field.required"></span>
|
||||
|
||||
<core-input-errors *ngIf="error && mode == 'edit'" [errorMessages]="error"></core-input-errors>
|
||||
|
||||
<input *ngIf="mode == 'search'" type="text" [placeholder]="field.name" [name]="'f_'+field.id">
|
||||
|
||||
<core-attachments *ngIf="mode == 'edit'" [files]="files" [maxSize]="maxSizeBytes" maxSubmissions="1" [component]="component" [componentId]="componentId" [allowOffline]="true"></core-attachments>
|
||||
|
||||
<ion-item *ngIf="mode == 'edit'" [formGroup]="form">
|
||||
<ion-label>{{ 'addon.mod_data.alttext' | translate }}</ion-label>
|
||||
<ion-input type="text" [formControlName]="'f_'+field.id+'_alttext'" [(ngModel)]="alttext" [placeholder]=" 'addon.mod_data.alttext' | translate" ></ion-input>
|
||||
<span class="placeholder-icon" item-right>°N</span>
|
||||
</ion-item>
|
||||
|
||||
<span *ngIf="mode == 'list' && imageUrl" (click)="viewAction()"><img [src]="imageUrl" [alt]="title" [title]="title" class="core-media-adapt-width list_picture" core-external-content/></span>
|
||||
|
||||
<img *ngIf="mode == 'show' && imageUrl" [src]="imageUrl" [alt]="title" [title]="title" class="core-media-adapt-width list_picture" [width]="width" [height]="height" core-external-content/>
|
|
@ -0,0 +1,128 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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, ElementRef } from '@angular/core';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
|
||||
import { CoreFileSessionProvider } from '@providers/file-session';
|
||||
import { AddonModDataProvider } from '../../../providers/data';
|
||||
|
||||
/**
|
||||
* Component to render data picture field.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-data-field-picture',
|
||||
templateUrl: 'picture.html'
|
||||
})
|
||||
export class AddonModDataFieldPictureComponent extends AddonModDataFieldPluginComponent implements OnInit {
|
||||
|
||||
control: FormControl;
|
||||
files = [];
|
||||
component: string;
|
||||
componentId: number;
|
||||
maxSizeBytes: number;
|
||||
|
||||
image: any;
|
||||
entryId: number;
|
||||
imageUrl: string;
|
||||
title: string;
|
||||
alttext: string;
|
||||
width: string;
|
||||
height: string;
|
||||
|
||||
constructor(protected fb: FormBuilder, protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
|
||||
element: ElementRef, private fileSessionprovider: CoreFileSessionProvider) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the files from the input value.
|
||||
*
|
||||
* @param {any} value Input value.
|
||||
* @return {any} List of files.
|
||||
*/
|
||||
protected getFiles(value: any): any {
|
||||
let files = (value && value.files) || [];
|
||||
|
||||
// Reduce to first element.
|
||||
if (files.length > 0) {
|
||||
files = [files[0]];
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find file in a list.
|
||||
*
|
||||
* @param {any[]} files File list where to search.
|
||||
* @param {string} filenameSeek Filename to search.
|
||||
* @return {any} File found or false.
|
||||
*/
|
||||
protected findFile(files: any[], filenameSeek: string): any {
|
||||
return files.find((file) => file.filename == filenameSeek) || false;
|
||||
}
|
||||
|
||||
protected render(): void {
|
||||
if (this.mode != 'search') {
|
||||
this.component = AddonModDataProvider.COMPONENT;
|
||||
this.componentId = this.database.coursemodule;
|
||||
|
||||
// Edit mode, the list shouldn't change so there is no need to watch it.
|
||||
const files = this.value && this.value.files || [];
|
||||
|
||||
// Get image or thumb.
|
||||
if (files.length > 0) {
|
||||
const filenameSeek = this.mode == 'list' ? 'thumb_' + this.value.content : this.value.content;
|
||||
this.image = this.findFile(files, filenameSeek);
|
||||
|
||||
if (!this.image && this.mode == 'list') {
|
||||
this.image = this.findFile(files, this.value.content);
|
||||
}
|
||||
|
||||
this.files = [this.image];
|
||||
} else {
|
||||
this.image = false;
|
||||
this.files = [];
|
||||
}
|
||||
|
||||
if (this.mode == 'edit') {
|
||||
this.maxSizeBytes = parseInt(this.field.param3, 10);
|
||||
this.fileSessionprovider.setFiles(this.component, this.database.id + '_' + this.field.id, this.files);
|
||||
this.alttext = (this.value && this.value.content1) || '';
|
||||
} else {
|
||||
this.entryId = (this.value && this.value.recordid) || null;
|
||||
this.title = (this.value && this.value.content1) || '';
|
||||
this.imageUrl = null;
|
||||
if (this.image) {
|
||||
if (this.image.offline) {
|
||||
this.imageUrl = (this.image && this.image.toURL()) || null;
|
||||
} else {
|
||||
this.imageUrl = (this.image && this.image.fileurl) || null;
|
||||
}
|
||||
}
|
||||
this.width = this.field.param1 || '';
|
||||
this.height = this.field.param2 || '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldPictureHandler } from './providers/handler';
|
||||
import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate';
|
||||
import { AddonModDataFieldPictureComponent } from './component/picture';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModDataFieldPictureComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule,
|
||||
],
|
||||
providers: [
|
||||
AddonModDataFieldPictureHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModDataFieldPictureComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModDataFieldPictureComponent
|
||||
]
|
||||
})
|
||||
export class AddonModDataFieldPictureModule {
|
||||
constructor(fieldDelegate: AddonModDataFieldsDelegate, handler: AddonModDataFieldPictureHandler) {
|
||||
fieldDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector, Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreFileSessionProvider } from '@providers/file-session';
|
||||
import { AddonModDataFieldHandler } from '../../../providers/fields-delegate';
|
||||
import { AddonModDataProvider } from '../../../providers/data';
|
||||
import { AddonModDataFieldPictureComponent } from '../component/picture';
|
||||
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
|
||||
|
||||
/**
|
||||
* Handler for picture data field plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModDataFieldPictureHandler implements AddonModDataFieldHandler {
|
||||
name = 'AddonModDataFieldPictureHandler';
|
||||
type = 'picture';
|
||||
|
||||
constructor(private translate: TranslateService, private fileSessionprovider: CoreFileSessionProvider,
|
||||
private fileUploaderProvider: CoreFileUploaderProvider) { }
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} field The field object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModDataFieldPictureComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field search data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the search form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldSearchData(field: any, inputData: any): any {
|
||||
const fieldName = 'f_' + field.id;
|
||||
|
||||
if (inputData[fieldName]) {
|
||||
return [{
|
||||
name: fieldName,
|
||||
value: inputData[fieldName]
|
||||
}];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field edit data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldEditData(field: any, inputData: any, originalFieldData: any): any {
|
||||
const files = this.getFieldEditFiles(field),
|
||||
values = [],
|
||||
fieldName = 'f_' + field.id + '_alttext';
|
||||
|
||||
if (files.length) {
|
||||
values.push({
|
||||
fieldid: field.id,
|
||||
subfield: 'file',
|
||||
files: files
|
||||
});
|
||||
}
|
||||
|
||||
if (inputData[fieldName]) {
|
||||
values.push({
|
||||
fieldid: field.id,
|
||||
subfield: 'alttext',
|
||||
value: inputData[fieldName]
|
||||
});
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field edit files in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field..
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldEditFiles(field: any): any {
|
||||
return this.fileSessionprovider.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field data in changed.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @param {any} originalFieldData Original field entered data.
|
||||
* @return {Promise<boolean> | boolean} If the field has changes.
|
||||
*/
|
||||
hasFieldDataChanged(field: any, inputData: any, originalFieldData: any): Promise<boolean> | boolean {
|
||||
const fieldName = 'f_' + field.id + '_alttext',
|
||||
altText = inputData[fieldName] || '',
|
||||
originalAltText = (originalFieldData && originalFieldData.content1) || '',
|
||||
files = this.getFieldEditFiles(field) || [];
|
||||
let originalFiles = (originalFieldData && originalFieldData.files) || [];
|
||||
|
||||
// Get image.
|
||||
if (originalFiles.length > 0) {
|
||||
const filenameSeek = (originalFieldData && originalFieldData.content) || '',
|
||||
file = originalFiles.find((file) => file.filename == filenameSeek);
|
||||
if (file) {
|
||||
originalFiles = [file];
|
||||
}
|
||||
} else {
|
||||
originalFiles = [];
|
||||
}
|
||||
|
||||
return altText != originalAltText || this.fileUploaderProvider.areFileListDifferent(files, originalFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and get field requeriments.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {string | false} String with the notification or false.
|
||||
*/
|
||||
getFieldsNotifications(field: any, inputData: any): string | false {
|
||||
if (field.required) {
|
||||
if (!inputData || !inputData.length) {
|
||||
return this.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 this.translate.instant('addon.mod_data.errormustsupplyvalue');
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override field content data with offline submission.
|
||||
*
|
||||
* @param {any} originalContent Original data to be overriden.
|
||||
* @param {any} offlineContent Array with all the offline data to override.
|
||||
* @param {any} [offlineFiles] Array with all the offline files in the field.
|
||||
* @return {any} Data overriden
|
||||
*/
|
||||
overrideData(originalContent: any, offlineContent: any, offlineFiles?: any): any {
|
||||
if (offlineContent && offlineContent.file && offlineContent.file.offline > 0 && offlineFiles && offlineFiles.length > 0) {
|
||||
originalContent.content = offlineFiles[0].filename;
|
||||
originalContent.files = [offlineFiles[0]];
|
||||
} else if (offlineContent && offlineContent.file && offlineContent.file.online && offlineContent.file.online.length > 0) {
|
||||
originalContent.content = offlineContent.file.online[0].filename;
|
||||
originalContent.files = [offlineContent.file.online[0]];
|
||||
}
|
||||
|
||||
originalContent.content1 = offlineContent.alttext || '';
|
||||
|
||||
return originalContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<span *ngIf="mode == 'edit'" [core-mark-required]="field.required"></span>
|
||||
<core-input-errors *ngIf="error && mode == 'edit'" [control]="form.controls['f_'+field.id]" [errorMessages]="error"></core-input-errors>
|
||||
|
||||
<ion-select *ngIf="mode != 'show'" [formControlName]="'f_'+field.id" [placeholder]="'addon.mod_data.menuchoose' | translate" core-input-errors [(ngModel)]="val">
|
||||
<ion-option value="">{{ 'addon.mod_data.menuchoose' | translate }}</ion-option>
|
||||
<ion-option *ngFor="let option of options" [value]="option">{{option}}</ion-option>
|
||||
</ion-select>
|
||||
|
||||
<core-format-text *ngIf="mode == 'show' && value && value.content" [text]="value.content"></core-format-text>
|
|
@ -0,0 +1,57 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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, ElementRef } from '@angular/core';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
|
||||
|
||||
/**
|
||||
* Component to render data radiobutton field.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-data-field-radiobutton',
|
||||
templateUrl: 'radiobutton.html'
|
||||
})
|
||||
export class AddonModDataFieldRadiobuttonComponent extends AddonModDataFieldPluginComponent implements OnInit {
|
||||
|
||||
control: FormControl;
|
||||
options: number;
|
||||
val: number;
|
||||
|
||||
constructor(protected fb: FormBuilder, protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
|
||||
element: ElementRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.mode = this.mode == 'list' ? 'show' : this.mode;
|
||||
this.render();
|
||||
}
|
||||
|
||||
protected render(): void {
|
||||
if (this.mode == 'show') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.options = this.field.param1.split('\n');
|
||||
|
||||
if (this.mode == 'edit' && this.value) {
|
||||
this.val = this.value.content;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector, Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldHandler } from '../../../providers/fields-delegate';
|
||||
import { AddonModDataFieldRadiobuttonComponent } from '../component/radiobutton';
|
||||
|
||||
/**
|
||||
* Handler for checkbox data field plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModDataFieldRadiobuttonHandler implements AddonModDataFieldHandler {
|
||||
name = 'AddonModDataFieldRadiobuttonHandler';
|
||||
type = 'radiobutton';
|
||||
|
||||
constructor(private translate: TranslateService) { }
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} field The field object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModDataFieldRadiobuttonComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field search data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the search form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldSearchData(field: any, inputData: any): any {
|
||||
const fieldName = 'f_' + field.id;
|
||||
if (inputData[fieldName]) {
|
||||
return [{
|
||||
name: fieldName,
|
||||
value: inputData[fieldName]
|
||||
}];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field edit data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldEditData(field: any, inputData: any, originalFieldData: any): any {
|
||||
const fieldName = 'f_' + field.id;
|
||||
|
||||
if (inputData[fieldName]) {
|
||||
return [{
|
||||
fieldid: field.id,
|
||||
value: inputData[fieldName]
|
||||
}];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field data in changed.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @param {any} originalFieldData Original field entered data.
|
||||
* @return {Promise<boolean> | boolean} If the field has changes.
|
||||
*/
|
||||
hasFieldDataChanged(field: any, inputData: any, originalFieldData: any): Promise<boolean> | boolean {
|
||||
const fieldName = 'f_' + field.id,
|
||||
input = inputData[fieldName] || '';
|
||||
originalFieldData = (originalFieldData && originalFieldData.content) || '';
|
||||
|
||||
return input != originalFieldData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and get field requeriments.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {string | false} String with the notification or false.
|
||||
*/
|
||||
getFieldsNotifications(field: any, inputData: any): string | false {
|
||||
if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
|
||||
return this.translate.instant('addon.mod_data.errormustsupplyvalue');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override field content data with offline submission.
|
||||
*
|
||||
* @param {any} originalContent Original data to be overriden.
|
||||
* @param {any} offlineContent Array with all the offline data to override.
|
||||
* @param {any} [offlineFiles] Array with all the offline files in the field.
|
||||
* @return {any} Data overriden
|
||||
*/
|
||||
overrideData(originalContent: any, offlineContent: any, offlineFiles?: any): any {
|
||||
originalContent.content = offlineContent[''] || '';
|
||||
|
||||
return originalContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldRadiobuttonHandler } from './providers/handler';
|
||||
import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate';
|
||||
import { AddonModDataFieldRadiobuttonComponent } from './component/radiobutton';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModDataFieldRadiobuttonComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModDataFieldRadiobuttonHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModDataFieldRadiobuttonComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModDataFieldRadiobuttonComponent
|
||||
]
|
||||
})
|
||||
export class AddonModDataFieldRadiobuttonModule {
|
||||
constructor(fieldDelegate: AddonModDataFieldsDelegate, handler: AddonModDataFieldRadiobuttonHandler) {
|
||||
fieldDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<span *ngIf="mode == 'edit'" [core-mark-required]="field.required"></span>
|
||||
|
||||
<core-input-errors *ngIf="error && mode == 'edit'" [control]="form.controls['f_'+field.id]" [errorMessages]="error"></core-input-errors>
|
||||
|
||||
<ion-input *ngIf="mode != 'show'" type="text" [formControlName]="'f_'+field.id" [placeholder]="field.name" [(ngModel)]="val"></ion-input>
|
||||
|
||||
<core-format-text *ngIf="mode == 'show' && value && value.content" [text]="value.content"></core-format-text>
|
|
@ -0,0 +1,54 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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, ElementRef } from '@angular/core';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
|
||||
|
||||
/**
|
||||
* Component to render data text field.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-data-field-text',
|
||||
templateUrl: 'text.html'
|
||||
})
|
||||
export class AddonModDataFieldTextComponent extends AddonModDataFieldPluginComponent implements OnInit {
|
||||
|
||||
control: FormControl;
|
||||
val: number;
|
||||
|
||||
constructor(protected fb: FormBuilder, protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
|
||||
element: ElementRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.mode = this.mode == 'list' ? 'show' : this.mode;
|
||||
this.render();
|
||||
}
|
||||
|
||||
protected render(): void {
|
||||
if (this.mode == 'show') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.mode == 'edit' && this.value) {
|
||||
this.val = this.value.content;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector, Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldHandler } from '../../../providers/fields-delegate';
|
||||
import { AddonModDataFieldTextComponent } from '../component/text';
|
||||
|
||||
/**
|
||||
* Handler for number data field plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModDataFieldTextHandler implements AddonModDataFieldHandler {
|
||||
name = 'AddonModDataFieldTextHandler';
|
||||
type = 'text';
|
||||
|
||||
constructor(protected translate: TranslateService) { }
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} field The field object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModDataFieldTextComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field search data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the search form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldSearchData(field: any, inputData: any): any {
|
||||
const fieldName = 'f_' + field.id;
|
||||
|
||||
if (inputData[fieldName]) {
|
||||
return [{
|
||||
name: fieldName,
|
||||
value: inputData[fieldName]
|
||||
}];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field edit data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldEditData(field: any, inputData: any, originalFieldData: any): any {
|
||||
const fieldName = 'f_' + field.id;
|
||||
|
||||
if (inputData[fieldName]) {
|
||||
return [{
|
||||
fieldid: field.id,
|
||||
value: inputData[fieldName]
|
||||
}];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field data in changed.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @param {any} originalFieldData Original field entered data.
|
||||
* @return {Promise<boolean> | boolean} If the field has changes.
|
||||
*/
|
||||
hasFieldDataChanged(field: any, inputData: any, originalFieldData: any): Promise<boolean> | boolean {
|
||||
const fieldName = 'f_' + field.id,
|
||||
input = inputData[fieldName] || '';
|
||||
originalFieldData = (originalFieldData && originalFieldData.content) || '';
|
||||
|
||||
return input != originalFieldData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and get field requeriments.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {string | false} String with the notification or false.
|
||||
*/
|
||||
getFieldsNotifications(field: any, inputData: any): string | false {
|
||||
if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
|
||||
return this.translate.instant('addon.mod_data.errormustsupplyvalue');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override field content data with offline submission.
|
||||
*
|
||||
* @param {any} originalContent Original data to be overriden.
|
||||
* @param {any} offlineContent Array with all the offline data to override.
|
||||
* @param {any} [offlineFiles] Array with all the offline files in the field.
|
||||
* @return {any} Data overriden
|
||||
*/
|
||||
overrideData(originalContent: any, offlineContent: any, offlineFiles?: any): any {
|
||||
originalContent.content = offlineContent[''] || '';
|
||||
|
||||
return originalContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
|
||||
*/
|
||||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldTextHandler } from './providers/handler';
|
||||
import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate';
|
||||
import { AddonModDataFieldTextComponent } from './component/text';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModDataFieldTextComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModDataFieldTextHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModDataFieldTextComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModDataFieldTextComponent
|
||||
]
|
||||
})
|
||||
export class AddonModDataFieldTextModule {
|
||||
constructor(fieldDelegate: AddonModDataFieldsDelegate, handler: AddonModDataFieldTextHandler) {
|
||||
fieldDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<span *ngIf="mode == 'edit'" [core-mark-required]="field.required"></span>
|
||||
|
||||
<core-input-errors *ngIf="error && mode == 'edit'" [control]="form.controls['f_'+field.id]" [errorMessages]="error"></core-input-errors>
|
||||
|
||||
<input *ngIf="mode == 'search'" type="text" [placeholder]="field.name" [name]="'f_'+field.id">
|
||||
|
||||
<core-rich-text-editor *ngIf="mode == 'edit'" item-content [control]="form.controls['f_'+field.id]" [placeholder]="field.name" [formControlName]="'f_'+field.id"></core-rich-text-editor>
|
||||
<!-- @todo: [component]="component" [componentId]="componentId" -->
|
||||
|
||||
<core-format-text *ngIf="mode == 'show' && value" [text]="value.content" [component]="component" [componentId]="componentId"></core-format-text>
|
|
@ -0,0 +1,69 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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, ElementRef } from '@angular/core';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModDataProvider } from '../../../providers/data';
|
||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
|
||||
|
||||
/**
|
||||
* Component to render data number field.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-data-field-textarea',
|
||||
templateUrl: 'textarea.html'
|
||||
})
|
||||
export class AddonModDataFieldTextareaComponent extends AddonModDataFieldPluginComponent implements OnInit {
|
||||
|
||||
control: FormControl;
|
||||
component: string;
|
||||
componentId: number;
|
||||
|
||||
constructor(protected fb: FormBuilder, protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
|
||||
element: ElementRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
format(value: any): string {
|
||||
const files = (value && value.files) || [];
|
||||
|
||||
return value ? this.textUtils.replacePluginfileUrls(value.content, files) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.mode = this.mode == 'list' ? 'show' : this.mode;
|
||||
this.render();
|
||||
}
|
||||
|
||||
protected render(): void {
|
||||
if (this.mode == 'show') {
|
||||
this.component = AddonModDataProvider.COMPONENT;
|
||||
this.componentId = this.database.coursemodule;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if rich text editor is enabled.
|
||||
if (this.mode == 'edit') {
|
||||
const files = (this.value && this.value.files) || [],
|
||||
text = this.value ? this.textUtils.replacePluginfileUrls(this.value.content, files) : '';
|
||||
|
||||
this.control = this.fb.control(text);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector, Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldTextHandler } from '../../text/providers/handler';
|
||||
import { AddonModDataFieldTextareaComponent } from '../component/textarea';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
|
||||
/**
|
||||
* Handler for textarea data field plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModDataFieldTextareaHandler extends AddonModDataFieldTextHandler {
|
||||
name = 'AddonModDataFieldTextareaHandler';
|
||||
type = 'textarea';
|
||||
|
||||
constructor(protected translate: TranslateService, private textUtils: CoreTextUtilsProvider,
|
||||
private domUtils: CoreDomUtilsProvider) {
|
||||
super(translate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} field The field object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModDataFieldTextareaComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field edit data in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldEditData(field: any, inputData: any, originalFieldData: any): any {
|
||||
const fieldName = 'f_' + field.id;
|
||||
|
||||
if (inputData[fieldName]) {
|
||||
return this.domUtils.isRichTextEditorEnabled().then((enabled) => {
|
||||
const files = this.getFieldEditFiles(field, inputData, originalFieldData);
|
||||
let text = this.textUtils.restorePluginfileUrls(inputData[fieldName], files);
|
||||
|
||||
if (!enabled) {
|
||||
// Rich text editor not enabled, add some HTML to the text if needed.
|
||||
text = this.textUtils.formatHtmlLines(text);
|
||||
}
|
||||
|
||||
return [{
|
||||
fieldid: field.id,
|
||||
value: text
|
||||
},
|
||||
{
|
||||
fieldid: field.id,
|
||||
subfield: 'content1',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
fieldid: field.id,
|
||||
subfield: 'itemid',
|
||||
files: files
|
||||
}
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field edit files in the input data.
|
||||
*
|
||||
* @param {any} field Defines the field..
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @param {any} originalFieldData Original field entered data.
|
||||
* @return {any} With name and value of the data to be sent.
|
||||
*/
|
||||
getFieldEditFiles(field: any, inputData: any, originalFieldData: any): any {
|
||||
return (originalFieldData && originalFieldData.files) || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and get field requeriments.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {string | false} String with the notification or false.
|
||||
*/
|
||||
getFieldsNotifications(field: any, inputData: any): string | false {
|
||||
if (field.required) {
|
||||
if (!inputData || !inputData.length) {
|
||||
return this.translate.instant('addon.mod_data.errormustsupplyvalue');
|
||||
}
|
||||
|
||||
const found = inputData.some((input) => {
|
||||
if (!input.subfield) {
|
||||
return !!input.value;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!found) {
|
||||
return this.translate.instant('addon.mod_data.errormustsupplyvalue');
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override field content data with offline submission.
|
||||
*
|
||||
* @param {any} originalContent Original data to be overriden.
|
||||
* @param {any} offlineContent Array with all the offline data to override.
|
||||
* @param {any} [offlineFiles] Array with all the offline files in the field.
|
||||
* @return {any} Data overriden
|
||||
*/
|
||||
overrideData(originalContent: any, offlineContent: any, offlineFiles?: any): any {
|
||||
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 = this.textUtils.replacePluginfileUrls(originalContent.content, originalContent.files);
|
||||
}
|
||||
|
||||
return originalContent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldTextareaHandler } from './providers/handler';
|
||||
import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate';
|
||||
import { AddonModDataFieldTextareaComponent } from './component/textarea';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModDataFieldTextareaComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModDataFieldTextareaHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModDataFieldTextareaComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModDataFieldTextareaComponent
|
||||
]
|
||||
})
|
||||
export class AddonModDataFieldTextareaModule {
|
||||
constructor(fieldDelegate: AddonModDataFieldsDelegate, handler: AddonModDataFieldTextareaHandler) {
|
||||
fieldDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<span *ngIf="mode == 'edit'" [core-mark-required]="field.required"></span>
|
||||
|
||||
<core-input-errors *ngIf="error && mode == 'edit'" [control]="form.controls['f_'+field.id]" [errorMessages]="error"></core-input-errors>
|
||||
|
||||
<ion-input *ngIf="mode != 'show'" type="url" [formControlName]="'f_'+field.id" [placeholder]="field.name" [(ngModel)]="val"></ion-input>
|
||||
|
||||
<a *ngIf="mode == 'show' && value && value.content" [href]="value.content" core-link capture-link="true">{{field.name}}</a>
|
|
@ -0,0 +1,54 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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, ElementRef } from '@angular/core';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { AddonModDataFieldPluginComponent } from '../../../classes/field-plugin-component';
|
||||
|
||||
/**
|
||||
* Component to render data url field.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-data-field-url',
|
||||
templateUrl: 'url.html'
|
||||
})
|
||||
export class AddonModDataFieldUrlComponent extends AddonModDataFieldPluginComponent implements OnInit {
|
||||
|
||||
control: FormControl;
|
||||
val: number;
|
||||
|
||||
constructor(protected fb: FormBuilder, protected domUtils: CoreDomUtilsProvider, protected textUtils: CoreTextUtilsProvider,
|
||||
element: ElementRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.mode = this.mode == 'list' ? 'show' : this.mode;
|
||||
this.render();
|
||||
}
|
||||
|
||||
protected render(): void {
|
||||
if (this.mode == 'show') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.mode == 'edit' && this.value) {
|
||||
this.val = this.value.content;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector, Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldTextHandler } from '../../text/providers/handler';
|
||||
import { AddonModDataFieldUrlComponent } from '../component/url';
|
||||
|
||||
/**
|
||||
* Handler for url data field plugin.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AddonModDataFieldUrlHandler extends AddonModDataFieldTextHandler {
|
||||
name = 'AddonModDataFieldUrlHandler';
|
||||
type = 'url';
|
||||
|
||||
constructor(protected translate: TranslateService) {
|
||||
super(translate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} field The field object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
return AddonModDataFieldUrlComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and get field requeriments.
|
||||
*
|
||||
* @param {any} field Defines the field to be rendered.
|
||||
* @param {any} inputData Data entered in the edit form.
|
||||
* @return {string | false} String with the notification or false.
|
||||
*/
|
||||
getFieldsNotifications(field: any, inputData: any): string | false {
|
||||
if (field.required && (!inputData || !inputData.length || !inputData[0].value)) {
|
||||
return this.translate.instant('addon.mod_data.errormustsupplyvalue');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from 'ionic-angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AddonModDataFieldUrlHandler } from './providers/handler';
|
||||
import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate';
|
||||
import { AddonModDataFieldUrlComponent } from './component/url';
|
||||
import { CoreComponentsModule } from '@components/components.module';
|
||||
import { CoreDirectivesModule } from '@directives/directives.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModDataFieldUrlComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreComponentsModule,
|
||||
CoreDirectivesModule
|
||||
],
|
||||
providers: [
|
||||
AddonModDataFieldUrlHandler
|
||||
],
|
||||
exports: [
|
||||
AddonModDataFieldUrlComponent
|
||||
],
|
||||
entryComponents: [
|
||||
AddonModDataFieldUrlComponent
|
||||
]
|
||||
})
|
||||
export class AddonModDataFieldUrlModule {
|
||||
constructor(fieldDelegate: AddonModDataFieldsDelegate, handler: AddonModDataFieldUrlHandler) {
|
||||
fieldDelegate.registerHandler(handler);
|
||||
}
|
||||
}
|
|
@ -113,7 +113,7 @@ export class AddonModDataHelperProvider {
|
|||
replace = new RegExp(replace, 'gi');
|
||||
|
||||
// Replace field by a generic directive.
|
||||
const render = '<addon-mod-data-field-plugin mode="search" field="fields[' + field.id +
|
||||
const render = '<addon-mod-data-field-plugin mode="search" [field]="fields[' + field.id +
|
||||
']"></addon-mod-data-field-plugin>';
|
||||
template = template.replace(replace, render);
|
||||
});
|
||||
|
@ -156,13 +156,13 @@ export class AddonModDataHelperProvider {
|
|||
replace = new RegExp(replace, 'gi');
|
||||
|
||||
// Replace field by a generic directive.
|
||||
render = '<addon-mod-data-field-plugin field="fields[' + field.id + ']" value="entries[' + entry.id + '].contents[' +
|
||||
field.id + ']" mode="' + mode + '" database="data" (viewAction)="gotoEntry(' + entry.id +
|
||||
render = '<addon-mod-data-field-plugin [field]="fields[' + field.id + ']" [value]="entries[' + entry.id +
|
||||
'].contents[' + field.id + ']" mode="' + mode + '" [database]="data" (viewAction)="gotoEntry(' + entry.id +
|
||||
')"></addon-mod-data-field-plugin>';
|
||||
template = template.replace(replace, render);
|
||||
});
|
||||
|
||||
for (const action in actions) {
|
||||
/*for (const action in actions) {
|
||||
replace = new RegExp('##' + action + '##', 'gi');
|
||||
// Is enabled?
|
||||
if (actions[action]) {
|
||||
|
@ -179,7 +179,7 @@ export class AddonModDataHelperProvider {
|
|||
} else {
|
||||
template = template.replace(replace, '');
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return template;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ export class AddonModFeedbackHelperProvider {
|
|||
protected getActivityHistoryBackCounter(pageName: string, instance: number, paramName: string, prefix: string,
|
||||
navCtrl: NavController): number {
|
||||
let historyInstance, params,
|
||||
backTimes = 0,
|
||||
view = navCtrl.getActive();
|
||||
|
||||
while (!view.isFirst()) {
|
||||
|
@ -60,9 +59,7 @@ export class AddonModFeedbackHelperProvider {
|
|||
historyInstance = params.get(paramName) ? params.get(paramName) : params.get('module').instance;
|
||||
|
||||
// Check we are not changing to another activity.
|
||||
if (historyInstance && historyInstance == instance) {
|
||||
backTimes++;
|
||||
} else {
|
||||
if (!historyInstance || historyInstance != instance) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
|
|||
@Input() text: string; // The HTML text to display.
|
||||
@Input() javascript: string; // The Javascript to execute in the component.
|
||||
@Input() jsData: any; // Data to pass to the fake component.
|
||||
@Input() extraImports: any[] = []; // Extra import modules.
|
||||
@Input() extraProviders: any[] = []; // Extra providers.
|
||||
@Output() created: EventEmitter<any> = new EventEmitter(); // Will emit an event when the component is instantiated.
|
||||
|
||||
// Get the container where to put the content.
|
||||
|
@ -61,7 +63,8 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
|
|||
ngOnChanges(changes: { [name: string]: SimpleChange }): void {
|
||||
if ((changes.text || changes.javascript) && this.text) {
|
||||
// Create a new component and a new module.
|
||||
this.compileProvider.createAndCompileComponent(this.text, this.getComponentClass()).then((factory) => {
|
||||
this.compileProvider.createAndCompileComponent(this.text, this.getComponentClass(), this.extraImports)
|
||||
.then((factory) => {
|
||||
// Destroy previous components.
|
||||
this.componentRef && this.componentRef.destroy();
|
||||
|
||||
|
@ -95,7 +98,7 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
|
|||
constructor() {
|
||||
// If there is some javascript to run, prepare the instance.
|
||||
if (compileInstance.javascript) {
|
||||
compileInstance.compileProvider.injectLibraries(this);
|
||||
compileInstance.compileProvider.injectLibraries(this, compileInstance.extraProviders);
|
||||
}
|
||||
|
||||
// Always add these elements, they could be needed on component init (componentObservable).
|
||||
|
|
|
@ -112,17 +112,20 @@ export class CoreCompileProvider {
|
|||
*
|
||||
* @param {string} template The template of the component.
|
||||
* @param {any} componentClass The JS class of the component.
|
||||
* @param {any[]} [extraImports] Extra imported modules if needed and not imported by this class.
|
||||
* @return {Promise<ComponentFactory<any>>} Promise resolved with the factory to instantiate the component.
|
||||
*/
|
||||
createAndCompileComponent(template: string, componentClass: any): Promise<ComponentFactory<any>> {
|
||||
createAndCompileComponent(template: string, componentClass: any, extraImports: any[] = []): Promise<ComponentFactory<any>> {
|
||||
// Create the component using the template and the class.
|
||||
const component = Component({
|
||||
template: template
|
||||
})
|
||||
(componentClass);
|
||||
|
||||
const imports = this.IMPORTS.concat(extraImports);
|
||||
|
||||
// Now create the module containing the component.
|
||||
const module = NgModule({imports: this.IMPORTS, declarations: [component]})(class {});
|
||||
const module = NgModule({imports: imports, declarations: [component]})(class {});
|
||||
|
||||
// Compile the module and the component.
|
||||
return this.compiler.compileModuleAndAllComponentsAsync(module).then((factories) => {
|
||||
|
@ -166,13 +169,14 @@ export class CoreCompileProvider {
|
|||
* Inject all the core libraries in a certain object.
|
||||
*
|
||||
* @param {any} instance The instance where to inject the libraries.
|
||||
* @param {any[]} [extraProviders] Extra imported providers if needed and not imported by this class.
|
||||
*/
|
||||
injectLibraries(instance: any): void {
|
||||
injectLibraries(instance: any, extraProviders: any[] = []): void {
|
||||
const providers = (<any[]> CORE_PROVIDERS).concat(CORE_CONTENTLINKS_PROVIDERS).concat(CORE_COURSE_PROVIDERS)
|
||||
.concat(CORE_COURSES_PROVIDERS).concat(CORE_FILEUPLOADER_PROVIDERS).concat(CORE_GRADES_PROVIDERS)
|
||||
.concat(CORE_LOGIN_PROVIDERS).concat(CORE_MAINMENU_PROVIDERS).concat(CORE_SHAREDFILES_PROVIDERS)
|
||||
.concat(CORE_SITEHOME_PROVIDERS).concat([CoreSitePluginsProvider]).concat(CORE_USER_PROVIDERS)
|
||||
.concat(CORE_QUESTION_PROVIDERS).concat(IONIC_NATIVE_PROVIDERS).concat(this.OTHER_PROVIDERS);
|
||||
.concat(CORE_QUESTION_PROVIDERS).concat(IONIC_NATIVE_PROVIDERS).concat(this.OTHER_PROVIDERS).concat(extraProviders);
|
||||
|
||||
// We cannot inject anything to this constructor. Use the Injector to inject all the providers into the instance.
|
||||
for (const i in providers) {
|
||||
|
|
Loading…
Reference in New Issue