diff --git a/src/addon/userprofilefield/checkbox/checkbox.module.ts b/src/addon/userprofilefield/checkbox/checkbox.module.ts
new file mode 100644
index 000000000..1d85b6890
--- /dev/null
+++ b/src/addon/userprofilefield/checkbox/checkbox.module.ts
@@ -0,0 +1,46 @@
+// (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 { IonicModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { AddonUserProfileFieldCheckboxHandler } from './providers/handler';
+import { CoreUserProfileFieldDelegate } from '../../../core/user/providers/user-profile-field-delegate';
+import { AddonUserProfileFieldCheckboxComponent } from './component/checkbox';
+import { CoreComponentsModule } from '../../../components/components.module';
+
+@NgModule({
+ declarations: [
+ AddonUserProfileFieldCheckboxComponent
+ ],
+ imports: [
+ IonicModule,
+ TranslateModule.forChild(),
+ CoreComponentsModule
+ ],
+ providers: [
+ AddonUserProfileFieldCheckboxHandler
+ ],
+ exports: [
+ AddonUserProfileFieldCheckboxComponent
+ ],
+ entryComponents: [
+ AddonUserProfileFieldCheckboxComponent
+ ]
+})
+export class AddonUserProfileFieldCheckboxModule {
+ constructor(userProfileFieldDelegate: CoreUserProfileFieldDelegate, handler: AddonUserProfileFieldCheckboxHandler) {
+ userProfileFieldDelegate.registerHandler(handler);
+ }
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/checkbox/component/checkbox.html b/src/addon/userprofilefield/checkbox/component/checkbox.html
new file mode 100644
index 000000000..8ab6fe45f
--- /dev/null
+++ b/src/addon/userprofilefield/checkbox/component/checkbox.html
@@ -0,0 +1,16 @@
+
+
+
{{ field.name }}
+
+ {{ 'core.yes' | translate }}
+
+
+ {{ 'core.no' | translate }}
+
+
+
+
+ {{ field.name }}
+
+
+
\ No newline at end of file
diff --git a/src/addon/userprofilefield/checkbox/component/checkbox.scss b/src/addon/userprofilefield/checkbox/component/checkbox.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/addon/userprofilefield/checkbox/component/checkbox.ts b/src/addon/userprofilefield/checkbox/component/checkbox.ts
new file mode 100644
index 000000000..28f11a4bf
--- /dev/null
+++ b/src/addon/userprofilefield/checkbox/component/checkbox.ts
@@ -0,0 +1,47 @@
+// (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, Input, OnInit } from '@angular/core';
+
+/**
+ * Directive to render a checkbox user profile field.
+ */
+@Component({
+ selector: 'core-user-profile-field-checkbox',
+ templateUrl: 'checkbox.html'
+})
+export class AddonUserProfileFieldCheckboxComponent implements OnInit {
+ @Input() field: any; // The profile field to be rendered.
+ @Input() edit?: boolean = false; // True if editing the field. Defaults to false.
+ @Input() model?: any; // Model where to store the data. Required if edit=true or signup=true.
+
+ constructor() {}
+
+ /**
+ * Component being initialized.
+ */
+ ngOnInit() {
+ let field = this.field;
+
+ if (field && this.edit && this.model) {
+ field.modelName = 'profile_field_' + field.shortname;
+
+ // Initialize the value.
+ if (typeof field.defaultdata != 'undefined' && typeof this.model[field.modelName] == 'undefined') {
+ this.model[field.modelName] = field.defaultdata && field.defaultdata !== '0' && field.defaultdata !== 'false';
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/checkbox/providers/handler.ts b/src/addon/userprofilefield/checkbox/providers/handler.ts
new file mode 100644
index 000000000..69c7ac051
--- /dev/null
+++ b/src/addon/userprofilefield/checkbox/providers/handler.ts
@@ -0,0 +1,70 @@
+
+// (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 { Injectable } from '@angular/core';
+import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '../../../../core/user/providers/user-profile-field-delegate';
+import { AddonUserProfileFieldCheckboxComponent } from '../component/checkbox';
+
+/**
+ * Checkbox user profile field handlers.
+ */
+@Injectable()
+export class AddonUserProfileFieldCheckboxHandler implements CoreUserProfileFieldHandler {
+ name = 'checkbox';
+
+ constructor() {}
+
+ /**
+ * Whether or not the handler is enabled on a site level.
+ *
+ * @return {boolean|Promise} True or promise resolved with true if enabled.
+ */
+ isEnabled() : boolean|Promise {
+ return true;
+ }
+
+ /**
+ * Get the data to send for the field based on the input data.
+ *
+ * @param {any} field User field to get the data for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @param {any} model Model with the input data.
+ * @return {CoreUserProfileFieldHandlerData} Data to send for the field.
+ */
+ getData(field: any, signup: boolean, registerAuth: string, model: any): CoreUserProfileFieldHandlerData {
+ let name = 'profile_field_' + field.shortname;
+
+ if (typeof model[name] != 'undefined') {
+ return {
+ type: 'checkbox',
+ name: name,
+ value: model[name] ? 1 : 0
+ };
+ }
+ }
+
+ /**
+ * Return the Component to use to display the user profile field.
+ *
+ * @param {any} field User field to get the data for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @return {any} The component to use, undefined if not found.
+ */
+ getComponent(field: any, signup: boolean, registerAuth: string) {
+ return AddonUserProfileFieldCheckboxComponent;
+ }
+
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/datetime/component/datetime.html b/src/addon/userprofilefield/datetime/component/datetime.html
new file mode 100644
index 000000000..cd19d4595
--- /dev/null
+++ b/src/addon/userprofilefield/datetime/component/datetime.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ {{ field.name }}
+
+
\ No newline at end of file
diff --git a/src/addon/userprofilefield/datetime/component/datetime.scss b/src/addon/userprofilefield/datetime/component/datetime.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/addon/userprofilefield/datetime/component/datetime.ts b/src/addon/userprofilefield/datetime/component/datetime.ts
new file mode 100644
index 000000000..4526abc5e
--- /dev/null
+++ b/src/addon/userprofilefield/datetime/component/datetime.ts
@@ -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, Input, OnInit } from '@angular/core';
+
+/**
+ * Directive to render a datetime user profile field.
+ */
+@Component({
+ selector: 'core-user-profile-field-datetime',
+ templateUrl: 'datetime.html'
+})
+export class AddonUserProfileFieldDatetimeComponent implements OnInit {
+ @Input() field: any; // The profile field to be rendered.
+ @Input() edit?: boolean = false; // True if editing the field. Defaults to false.
+ @Input() model?: any; // Model where to store the data. Required if edit=true or signup=true.
+
+
+ constructor() {}
+
+ /**
+ * Component being initialized.
+ */
+ ngOnInit() {
+ let field = this.field,
+ year;
+ if (field && this.edit && this.model) {
+ field.modelName = 'profile_field_' + field.shortname;
+
+ // Check if it's only date or it has time too.
+ field.hasTime = field.param3 && field.param3 !== '0' && field.param3 !== 'false';
+ field.format = field.hasTime ? 'core.dffulldate' : 'core.dfdaymonthyear';
+
+ // Check min value.
+ if (field.param1) {
+ year = parseInt(field.param1, 10);
+ if (year) {
+ field.min = year;
+ }
+ }
+
+ // Check max value.
+ if (field.param2) {
+ year = parseInt(field.param2, 10);
+ if (year) {
+ field.max = year;
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/datetime/datetime.module.ts b/src/addon/userprofilefield/datetime/datetime.module.ts
new file mode 100644
index 000000000..1697b0e9f
--- /dev/null
+++ b/src/addon/userprofilefield/datetime/datetime.module.ts
@@ -0,0 +1,48 @@
+// (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 { IonicModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { AddonUserProfileFieldDatetimeHandler } from './providers/handler';
+import { CoreUserProfileFieldDelegate } from '../../../core/user/providers/user-profile-field-delegate';
+import { AddonUserProfileFieldDatetimeComponent } from './component/datetime';
+import { CoreComponentsModule } from '../../../components/components.module';
+import { CorePipesModule } from '../../../pipes/pipes.module';
+
+@NgModule({
+ declarations: [
+ AddonUserProfileFieldDatetimeComponent
+ ],
+ imports: [
+ IonicModule,
+ TranslateModule.forChild(),
+ CoreComponentsModule,
+ CorePipesModule
+ ],
+ providers: [
+ AddonUserProfileFieldDatetimeHandler
+ ],
+ exports: [
+ AddonUserProfileFieldDatetimeComponent
+ ],
+ entryComponents: [
+ AddonUserProfileFieldDatetimeComponent
+ ]
+})
+export class AddonUserProfileFieldDatetimeModule {
+ constructor(userProfileFieldDelegate: CoreUserProfileFieldDelegate, handler: AddonUserProfileFieldDatetimeHandler) {
+ userProfileFieldDelegate.registerHandler(handler);
+ }
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/datetime/providers/handler.ts b/src/addon/userprofilefield/datetime/providers/handler.ts
new file mode 100644
index 000000000..ad3c95414
--- /dev/null
+++ b/src/addon/userprofilefield/datetime/providers/handler.ts
@@ -0,0 +1,85 @@
+
+// (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 { Injectable } from '@angular/core';
+import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '../../../../core/user/providers/user-profile-field-delegate';
+import { AddonUserProfileFieldDatetimeComponent } from '../component/datetime';
+import { Platform } from 'ionic-angular';
+
+/**
+ * Datetime user profile field handlers.
+ */
+@Injectable()
+export class AddonUserProfileFieldDatetimeHandler implements CoreUserProfileFieldHandler {
+ name = 'datetime';
+
+ constructor(private platform: Platform) {}
+
+ /**
+ * Whether or not the handler is enabled on a site level.
+ *
+ * @return {boolean|Promise} True or promise resolved with true if enabled.
+ */
+ isEnabled() : boolean|Promise {
+ return true;
+ }
+
+ /**
+ * Get the data to send for the field based on the input data.
+ *
+ * @param {any} field User field to get the data for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @param {any} model Model with the input data.
+ * @return {CoreUserProfileFieldHandlerData} Data to send for the field.
+ */
+ getData(field: any, signup: boolean, registerAuth: string, model: any): CoreUserProfileFieldHandlerData {
+ let hasTime = field.param3 && field.param3 !== '0' && field.param3 !== 'false',
+ modelName = 'profile_field_' + field.shortname,
+ date = JSON.parse(JSON.stringify(model[modelName + '_date'])),
+ time;
+
+ if (date) {
+ if (hasTime && this.platform.is('ios')) {
+ // In iOS the time is in a different input. Add it to the date.
+ time = model[modelName + '_time'];
+ if (!time) {
+ return;
+ }
+
+ date.setHours(time.getHours());
+ date.setMinutes(time.getMinutes());
+ }
+
+ return {
+ type: 'datetime',
+ name: 'profile_field_' + field.shortname,
+ value: Math.round(date.getTime() / 1000)
+ };
+ }
+ }
+
+ /**
+ * Return the Component to use to display the user profile field.
+ *
+ * @param {any} field User field to get the data for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @return {any} The component to use, undefined if not found.
+ */
+ getComponent(field: any, signup: boolean, registerAuth: string) {
+ return AddonUserProfileFieldDatetimeComponent;
+ }
+
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/menu/component/menu.html b/src/addon/userprofilefield/menu/component/menu.html
new file mode 100644
index 000000000..23ee49f9b
--- /dev/null
+++ b/src/addon/userprofilefield/menu/component/menu.html
@@ -0,0 +1,13 @@
+
+
+
{{ field.name }}
+
+
+
+
+ {{ field.name }}
+
+ {{ 'core.choosedots' | translate }}
+ {{option}}
+
+
diff --git a/src/addon/userprofilefield/menu/component/menu.scss b/src/addon/userprofilefield/menu/component/menu.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/addon/userprofilefield/menu/component/menu.ts b/src/addon/userprofilefield/menu/component/menu.ts
new file mode 100644
index 000000000..98bf2f43b
--- /dev/null
+++ b/src/addon/userprofilefield/menu/component/menu.ts
@@ -0,0 +1,55 @@
+// (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, Input, OnInit } from '@angular/core';
+
+/**
+ * Directive to render a menu user profile field.
+ */
+@Component({
+ selector: 'core-user-profile-field-menu',
+ templateUrl: 'menu.html'
+})
+export class AddonUserProfileFieldMenuComponent implements OnInit {
+ @Input() field: any; // The profile field to be rendered.
+ @Input() edit?: boolean = false; // True if editing the field. Defaults to false.
+ @Input() model?: any; // Model where to store the data. Required if edit=true or signup=true.
+
+ constructor() {}
+
+ /**
+ * Component being initialized.
+ */
+ ngOnInit() {
+ let field = this.field;
+
+ if (field && this.edit && this.model) {
+ field.modelName = 'profile_field_' + field.shortname;
+
+ // Parse options.
+ if (field.param1) {
+ field.options = field.param1.split(/\r\n|\r|\n/g);
+ } else {
+ field.options = [];
+ }
+
+ // Initialize the value using default data.
+ if (typeof field.defaultdata != 'undefined' && typeof this.model[field.modelName] == 'undefined') {
+ this.model[field.modelName] = field.defaultdata;
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/menu/menu.module.ts b/src/addon/userprofilefield/menu/menu.module.ts
new file mode 100644
index 000000000..dfaa1c0ea
--- /dev/null
+++ b/src/addon/userprofilefield/menu/menu.module.ts
@@ -0,0 +1,48 @@
+// (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 { IonicModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { AddonUserProfileFieldMenuHandler } from './providers/handler';
+import { CoreUserProfileFieldDelegate } from '../../../core/user/providers/user-profile-field-delegate';
+import { AddonUserProfileFieldMenuComponent } from './component/menu';
+import { CoreComponentsModule } from '../../../components/components.module';
+import { CoreDirectivesModule } from '../../../directives/directives.module';
+
+@NgModule({
+ declarations: [
+ AddonUserProfileFieldMenuComponent
+ ],
+ imports: [
+ IonicModule,
+ TranslateModule.forChild(),
+ CoreComponentsModule,
+ CoreDirectivesModule
+ ],
+ providers: [
+ AddonUserProfileFieldMenuHandler
+ ],
+ exports: [
+ AddonUserProfileFieldMenuComponent
+ ],
+ entryComponents: [
+ AddonUserProfileFieldMenuComponent
+ ]
+})
+export class AddonUserProfileFieldMenuModule {
+ constructor(userProfileFieldDelegate: CoreUserProfileFieldDelegate, handler: AddonUserProfileFieldMenuHandler) {
+ userProfileFieldDelegate.registerHandler(handler);
+ }
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/menu/providers/handler.ts b/src/addon/userprofilefield/menu/providers/handler.ts
new file mode 100644
index 000000000..470fd1d3d
--- /dev/null
+++ b/src/addon/userprofilefield/menu/providers/handler.ts
@@ -0,0 +1,70 @@
+
+// (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 { Injectable } from '@angular/core';
+import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '../../../../core/user/providers/user-profile-field-delegate';
+import { AddonUserProfileFieldMenuComponent } from '../component/menu';
+
+/**
+ * Menu user profile field handlers.
+ */
+@Injectable()
+export class AddonUserProfileFieldMenuHandler implements CoreUserProfileFieldHandler {
+ name = 'menu';
+
+ constructor() {}
+
+ /**
+ * Whether or not the handler is enabled on a site level.
+ *
+ * @return {boolean|Promise} True or promise resolved with true if enabled.
+ */
+ isEnabled() : boolean|Promise {
+ return true;
+ }
+
+ /**
+ * Get the data to send for the field based on the input data.
+ *
+ * @param {any} field User field to get the data for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @param {any} model Model with the input data.
+ * @return {CoreUserProfileFieldHandlerData} Data to send for the field.
+ */
+ getData(field: any, signup: boolean, registerAuth: string, model: any): CoreUserProfileFieldHandlerData {
+ let name = 'profile_field_' + field.shortname;
+
+ if (model[name]) {
+ return {
+ type: 'menu',
+ name: name,
+ value: model[name]
+ };
+ }
+ }
+
+ /**
+ * Return the Component to use to display the user profile field.
+ *
+ * @param {any} field User field to get the data for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @return {any} The component to use, undefined if not found.
+ */
+ getComponent(field: any, signup: boolean, registerAuth: string) {
+ return AddonUserProfileFieldMenuComponent;
+ }
+
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/text/component/text.html b/src/addon/userprofilefield/text/component/text.html
new file mode 100644
index 000000000..c27315320
--- /dev/null
+++ b/src/addon/userprofilefield/text/component/text.html
@@ -0,0 +1,10 @@
+
+
+
{{ field.name }}
+
+
+
+
+ {{ field.name }}
+
+
diff --git a/src/addon/userprofilefield/text/component/text.scss b/src/addon/userprofilefield/text/component/text.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/addon/userprofilefield/text/component/text.ts b/src/addon/userprofilefield/text/component/text.ts
new file mode 100644
index 000000000..f8fd5b72e
--- /dev/null
+++ b/src/addon/userprofilefield/text/component/text.ts
@@ -0,0 +1,55 @@
+// (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, Input, OnInit } from '@angular/core';
+
+/**
+ * Directive to render a text user profile field.
+ */
+@Component({
+ selector: 'core-user-profile-field-text',
+ templateUrl: 'text.html'
+})
+export class AddonUserProfileFieldTextComponent implements OnInit {
+ @Input() field: any; // The profile field to be rendered.
+ @Input() edit?: boolean = false; // True if editing the field. Defaults to false.
+ @Input() model?: any; // Model where to store the data. Required if edit=true or signup=true.
+
+ constructor() {}
+
+ /**
+ * Component being initialized.
+ */
+ ngOnInit() {
+ let field = this.field;
+
+ if (field && this.edit && this.model) {
+ field.modelName = 'profile_field_' + field.shortname;
+
+ // Check max length.
+ if (field.param2) {
+ field.maxlength = parseInt(field.param2, 10) || '';
+ }
+
+ // Check if it's a password or text.
+ field.inputType = field.param3 && field.param3 !== '0' && field.param3 !== 'false' ? 'password' : 'text';
+
+ // Initialize the value using default data.
+ if (typeof field.defaultdata != 'undefined' && typeof this.model[field.modelName] == 'undefined') {
+ this.model[field.modelName] = field.defaultdata;
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/text/providers/handler.ts b/src/addon/userprofilefield/text/providers/handler.ts
new file mode 100644
index 000000000..30949f452
--- /dev/null
+++ b/src/addon/userprofilefield/text/providers/handler.ts
@@ -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 { Injectable } from '@angular/core';
+import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '../../../../core/user/providers/user-profile-field-delegate';
+import { AddonUserProfileFieldTextComponent } from '../component/text';
+import { CoreTextUtilsProvider } from '../../../../providers/utils/text';
+
+/**
+ * Text user profile field handlers.
+ */
+@Injectable()
+export class AddonUserProfileFieldTextHandler implements CoreUserProfileFieldHandler {
+ name = 'text';
+
+ constructor(private textUtils: CoreTextUtilsProvider) {}
+
+ /**
+ * Whether or not the handler is enabled on a site level.
+ *
+ * @return {boolean|Promise} True or promise resolved with true if enabled.
+ */
+ isEnabled() : boolean|Promise {
+ return true;
+ }
+
+ /**
+ * Get the data to send for the field based on the input data.
+ *
+ * @param {any} field User field to get the data for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @param {any} model Model with the input data.
+ * @return {CoreUserProfileFieldHandlerData} Data to send for the field.
+ */
+ getData(field: any, signup: boolean, registerAuth: string, model: any): CoreUserProfileFieldHandlerData {
+ let name = 'profile_field_' + field.shortname;
+
+ return {
+ type: 'text',
+ name: name,
+ value: this.textUtils.cleanTags(model[name])
+ };
+ }
+
+ /**
+ * Return the Component to use to display the user profile field.
+ *
+ * @param {any} field User field to get the data for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @return {any} The component to use, undefined if not found.
+ */
+ getComponent(field: any, signup: boolean, registerAuth: string) {
+ return AddonUserProfileFieldTextComponent;
+ }
+
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/text/text.module.ts b/src/addon/userprofilefield/text/text.module.ts
new file mode 100644
index 000000000..4264c858c
--- /dev/null
+++ b/src/addon/userprofilefield/text/text.module.ts
@@ -0,0 +1,48 @@
+// (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 { IonicModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { AddonUserProfileFieldTextHandler } from './providers/handler';
+import { CoreUserProfileFieldDelegate } from '../../../core/user/providers/user-profile-field-delegate';
+import { AddonUserProfileFieldTextComponent } from './component/text';
+import { CoreComponentsModule } from '../../../components/components.module';
+import { CoreDirectivesModule } from '../../../directives/directives.module';
+
+@NgModule({
+ declarations: [
+ AddonUserProfileFieldTextComponent
+ ],
+ imports: [
+ IonicModule,
+ TranslateModule.forChild(),
+ CoreComponentsModule,
+ CoreDirectivesModule
+ ],
+ providers: [
+ AddonUserProfileFieldTextHandler
+ ],
+ exports: [
+ AddonUserProfileFieldTextComponent
+ ],
+ entryComponents: [
+ AddonUserProfileFieldTextComponent
+ ]
+})
+export class AddonUserProfileFieldTextModule {
+ constructor(userProfileFieldDelegate: CoreUserProfileFieldDelegate, handler: AddonUserProfileFieldTextHandler) {
+ userProfileFieldDelegate.registerHandler(handler);
+ }
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/textarea/component/textarea.html b/src/addon/userprofilefield/textarea/component/textarea.html
new file mode 100644
index 000000000..003d70ef2
--- /dev/null
+++ b/src/addon/userprofilefield/textarea/component/textarea.html
@@ -0,0 +1,10 @@
+
+
+
{{ field.name }}
+
+
+
+
+ {{ field.name }}
+
+
diff --git a/src/addon/userprofilefield/textarea/component/textarea.scss b/src/addon/userprofilefield/textarea/component/textarea.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/addon/userprofilefield/textarea/component/textarea.ts b/src/addon/userprofilefield/textarea/component/textarea.ts
new file mode 100644
index 000000000..967c4081c
--- /dev/null
+++ b/src/addon/userprofilefield/textarea/component/textarea.ts
@@ -0,0 +1,50 @@
+// (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, Input, OnInit } from '@angular/core';
+
+/**
+ * Directive to render a textarea user profile field.
+ */
+@Component({
+ selector: 'core-user-profile-field-textarea',
+ templateUrl: 'textarea.html'
+})
+export class AddonUserProfileFieldTextareaComponent implements OnInit {
+ @Input() field: any; // The profile field to be rendered.
+ @Input() edit?: boolean = false; // True if editing the field. Defaults to false.
+ @Input() model?: any; // Model where to store the data. Required if edit=true or signup=true.
+
+ constructor() {}
+
+ /**
+ * Component being initialized.
+ */
+ ngOnInit() {
+ let field = this.field;
+
+ if (field && this.edit && this.model) {
+ field.modelName = 'profile_field_' + field.shortname;
+ this.model[field.modelName] = {
+ format: 1
+ };
+
+ // Initialize the value using default data.
+ if (typeof field.defaultdata != 'undefined' && typeof this.model[field.modelName].text == 'undefined') {
+ this.model[field.modelName].text = field.defaultdata;
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/textarea/providers/handler.ts b/src/addon/userprofilefield/textarea/providers/handler.ts
new file mode 100644
index 000000000..544c2ad3e
--- /dev/null
+++ b/src/addon/userprofilefield/textarea/providers/handler.ts
@@ -0,0 +1,83 @@
+
+// (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 { Injectable } from '@angular/core';
+import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '../../../../core/user/providers/user-profile-field-delegate';
+import { AddonUserProfileFieldTextareaComponent } from '../component/textarea';
+import { CoreTextUtilsProvider } from '../../../../providers/utils/text';
+import { CoreDomUtilsProvider } from '../../../../providers/utils/dom';
+
+/**
+ * Textarea user profile field handlers.
+ */
+@Injectable()
+export class AddonUserProfileFieldTextareaHandler implements CoreUserProfileFieldHandler {
+ name = 'textarea';
+
+ constructor(private textUtils: CoreTextUtilsProvider, private domUtils: CoreDomUtilsProvider) {}
+
+ /**
+ * Whether or not the handler is enabled on a site level.
+ *
+ * @return {boolean|Promise} True or promise resolved with true if enabled.
+ */
+ isEnabled() : boolean|Promise {
+ return true;
+ }
+
+ /**
+ * Get the data to send for the field based on the input data.
+ *
+ * @param {any} field User field to get the data for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @param {any} model Model with the input data.
+ * @return {Promise} Data to send for the field.
+ */
+ getData(field: any, signup: boolean, registerAuth: string, model: any): Promise {
+ let name = 'profile_field_' + field.shortname;
+
+ if (model[name]) {
+ return this.domUtils.isRichTextEditorEnabled().then((enabled) => {
+ let text = model[name].text || '';
+ if (!enabled) {
+ // Rich text editor not enabled, add some HTML to the message if needed.
+ text = this.textUtils.formatHtmlLines(text);
+ }
+
+ return {
+ type: 'textarea',
+ name: name,
+ value: JSON.stringify({
+ text: text,
+ format: model[name].format || 1
+ })
+ };
+ });
+ }
+ }
+
+ /**
+ * Return the Component to use to display the user profile field.
+ *
+ * @param {any} field User field to get the data for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @return {any} The component to use, undefined if not found.
+ */
+ getComponent(field: any, signup: boolean, registerAuth: string) {
+ return AddonUserProfileFieldTextareaComponent;
+ }
+
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/textarea/textarea.module.ts b/src/addon/userprofilefield/textarea/textarea.module.ts
new file mode 100644
index 000000000..b1c2212d3
--- /dev/null
+++ b/src/addon/userprofilefield/textarea/textarea.module.ts
@@ -0,0 +1,48 @@
+// (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 { IonicModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { AddonUserProfileFieldTextareaHandler } from './providers/handler';
+import { CoreUserProfileFieldDelegate } from '../../../core/user/providers/user-profile-field-delegate';
+import { AddonUserProfileFieldTextareaComponent } from './component/textarea';
+import { CoreComponentsModule } from '../../../components/components.module';
+import { CoreDirectivesModule } from '../../../directives/directives.module';
+
+@NgModule({
+ declarations: [
+ AddonUserProfileFieldTextareaComponent
+ ],
+ imports: [
+ IonicModule,
+ TranslateModule.forChild(),
+ CoreComponentsModule,
+ CoreDirectivesModule
+ ],
+ providers: [
+ AddonUserProfileFieldTextareaHandler
+ ],
+ exports: [
+ AddonUserProfileFieldTextareaComponent
+ ],
+ entryComponents: [
+ AddonUserProfileFieldTextareaComponent
+ ]
+})
+export class AddonUserProfileFieldTextareaModule {
+ constructor(userProfileFieldDelegate: CoreUserProfileFieldDelegate, handler: AddonUserProfileFieldTextareaHandler) {
+ userProfileFieldDelegate.registerHandler(handler);
+ }
+}
\ No newline at end of file
diff --git a/src/addon/userprofilefield/userprofilefield.module.ts b/src/addon/userprofilefield/userprofilefield.module.ts
new file mode 100644
index 000000000..a946dab74
--- /dev/null
+++ b/src/addon/userprofilefield/userprofilefield.module.ts
@@ -0,0 +1,35 @@
+// (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 { AddonUserProfileFieldCheckboxModule } from './checkbox/checkbox.module';
+import { AddonUserProfileFieldDatetimeModule } from './datetime/datetime.module';
+import { AddonUserProfileFieldMenuModule } from './menu/menu.module';
+import { AddonUserProfileFieldTextModule } from './text/text.module';
+import { AddonUserProfileFieldTextareaModule } from './textarea/textarea.module';
+
+
+@NgModule({
+ declarations: [],
+ imports: [
+ AddonUserProfileFieldCheckboxModule,
+ AddonUserProfileFieldDatetimeModule,
+ AddonUserProfileFieldMenuModule,
+ AddonUserProfileFieldTextModule,
+ AddonUserProfileFieldTextareaModule
+ ],
+ providers: [
+ ],
+ exports: []
+})
+export class AddonUserProfileFieldModule {}
\ No newline at end of file
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 2a824241a..c68d1071b 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -64,6 +64,8 @@ import { CoreUserModule } from '../core/user/user.module';
// Addon modules.
import { AddonCalendarModule } from '../addon/calendar/calendar.module';
+import { AddonUserProfileFieldModule } from '../addon/userprofilefield/userprofilefield.module';
+
// For translate loader. AoT requires an exported function for factories.
export function createTranslateLoader(http: HttpClient) {
@@ -99,7 +101,8 @@ export function createTranslateLoader(http: HttpClient) {
CoreSiteHomeModule,
CoreContentLinksModule,
CoreUserModule,
- AddonCalendarModule
+ AddonCalendarModule,
+ AddonUserProfileFieldModule
],
bootstrap: [IonicApp],
entryComponents: [
diff --git a/src/core/user/components/components.module.ts b/src/core/user/components/components.module.ts
new file mode 100644
index 000000000..13682bbe7
--- /dev/null
+++ b/src/core/user/components/components.module.ts
@@ -0,0 +1,36 @@
+// (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 { CoreUserProfileFieldComponent } from './user-profile-field/user-profile-field';
+
+@NgModule({
+ declarations: [
+ CoreUserProfileFieldComponent
+ ],
+ imports: [
+ CommonModule,
+ IonicModule,
+ TranslateModule.forChild(),
+ ],
+ providers: [
+ ],
+ exports: [
+ CoreUserProfileFieldComponent
+ ]
+})
+export class CoreUserComponentsModule {}
diff --git a/src/core/user/components/user-profile-field/user-profile-field.html b/src/core/user/components/user-profile-field/user-profile-field.html
new file mode 100644
index 000000000..825590342
--- /dev/null
+++ b/src/core/user/components/user-profile-field/user-profile-field.html
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/src/core/user/components/user-profile-field/user-profile-field.scss b/src/core/user/components/user-profile-field/user-profile-field.scss
new file mode 100644
index 000000000..a5595aa37
--- /dev/null
+++ b/src/core/user/components/user-profile-field/user-profile-field.scss
@@ -0,0 +1,5 @@
+core-user-profile-field {
+
+}
+
+
diff --git a/src/core/user/components/user-profile-field/user-profile-field.ts b/src/core/user/components/user-profile-field/user-profile-field.ts
new file mode 100644
index 000000000..1b3dcfee0
--- /dev/null
+++ b/src/core/user/components/user-profile-field/user-profile-field.ts
@@ -0,0 +1,98 @@
+// (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, Input, ViewChild, ViewContainerRef, ComponentFactoryResolver, ComponentRef, OnInit } from '@angular/core';
+import { CoreLoggerProvider } from '../../../../providers/logger';
+import { CoreUserProfileFieldDelegate } from '../../providers/user-profile-field-delegate';
+
+/**
+ * Directive to render user profile field.
+ */
+@Component({
+ selector: 'core-user-profile-field',
+ templateUrl: 'user-profile-field.html'
+})
+export class CoreUserProfileFieldComponent implements OnInit {
+ @Input() field: any; // The profile field to be rendered.
+ @Input() signup?: boolean = false; // True if editing the field in signup. Defaults to false.
+ @Input() edit?: boolean = false; // True if editing the field. Defaults to false.
+ @Input() model?: any; // Model where to store the data. Required if edit=true or signup=true.
+ @Input() registerAuth?: string; // Register auth method. E.g. 'email'.
+
+ // Get the containers where to inject dynamic components. We use a setter because they might be inside a *ngIf.
+ @ViewChild('userProfileField', { read: ViewContainerRef }) set userProfileField (el: ViewContainerRef) {
+ if (this.field) {
+ this.createComponent(this.ufDelegate.getComponent(this.field, this.signup, this.registerAuth), el);
+ } else {
+ // The component hasn't been initialized yet. Store the container.
+ this.fieldContainer = el;
+ }
+ };
+
+ protected logger;
+
+ // Instances and containers of all the components that the handler could define.
+ protected fieldContainer: ViewContainerRef;
+ protected fieldInstance: any;
+
+ constructor(logger: CoreLoggerProvider, private factoryResolver: ComponentFactoryResolver,
+ private ufDelegate: CoreUserProfileFieldDelegate) {
+ this.logger = logger.getInstance('CoreUserProfileFieldComponent');
+ }
+
+ /**
+ * Component being initialized.
+ */
+ ngOnInit() {
+ this.createComponent(this.ufDelegate.getComponent(this.field, this.signup, this.registerAuth), this.fieldContainer);
+ }
+
+ /**
+ * Create a component, add it to a container and set the input data.
+ *
+ * @param {any} componentClass The class of the component to create.
+ * @param {ViewContainerRef} container The container to add the component to.
+ * @return {boolean} Whether the component was successfully created.
+ */
+ protected createComponent(componentClass: any, container: ViewContainerRef) : boolean {
+ if (!componentClass || !container) {
+ // No component to instantiate or container doesn't exist right now.
+ return false;
+ }
+
+ if (this.fieldInstance && container === this.fieldContainer) {
+ // Component already instantiated and the component hasn't been destroyed, nothing to do.
+ return true;
+ }
+
+ try {
+ // Create the component and add it to the container.
+ const factory = this.factoryResolver.resolveComponentFactory(componentClass),
+ componentRef = container.createComponent(factory);
+
+ this.fieldContainer = container;
+ this.fieldInstance = componentRef.instance;
+
+ // Set the Input data.
+ this.fieldInstance.field = this.field;
+ this.fieldInstance.edit = this.edit;
+ this.fieldInstance.model = this.model;
+
+ return true;
+ } catch(ex) {
+ this.logger.error('Error creating user field component', ex, componentClass);
+ return false;
+ }
+ }
+}
diff --git a/src/core/user/pages/about/about.html b/src/core/user/pages/about/about.html
index 6556144a4..f95e6f7c3 100644
--- a/src/core/user/pages/about/about.html
+++ b/src/core/user/pages/about/about.html
@@ -59,6 +59,7 @@
{{ 'core.user.interests' | translate}}
+ {{ 'core.user.description' | translate}}
diff --git a/src/core/user/pages/about/about.module.ts b/src/core/user/pages/about/about.module.ts
index 07f43dbba..22ea2afdd 100644
--- a/src/core/user/pages/about/about.module.ts
+++ b/src/core/user/pages/about/about.module.ts
@@ -18,6 +18,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { CoreUserAboutPage } from './about';
import { CoreDirectivesModule } from '../../../../directives/directives.module';
import { CoreComponentsModule } from '../../../../components/components.module';
+import { CoreUserComponentsModule } from '../../components/components.module';
@NgModule({
declarations: [
@@ -26,6 +27,7 @@ import { CoreComponentsModule } from '../../../../components/components.module';
imports: [
CoreComponentsModule,
CoreDirectivesModule,
+ CoreUserComponentsModule,
IonicPageModule.forChild(CoreUserAboutPage),
TranslateModule.forChild()
],
diff --git a/src/core/user/pages/profile/profile.ts b/src/core/user/pages/profile/profile.ts
index 143c5d850..75f9456a1 100644
--- a/src/core/user/pages/profile/profile.ts
+++ b/src/core/user/pages/profile/profile.ts
@@ -23,7 +23,7 @@ import { CoreEventsProvider } from '../../../../providers/events';
import { CoreSitesProvider } from '../../../../providers/sites';
import { CoreMimetypeUtilsProvider } from '../../../../providers/utils/mimetype';
import { CoreFileUploaderHelperProvider } from '../../../fileuploader/providers/helper';
-import { CoreUserDelegate } from '../../providers/delegate';
+import { CoreUserDelegate } from '../../providers/user-delegate';
/**
* Page that displays an user profile page.
@@ -103,7 +103,6 @@ export class CoreUserProfilePage {
this.isLoadingHandlers = true;
this.userDelegate.getProfileHandlersFor(user, this.courseId).then((handlers) => {
- console.error(handlers);
this.actionHandlers = [];
this.newPageHandlers = [];
this.communicationHandlers = [];
diff --git a/src/core/user/providers/delegate.ts b/src/core/user/providers/user-delegate.ts
similarity index 98%
rename from src/core/user/providers/delegate.ts
rename to src/core/user/providers/user-delegate.ts
index 7bb2f7638..659d09ba8 100644
--- a/src/core/user/providers/delegate.ts
+++ b/src/core/user/providers/user-delegate.ts
@@ -124,7 +124,7 @@ export class CoreUserDelegate extends CoreDelegate {
protected featurePrefix = '$mmUserDelegate_';
constructor(protected loggerProvider: CoreLoggerProvider, protected sitesProvider: CoreSitesProvider,
- private coursesProvider: CoreCoursesProvider, protected eventsProvider: CoreEventsProvider) {
+ private coursesProvider: CoreCoursesProvider, protected eventsProvider: CoreEventsProvider) {
super('CoreUserDelegate', loggerProvider, sitesProvider, eventsProvider);
}
diff --git a/src/core/user/providers/user-handler.ts b/src/core/user/providers/user-handler.ts
index 3a37255e1..48f439250 100644
--- a/src/core/user/providers/user-handler.ts
+++ b/src/core/user/providers/user-handler.ts
@@ -13,7 +13,7 @@
// limitations under the License.
import { Injectable } from '@angular/core';
-import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from './delegate';
+import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from './user-delegate';
import { CoreSitesProvider } from '../../../providers/sites';
/**
diff --git a/src/core/user/providers/user-profile-field-delegate.ts b/src/core/user/providers/user-profile-field-delegate.ts
new file mode 100644
index 000000000..b3b8784dd
--- /dev/null
+++ b/src/core/user/providers/user-profile-field-delegate.ts
@@ -0,0 +1,164 @@
+// (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 { Injectable } from '@angular/core';
+import { CoreDelegate, CoreDelegateHandler } from '../../../classes/delegate';
+import { CoreLoggerProvider } from '../../../providers/logger';
+import { CoreSitesProvider } from '../../../providers/sites';
+import { CoreEventsProvider } from '../../../providers/events';
+
+export interface CoreUserProfileFieldHandler extends CoreDelegateHandler {
+
+ /**
+ * Return the Component to use to display the user profile field.
+ *
+ * @param {any} field User field to get the data for.
+ * @param {boolean} [signup] True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @return {any} The component to use, undefined if not found.
+ */
+ getComponent(field: any, signup: boolean, registerAuth: string): any;
+
+ /**
+ * Get the data to send for the field based on the input data.
+ * @param {any} field User field to get the data for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @param {any} model Model with the input data.
+ * @return {Promise|CoreUserProfileFieldHandlerData} Data to send for the field.
+ */
+ getData?(field: any, signup: boolean, registerAuth: string, model: any):
+ Promise | CoreUserProfileFieldHandlerData;
+};
+
+export interface CoreUserProfileFieldHandlerData {
+ /**
+ * Name to display.
+ * @type {string}
+ */
+ name: string;
+
+ /**
+ * Field type.
+ * @type {string}
+ */
+ type?: string;
+
+ /**
+ * Value of the field.
+ * @type {any}
+ */
+ value: any;
+};
+
+/**
+ * Service to interact with user profile fields. Provides functions to register a plugin.
+ */
+@Injectable()
+export class CoreUserProfileFieldDelegate extends CoreDelegate {
+ protected handlers: {[s: string]: CoreUserProfileFieldHandler} = {};
+ protected enabledHandlers: {[s: string]: CoreUserProfileFieldHandler} = {};
+
+ constructor(protected loggerProvider: CoreLoggerProvider, protected sitesProvider: CoreSitesProvider,
+ protected eventsProvider: CoreEventsProvider) {
+ super('CoreUserProfileFieldDelegate', loggerProvider, sitesProvider, eventsProvider);
+ }
+
+ /**
+ * Get the component to use to display an user field.
+ *
+ * @param {any} field User field to get the directive for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} registerAuth Register auth method. E.g. 'email'
+ * @return {any} The component to use, undefined if not found.
+ */
+ getComponent(field: any, signup: boolean, registerAuth: string) : any {
+ let type = field.type || field.datatype;
+ return this.executeFunction(type, 'getComponent', [field, signup, registerAuth]);
+ }
+
+ /**
+ * Get the data to send for a certain field based on the input data.
+ *
+ * @param {any} field User field to get the data for.
+ * @param {boolean} signup True if user is in signup page.
+ * @param {string} registerAuth Register auth method. E.g. 'email'.
+ * @param {any} model Model with the input data.
+ * @return {Promise} Data to send for the field.
+ */
+ getDataForField(field: any, signup: boolean, registerAuth: string, model: any): Promise {
+ let handler = this.getHandler(field, signup);
+
+ if (handler) {
+ let name = 'profile_field_' + field.shortname;
+ if (handler.getData) {
+ return Promise.resolve(handler.getData(field, signup, registerAuth, model));
+ } else if (field.shortname && typeof model[name] != 'undefined') {
+ // Handler doesn't implement the function, but the model has data for the field.
+ return Promise.resolve({
+ type: field.type || field.datatype,
+ name: name,
+ value: model[name]
+ });
+ }
+ }
+ return Promise.reject(null);
+ }
+
+ /**
+ * Get the data to send for a list of fields based on the input data.
+ *
+ * @param {any[]} fields User fields to get the data for.
+ * @param {boolean} [signup] True if user is in signup page.
+ * @param {string} [registerAuth] Register auth method. E.g. 'email'.
+ * @param {any} model Model with the input data.
+ * @return {Promise} Data to send.
+ */
+ getDataForFields(fields: any[], signup = false, registerAuth = "", model: any): Promise {
+ let result = [],
+ promises = [];
+
+ fields.forEach((field) => {
+ this.getDataForField(field, signup, registerAuth, model).then((data) => {
+ result.push(data);
+ }).catch(() => {
+ // Ignore errors.
+ });
+ });
+
+ return Promise.all(promises).then(() => {
+ return result;
+ });
+ }
+
+ /**
+ * Get a handler.
+ *
+ * @param {any} field User field to get the directive for.
+ * @param {boolean} signup True if user is in signup page.
+ * @return {any} Handler.
+ */
+ protected getHandler(field: any, signup: boolean): any {
+ let type = field.type || field.datatype;
+
+ if (signup) {
+ if (this.handlers[type]) {
+ return this.handlers[type];
+ }
+ return false;
+ }
+
+ return this.enabledHandlers[type];
+ }
+}
diff --git a/src/core/user/user.module.ts b/src/core/user/user.module.ts
index 3f052aa1d..474d9171a 100644
--- a/src/core/user/user.module.ts
+++ b/src/core/user/user.module.ts
@@ -13,7 +13,8 @@
// limitations under the License.
import { NgModule } from '@angular/core';
-import { CoreUserDelegate } from './providers/delegate';
+import { CoreUserDelegate } from './providers/user-delegate';
+import { CoreUserProfileFieldDelegate } from './providers/user-profile-field-delegate';
import { CoreUserProvider } from './providers/user';
import { CoreUserHelperProvider } from './providers/helper';
import { CoreUserProfileMailHandler } from './providers/user-handler';
@@ -25,6 +26,7 @@ import { CoreUserProfileMailHandler } from './providers/user-handler';
],
providers: [
CoreUserDelegate,
+ CoreUserProfileFieldDelegate,
CoreUserProfileMailHandler,
CoreUserProvider,
CoreUserHelperProvider