MOBILE-2317 login: Add custom user profile field to sign-up

main
Pau Ferrer Ocaña 2018-01-18 16:38:41 +01:00
parent 61a477afd5
commit d7c6c25292
32 changed files with 253 additions and 213 deletions

View File

@ -9,8 +9,9 @@
</p> </p>
</ion-item> </ion-item>
<!-- Edit. --> <!-- Edit. -->
<ion-item *ngIf="edit && field && field.shortname"> <ion-item *ngIf="edit && field && field.shortname" [formGroup]="form">
<ion-label [core-mark-required]="field.required">{{ field.name }}</ion-label> <ion-label [core-mark-required]="field.required">{{ field.name }}</ion-label>
<ion-checkbox text-wrap [name]="field.modelName" [(ngModel)]="model[field.modelName]" [disabled]="!signup && field.locked" [required]="field.required" core-input-errors> <ion-checkbox item-end [formControlName]="field.modelName">
</ion-checkbox> </ion-checkbox>
<core-input-errors [control]="form.controls[field.modelName]" [errorMessages]="errors"></core-input-errors>
</ion-item> </ion-item>

View File

@ -13,20 +13,22 @@
// limitations under the License. // limitations under the License.
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
/** /**
* Directive to render a checkbox user profile field. * Directive to render a checkbox user profile field.
*/ */
@Component({ @Component({
selector: 'core-user-profile-field-checkbox', selector: 'addon-user-profile-field-checkbox',
templateUrl: 'checkbox.html' templateUrl: 'checkbox.html'
}) })
export class AddonUserProfileFieldCheckboxComponent implements OnInit { export class AddonUserProfileFieldCheckboxComponent implements OnInit {
@Input() field: any; // The profile field to be rendered. @Input() field: any; // The profile field to be rendered.
@Input() edit?: boolean = false; // True if editing the field. 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() disabled?: boolean = false; // True if disabled. Defaults to false.
@Input() form?: FormGroup; // Form where to add the form control.
constructor() {} constructor(private fb: FormBuilder) {}
/** /**
* Component being initialized. * Component being initialized.
@ -34,13 +36,15 @@ export class AddonUserProfileFieldCheckboxComponent implements OnInit {
ngOnInit() { ngOnInit() {
let field = this.field; let field = this.field;
if (field && this.edit && this.model) { if (field && this.edit && this.form) {
field.modelName = 'profile_field_' + field.shortname; field.modelName = 'profile_field_' + field.shortname;
// Initialize the value. // Initialize the value.
if (typeof field.defaultdata != 'undefined' && typeof this.model[field.modelName] == 'undefined') { let formData = {
this.model[field.modelName] = field.defaultdata && field.defaultdata !== '0' && field.defaultdata !== 'false'; value: field.defaultdata && field.defaultdata !== '0' && field.defaultdata !== 'false',
} disabled: this.disabled
};
this.form.addControl(field.modelName, this.fb.control(formData, field.required && !field.locked ? Validators.requiredTrue : null));
} }
} }

View File

@ -40,17 +40,17 @@ export class AddonUserProfileFieldCheckboxHandler implements CoreUserProfileFiel
* @param {any} field User field to get the data for. * @param {any} field User field to get the data for.
* @param {boolean} signup True if user is in signup page. * @param {boolean} signup True if user is in signup page.
* @param {string} [registerAuth] Register auth method. E.g. 'email'. * @param {string} [registerAuth] Register auth method. E.g. 'email'.
* @param {any} model Model with the input data. * @param {any} formValues Form Values.
* @return {CoreUserProfileFieldHandlerData} Data to send for the field. * @return {CoreUserProfileFieldHandlerData} Data to send for the field.
*/ */
getData(field: any, signup: boolean, registerAuth: string, model: any): CoreUserProfileFieldHandlerData { getData(field: any, signup: boolean, registerAuth: string, formValues: any): CoreUserProfileFieldHandlerData {
let name = 'profile_field_' + field.shortname; let name = 'profile_field_' + field.shortname;
if (typeof model[name] != 'undefined') { if (typeof formValues[name] != 'undefined') {
return { return {
type: 'checkbox', type: 'checkbox',
name: name, name: name,
value: model[name] ? 1 : 0 value: formValues[name] ? 1 : 0
}; };
} }
} }
@ -58,12 +58,9 @@ export class AddonUserProfileFieldCheckboxHandler implements CoreUserProfileFiel
/** /**
* Return the Component to use to display the user profile field. * 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. * @return {any} The component to use, undefined if not found.
*/ */
getComponent(field: any, signup: boolean, registerAuth: string) { getComponent() {
return AddonUserProfileFieldCheckboxComponent; return AddonUserProfileFieldCheckboxComponent;
} }

View File

@ -4,7 +4,7 @@
<p>{{ field.value * 1000 | coreFormatDate:"dfmediumdate"}}</p> <p>{{ field.value * 1000 | coreFormatDate:"dfmediumdate"}}</p>
</ion-item> </ion-item>
<!-- Edit. --> <!-- Edit. -->
<ion-item *ngIf="edit && field && field.shortname" text-wrap> <ion-item *ngIf="edit && field && field.shortname" text-wrap [formGroup]="form">
<ion-label [core-mark-required]="field.required">{{ field.name }}</ion-label> <ion-label stacked [core-mark-required]="field.required">{{ field.name }}</ion-label>
<ion-datetime [name]="field.modelName" [displayFormat]="field.format | translate" [disabled]="!signup && field.locked" [(ngModel)]="model[field.modelName]" [required]="field.required" core-input-errors [max]="field.max" [min]="field.min"></ion-datetime> <ion-datetime [formControlName]="field.modelName" [placeholder]="'core.choosedots' | translate" [displayFormat]="field.format" core-input-errors [max]="field.max" [min]="field.min"></ion-datetime>
</ion-item> </ion-item>

View File

@ -13,21 +13,23 @@
// limitations under the License. // limitations under the License.
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { CoreTimeUtilsProvider } from '../../../../providers/utils/time';
/** /**
* Directive to render a datetime user profile field. * Directive to render a datetime user profile field.
*/ */
@Component({ @Component({
selector: 'core-user-profile-field-datetime', selector: 'addon-user-profile-field-datetime',
templateUrl: 'datetime.html' templateUrl: 'datetime.html'
}) })
export class AddonUserProfileFieldDatetimeComponent implements OnInit { export class AddonUserProfileFieldDatetimeComponent implements OnInit {
@Input() field: any; // The profile field to be rendered. @Input() field: any; // The profile field to be rendered.
@Input() edit?: boolean = false; // True if editing the field. 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() disabled?: boolean = false; // True if disabled. Defaults to false.
@Input() form?: FormGroup; // Form where to add the form control.
constructor(private fb: FormBuilder, private timeUtils: CoreTimeUtilsProvider) {}
constructor() {}
/** /**
* Component being initialized. * Component being initialized.
@ -35,12 +37,12 @@ export class AddonUserProfileFieldDatetimeComponent implements OnInit {
ngOnInit() { ngOnInit() {
let field = this.field, let field = this.field,
year; year;
if (field && this.edit && this.model) { if (field && this.edit && this.form) {
field.modelName = 'profile_field_' + field.shortname; field.modelName = 'profile_field_' + field.shortname;
// Check if it's only date or it has time too. // Check if it's only date or it has time too.
field.hasTime = field.param3 && field.param3 !== '0' && field.param3 !== 'false'; let hasTime = field.param3 && field.param3 !== '0' && field.param3 !== 'false';
field.format = field.hasTime ? 'core.dffulldate' : 'core.dfdaymonthyear'; field.format = hasTime ? this.timeUtils.getLocalizedDateFormat('LLL') : this.timeUtils.getLocalizedDateFormat('LL');
// Check min value. // Check min value.
if (field.param1) { if (field.param1) {
@ -57,6 +59,12 @@ export class AddonUserProfileFieldDatetimeComponent implements OnInit {
field.max = year; field.max = year;
} }
} }
let formData = {
value: field.defaultdata,
disabled: this.disabled
};
this.form.addControl(field.modelName, this.fb.control(formData, field.required && !field.locked ? Validators.required : null));
} }
} }

View File

@ -41,31 +41,18 @@ export class AddonUserProfileFieldDatetimeHandler implements CoreUserProfileFiel
* @param {any} field User field to get the data for. * @param {any} field User field to get the data for.
* @param {boolean} signup True if user is in signup page. * @param {boolean} signup True if user is in signup page.
* @param {string} [registerAuth] Register auth method. E.g. 'email'. * @param {string} [registerAuth] Register auth method. E.g. 'email'.
* @param {any} model Model with the input data. * @param {any} formValues Form Values.
* @return {CoreUserProfileFieldHandlerData} Data to send for the field. * @return {CoreUserProfileFieldHandlerData} Data to send for the field.
*/ */
getData(field: any, signup: boolean, registerAuth: string, model: any): CoreUserProfileFieldHandlerData { getData(field: any, signup: boolean, registerAuth: string, formValues: any): CoreUserProfileFieldHandlerData {
let hasTime = field.param3 && field.param3 !== '0' && field.param3 !== 'false', let name = 'profile_field_' + field.shortname;
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());
}
if (formValues[name]) {
let milliseconds = new Date(formValues[name]).getTime();
return { return {
type: 'datetime', type: 'datetime',
name: 'profile_field_' + field.shortname, name: 'profile_field_' + field.shortname,
value: Math.round(date.getTime() / 1000) value: Math.round(milliseconds / 1000)
}; };
} }
} }
@ -73,12 +60,9 @@ export class AddonUserProfileFieldDatetimeHandler implements CoreUserProfileFiel
/** /**
* Return the Component to use to display the user profile field. * 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. * @return {any} The component to use, undefined if not found.
*/ */
getComponent(field: any, signup: boolean, registerAuth: string) { getComponent() {
return AddonUserProfileFieldDatetimeComponent; return AddonUserProfileFieldDatetimeComponent;
} }

View File

@ -4,9 +4,9 @@
<p><core-format-text [text]="field.value"></core-format-text></p> <p><core-format-text [text]="field.value"></core-format-text></p>
</ion-item> </ion-item>
<!-- Edit. --> <!-- Edit. -->
<ion-item *ngIf="edit && field && field.shortname" text-wrap> <ion-item *ngIf="edit && field && field.shortname" text-wrap [formGroup]="form">
<ion-label [core-mark-required]="field.required">{{ field.name }}</ion-label> <ion-label stacked [core-mark-required]="field.required">{{ field.name }}</ion-label>
<ion-select [name]="field.modelName" [(ngModel)]="model[field.modelName]" [disabled]="!signup && field.locked" [required]="field.required" core-input-errors> <ion-select [formControlName]="field.modelName" [placeholder]="'core.choosedots' | translate" core-input-errors>
<ion-option value="">{{ 'core.choosedots' | translate }}</ion-option> <ion-option value="">{{ 'core.choosedots' | translate }}</ion-option>
<ion-option *ngFor="let option of field.options" [value]="option">{{option}}</ion-option> <ion-option *ngFor="let option of field.options" [value]="option">{{option}}</ion-option>
</ion-select> </ion-select>

View File

@ -13,20 +13,22 @@
// limitations under the License. // limitations under the License.
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
/** /**
* Directive to render a menu user profile field. * Directive to render a menu user profile field.
*/ */
@Component({ @Component({
selector: 'core-user-profile-field-menu', selector: 'addon-user-profile-field-menu',
templateUrl: 'menu.html' templateUrl: 'menu.html'
}) })
export class AddonUserProfileFieldMenuComponent implements OnInit { export class AddonUserProfileFieldMenuComponent implements OnInit {
@Input() field: any; // The profile field to be rendered. @Input() field: any; // The profile field to be rendered.
@Input() edit?: boolean = false; // True if editing the field. 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() disabled?: boolean = false; // True if disabled. Defaults to false.
@Input() form?: FormGroup; // Form where to add the form control.
constructor() {} constructor(private fb: FormBuilder) {}
/** /**
* Component being initialized. * Component being initialized.
@ -34,7 +36,7 @@ export class AddonUserProfileFieldMenuComponent implements OnInit {
ngOnInit() { ngOnInit() {
let field = this.field; let field = this.field;
if (field && this.edit && this.model) { if (field && this.edit && this.form) {
field.modelName = 'profile_field_' + field.shortname; field.modelName = 'profile_field_' + field.shortname;
// Parse options. // Parse options.
@ -44,10 +46,12 @@ export class AddonUserProfileFieldMenuComponent implements OnInit {
field.options = []; field.options = [];
} }
let formData = {
value: field.defaultdata,
disabled: this.disabled
};
// Initialize the value using default data. // Initialize the value using default data.
if (typeof field.defaultdata != 'undefined' && typeof this.model[field.modelName] == 'undefined') { this.form.addControl(field.modelName, this.fb.control(formData, field.required && !field.locked ? Validators.required : null));
this.model[field.modelName] = field.defaultdata;
}
} }
} }

View File

@ -40,17 +40,17 @@ export class AddonUserProfileFieldMenuHandler implements CoreUserProfileFieldHan
* @param {any} field User field to get the data for. * @param {any} field User field to get the data for.
* @param {boolean} signup True if user is in signup page. * @param {boolean} signup True if user is in signup page.
* @param {string} [registerAuth] Register auth method. E.g. 'email'. * @param {string} [registerAuth] Register auth method. E.g. 'email'.
* @param {any} model Model with the input data. * @param {any} formValues Form Values.
* @return {CoreUserProfileFieldHandlerData} Data to send for the field. * @return {CoreUserProfileFieldHandlerData} Data to send for the field.
*/ */
getData(field: any, signup: boolean, registerAuth: string, model: any): CoreUserProfileFieldHandlerData { getData(field: any, signup: boolean, registerAuth: string, formValues: any): CoreUserProfileFieldHandlerData {
let name = 'profile_field_' + field.shortname; let name = 'profile_field_' + field.shortname;
if (model[name]) { if (formValues[name]) {
return { return {
type: 'menu', type: 'menu',
name: name, name: name,
value: model[name] value: formValues[name]
}; };
} }
} }
@ -58,12 +58,9 @@ export class AddonUserProfileFieldMenuHandler implements CoreUserProfileFieldHan
/** /**
* Return the Component to use to display the user profile field. * 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. * @return {any} The component to use, undefined if not found.
*/ */
getComponent(field: any, signup: boolean, registerAuth: string) { getComponent() {
return AddonUserProfileFieldMenuComponent; return AddonUserProfileFieldMenuComponent;
} }

View File

@ -4,7 +4,7 @@
<p><core-format-text [text]="field.value"></core-format-text></p> <p><core-format-text [text]="field.value"></core-format-text></p>
</ion-item> </ion-item>
<!-- Edit. --> <!-- Edit. -->
<ion-item *ngIf="edit && field && field.shortname" text-wrap> <ion-item *ngIf="edit && field && field.shortname" text-wrap [formGroup]="form">
<ion-label [core-mark-required]="field.required">{{ field.name }}</ion-label> <ion-label stacked [core-mark-required]="field.required">{{ field.name }}</ion-label>
<ion-input [type]="field.inputType" [name]="field.modelName" [placeholder]="field.name" [(ngModel)]="model[field.modelName]" [disabled]="!signup && field.locked" maxlength="{{field.maxlength}}" [required]="field.required" core-input-errors></ion-input> <ion-input [type]="field.inputType" [formControlName]="field.modelName" [placeholder]="field.name" maxlength="{{field.maxlength}}" core-input-errors></ion-input>
</ion-item> </ion-item>

View File

@ -13,20 +13,22 @@
// limitations under the License. // limitations under the License.
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
/** /**
* Directive to render a text user profile field. * Directive to render a text user profile field.
*/ */
@Component({ @Component({
selector: 'core-user-profile-field-text', selector: 'addon-user-profile-field-text',
templateUrl: 'text.html' templateUrl: 'text.html'
}) })
export class AddonUserProfileFieldTextComponent implements OnInit { export class AddonUserProfileFieldTextComponent implements OnInit {
@Input() field: any; // The profile field to be rendered. @Input() field: any; // The profile field to be rendered.
@Input() edit?: boolean = false; // True if editing the field. 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() disabled?: boolean = false; // True if disabled. Defaults to false.
@Input() form?: FormGroup; // Form where to add the form control.
constructor() {} constructor(private fb: FormBuilder) {}
/** /**
* Component being initialized. * Component being initialized.
@ -34,7 +36,7 @@ export class AddonUserProfileFieldTextComponent implements OnInit {
ngOnInit() { ngOnInit() {
let field = this.field; let field = this.field;
if (field && this.edit && this.model) { if (field && this.edit && this.form) {
field.modelName = 'profile_field_' + field.shortname; field.modelName = 'profile_field_' + field.shortname;
// Check max length. // Check max length.
@ -45,10 +47,12 @@ export class AddonUserProfileFieldTextComponent implements OnInit {
// Check if it's a password or text. // Check if it's a password or text.
field.inputType = field.param3 && field.param3 !== '0' && field.param3 !== 'false' ? 'password' : 'text'; field.inputType = field.param3 && field.param3 !== '0' && field.param3 !== 'false' ? 'password' : 'text';
let formData = {
value: field.defaultdata,
disabled: this.disabled
};
// Initialize the value using default data. // Initialize the value using default data.
if (typeof field.defaultdata != 'undefined' && typeof this.model[field.modelName] == 'undefined') { this.form.addControl(field.modelName, this.fb.control(formData, field.required && !field.locked ? Validators.required : null));
this.model[field.modelName] = field.defaultdata;
}
} }
} }

View File

@ -41,28 +41,25 @@ export class AddonUserProfileFieldTextHandler implements CoreUserProfileFieldHan
* @param {any} field User field to get the data for. * @param {any} field User field to get the data for.
* @param {boolean} signup True if user is in signup page. * @param {boolean} signup True if user is in signup page.
* @param {string} [registerAuth] Register auth method. E.g. 'email'. * @param {string} [registerAuth] Register auth method. E.g. 'email'.
* @param {any} model Model with the input data. * @param {any} formValues Form Values.
* @return {CoreUserProfileFieldHandlerData} Data to send for the field. * @return {CoreUserProfileFieldHandlerData} Data to send for the field.
*/ */
getData(field: any, signup: boolean, registerAuth: string, model: any): CoreUserProfileFieldHandlerData { getData(field: any, signup: boolean, registerAuth: string, formValues: any): CoreUserProfileFieldHandlerData {
let name = 'profile_field_' + field.shortname; let name = 'profile_field_' + field.shortname;
return { return {
type: 'text', type: 'text',
name: name, name: name,
value: this.textUtils.cleanTags(model[name]) value: this.textUtils.cleanTags(formValues[name])
}; };
} }
/** /**
* Return the Component to use to display the user profile field. * 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. * @return {any} The component to use, undefined if not found.
*/ */
getComponent(field: any, signup: boolean, registerAuth: string) { getComponent() {
return AddonUserProfileFieldTextComponent; return AddonUserProfileFieldTextComponent;
} }

View File

@ -4,7 +4,7 @@
<p><core-format-text [text]="field.value"></core-format-text></p> <p><core-format-text [text]="field.value"></core-format-text></p>
</ion-item> </ion-item>
<!-- Edit. --> <!-- Edit. -->
<ion-item *ngIf="edit && field && field.shortname" text-wrap> <ion-item *ngIf="edit && field && field.shortname" text-wrap [formGroup]="form">
<ion-label [core-mark-required]="field.required">{{ field.name }}</ion-label> <ion-label stacked [core-mark-required]="field.required">{{ field.name }}</ion-label>
<ion-textarea [name]="field.modelName" [(ngModel)]="model[field.modelName]" [placeholder]="field.name" [disabled]="!signup && field.locked" [required]="field.required"></ion-textarea> <core-rich-text-editor item-content [control]="control" [placeholder]="field.name"></core-rich-text-editor>
</ion-item> </ion-item>

View File

@ -13,18 +13,22 @@
// limitations under the License. // limitations under the License.
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { FormGroup, Validators, FormControl} from '@angular/forms';
/** /**
* Directive to render a textarea user profile field. * Directive to render a textarea user profile field.
*/ */
@Component({ @Component({
selector: 'core-user-profile-field-textarea', selector: 'addon-user-profile-field-textarea',
templateUrl: 'textarea.html' templateUrl: 'textarea.html'
}) })
export class AddonUserProfileFieldTextareaComponent implements OnInit { export class AddonUserProfileFieldTextareaComponent implements OnInit {
@Input() field: any; // The profile field to be rendered. @Input() field: any; // The profile field to be rendered.
@Input() edit?: boolean = false; // True if editing the field. 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() disabled?: boolean = false; // True if disabled. Defaults to false.
@Input() form?: FormGroup; // Form where to add the form control.
control: FormControl
constructor() {} constructor() {}
@ -34,17 +38,17 @@ export class AddonUserProfileFieldTextareaComponent implements OnInit {
ngOnInit() { ngOnInit() {
let field = this.field; let field = this.field;
if (field && this.edit && this.model) { if (field && this.edit && this.form) {
field.modelName = 'profile_field_' + field.shortname; 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;
}
} }
let formData = {
value: field.defaultdata,
disabled: this.disabled
};
this.control = new FormControl(formData, field.required && !field.locked ? Validators.required : null);
this.form.addControl(field.modelName, this.control);
} }
} }

View File

@ -16,7 +16,6 @@ import { Injectable } from '@angular/core';
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '../../../../core/user/providers/user-profile-field-delegate'; import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '../../../../core/user/providers/user-profile-field-delegate';
import { AddonUserProfileFieldTextareaComponent } from '../component/textarea'; import { AddonUserProfileFieldTextareaComponent } from '../component/textarea';
import { CoreTextUtilsProvider } from '../../../../providers/utils/text'; import { CoreTextUtilsProvider } from '../../../../providers/utils/text';
import { CoreDomUtilsProvider } from '../../../../providers/utils/dom';
/** /**
* Textarea user profile field handlers. * Textarea user profile field handlers.
@ -25,7 +24,7 @@ import { CoreDomUtilsProvider } from '../../../../providers/utils/dom';
export class AddonUserProfileFieldTextareaHandler implements CoreUserProfileFieldHandler { export class AddonUserProfileFieldTextareaHandler implements CoreUserProfileFieldHandler {
name = 'textarea'; name = 'textarea';
constructor(private textUtils: CoreTextUtilsProvider, private domUtils: CoreDomUtilsProvider) {} constructor(private textUtils: CoreTextUtilsProvider) {}
/** /**
* Whether or not the handler is enabled on a site level. * Whether or not the handler is enabled on a site level.
@ -42,41 +41,34 @@ export class AddonUserProfileFieldTextareaHandler implements CoreUserProfileFiel
* @param {any} field User field to get the data for. * @param {any} field User field to get the data for.
* @param {boolean} signup True if user is in signup page. * @param {boolean} signup True if user is in signup page.
* @param {string} [registerAuth] Register auth method. E.g. 'email'. * @param {string} [registerAuth] Register auth method. E.g. 'email'.
* @param {any} model Model with the input data. * @param {any} formValues Form Values.
* @return {Promise<CoreUserProfileFieldHandlerData>} Data to send for the field. * @return {CoreUserProfileFieldHandlerData} Data to send for the field.
*/ */
getData(field: any, signup: boolean, registerAuth: string, model: any): Promise<CoreUserProfileFieldHandlerData> { getData(field: any, signup: boolean, registerAuth: string, formValues: any): CoreUserProfileFieldHandlerData {
let name = 'profile_field_' + field.shortname; let name = 'profile_field_' + field.shortname;
if (model[name]) { if (formValues[name]) {
return this.domUtils.isRichTextEditorEnabled().then((enabled) => { let text = formValues[name] || '';
let text = model[name].text || ''; // Add some HTML to the message in case the user edited with textarea.
if (!enabled) { text = this.textUtils.formatHtmlLines(text);
// Rich text editor not enabled, add some HTML to the message if needed.
text = this.textUtils.formatHtmlLines(text);
}
return { return {
type: 'textarea', type: 'textarea',
name: name, name: name,
value: JSON.stringify({ value: JSON.stringify({
text: text, text: text,
format: model[name].format || 1 format: 1 // Always send this format.
}) })
}; };
});
} }
} }
/** /**
* Return the Component to use to display the user profile field. * 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. * @return {any} The component to use, undefined if not found.
*/ */
getComponent(field: any, signup: boolean, registerAuth: string) { getComponent() {
return AddonUserProfileFieldTextareaComponent; return AddonUserProfileFieldTextareaComponent;
} }

View File

@ -92,6 +92,19 @@ export class CoreDelegate {
eventsProvider.on(CoreEventsProvider.REMOTE_ADDONS_LOADED, this.updateHandlers.bind(this)); eventsProvider.on(CoreEventsProvider.REMOTE_ADDONS_LOADED, this.updateHandlers.bind(this));
} }
/**
* Execute a certain function in a enabled handler.
* If the handler isn't found or function isn't defined, call the same function in the default handler.
*
* @param {string} handlerName The handler name.
* @param {string} fnName Name of the function to execute.
* @param {any[]} params Parameters to pass to the function.
* @return {any} Function returned value or default value.
*/
protected executeFunctionOnEnabled(handlerName: string, fnName: string, params?: any[]) : any {
return this.execute(this.enabledHandlers[handlerName], fnName, params);
}
/** /**
* Execute a certain function in a handler. * Execute a certain function in a handler.
* If the handler isn't found or function isn't defined, call the same function in the default handler. * If the handler isn't found or function isn't defined, call the same function in the default handler.
@ -102,7 +115,19 @@ export class CoreDelegate {
* @return {any} Function returned value or default value. * @return {any} Function returned value or default value.
*/ */
protected executeFunction(handlerName: string, fnName: string, params?: any[]) : any { protected executeFunction(handlerName: string, fnName: string, params?: any[]) : any {
let handler = this.enabledHandlers[handlerName]; return this.execute(this.handlers[handlerName], fnName, params);
}
/**
* Execute a certain function in a handler.
* If the handler isn't found or function isn't defined, call the same function in the default handler.
*
* @param {any} handler The handler.
* @param {string} fnName Name of the function to execute.
* @param {any[]} params Parameters to pass to the function.
* @return {any} Function returned value or default value.
*/
private execute(handler: any, fnName: string, params?: any[]) : any {
if (handler && handler[fnName]) { if (handler && handler[fnName]) {
return handler[fnName].apply(handler, params); return handler[fnName].apply(handler, params);
} else if (this.defaultHandler && this.defaultHandler[fnName]) { } else if (this.defaultHandler && this.defaultHandler[fnName]) {
@ -110,14 +135,26 @@ export class CoreDelegate {
} }
} }
/**
* Get a handler.
*
* @param {string} handlerName The handler name.
* @param {boolean} [enabled] Only enabled, or any.
* @return {any} Handler.
*/
protected getHandler(handlerName: string, enabled = false): any {
return enabled ? this.enabledHandlers[handlerName] : this.handlers[handlerName];
}
/** /**
* Check if a handler name has a registered handler (not necessarily enabled). * Check if a handler name has a registered handler (not necessarily enabled).
* *
* @param {string} name The name of the handler. * @param {string} name The handler name.
* @param {boolean} [enabled] Only enabled, or any.
* @return {boolean} If the controller is installed or not. * @return {boolean} If the controller is installed or not.
*/ */
hasHandler(name: string) : boolean { hasHandler(name: string, enabled = false) : boolean {
return typeof this.handlers[name] !== 'undefined'; return enabled ? typeof this.enabledHandlers[name] !== 'undefined' : typeof this.handlers[name] !== 'undefined';
} }
/** /**
@ -234,5 +271,4 @@ export class CoreDelegate {
updateData() { updateData() {
} }
} }

View File

@ -21,7 +21,7 @@ import { CoreLoginHelperProvider } from './providers/helper';
imports: [ imports: [
], ],
providers: [ providers: [
CoreLoginHelperProvider, CoreLoginHelperProvider
] ]
}) })
export class CoreLoginModule {} export class CoreLoginModule {}

View File

@ -75,14 +75,14 @@
</ion-select> </ion-select>
</ion-item> </ion-item>
<!-- Other categories. @todo: Implement once user profile fields are implemented. --> <!-- Other categories. -->
<!-- <div *ngFor="let category in categories"> <ng-container *ngFor="let category of categories">
<ion-item-divider text-wrap color="light">{{ category.name }}</div> <ion-item-divider text-wrap color="light">{{ category.name }}</ion-item-divider>
<core-user-profile-field *ngFor="let field in category.fields" field="field" edit="true" signup="true" register-auth="email" model="data" scroll-handle="mmLoginEmailSignupScroll"></core-user-profile-field> <core-user-profile-field *ngFor="let field of category.fields" [field]="field" edit="true" signup="true" registerAuth="email" [form]="signupForm"></core-user-profile-field>
</div> --> </ng-container>
<!-- ReCAPTCHA --> <!-- ReCAPTCHA -->
<div *ngIf="settings.recaptchachallengehash && settings.recaptchachallengeimage"> <ng-container *ngIf="settings.recaptchachallengehash && settings.recaptchachallengeimage">
<ion-item-divider text-wrap color="light">{{ 'core.login.security_question' | translate }}</ion-item-divider> <ion-item-divider text-wrap color="light">{{ 'core.login.security_question' | translate }}</ion-item-divider>
<ion-item> <ion-item>
<img [src]="settings.recaptchachallengeimage" alt="{{ 'core.login.recaptchachallengeimage' | translate }}"> <img [src]="settings.recaptchachallengeimage" alt="{{ 'core.login.recaptchachallengeimage' | translate }}">
@ -96,20 +96,20 @@
<!-- Use anchor instead of button to prevent marking form as submitted. --> <!-- Use anchor instead of button to prevent marking form as submitted. -->
<a ion-button block (click)="requestCaptcha()">{{ 'core.login.getanothercaptcha' | translate }}</a> <a ion-button block (click)="requestCaptcha()">{{ 'core.login.getanothercaptcha' | translate }}</a>
</ion-item> </ion-item>
</div> </ng-container>
<!-- Site policy (if any). --> <!-- Site policy (if any). -->
<div *ngIf="settings.sitepolicy"> <ng-container *ngIf="settings.sitepolicy">
<ion-item-divider text-wrap color="light">{{ 'core.login.policyagreement' | translate }}</ion-item-divider> <ion-item-divider text-wrap color="light">{{ 'core.login.policyagreement' | translate }}</ion-item-divider>
<ion-item text-wrap> <ion-item text-wrap>
<p><a [href]="settings.sitepolicy" core-link capture="false">{{ 'core.login.policyagreementclick' | translate }}</a></p> <p><a [href]="settings.sitepolicy" core-link capture="false">{{ 'core.login.policyagreementclick' | translate }}</a></p>
</ion-item> </ion-item>
<ion-item text-wrap> <ion-item text-wrap>
<ion-label core-mark-required="true">{{ 'core.login.policyaccept' | translate }}</ion-label> <ion-label core-mark-required="true">{{ 'core.login.policyaccept' | translate }}</ion-label>
<ion-checkbox item-right name="policyagreed" formControlName="policyagreed"></ion-checkbox> <ion-checkbox item-end name="policyagreed" formControlName="policyagreed"></ion-checkbox>
<core-input-errors [control]="signupForm.controls.policyagreed" [errorMessages]="policyErrors"></core-input-errors> <core-input-errors [control]="signupForm.controls.policyagreed" [errorMessages]="policyErrors"></core-input-errors>
</ion-item> </ion-item>
</div> </ng-container>
<!-- Submit button. --> <!-- Submit button. -->
<ion-item padding> <ion-item padding>

View File

@ -18,6 +18,7 @@ import { CoreLoginEmailSignupPage } from './email-signup';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { CoreComponentsModule } from '../../../../components/components.module'; import { CoreComponentsModule } from '../../../../components/components.module';
import { CoreDirectivesModule } from '../../../../directives/directives.module'; import { CoreDirectivesModule } from '../../../../directives/directives.module';
import { CoreUserComponentsModule } from '../../../user/components/components.module';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -26,6 +27,7 @@ import { CoreDirectivesModule } from '../../../../directives/directives.module';
imports: [ imports: [
CoreComponentsModule, CoreComponentsModule,
CoreDirectivesModule, CoreDirectivesModule,
CoreUserComponentsModule,
IonicPageModule.forChild(CoreLoginEmailSignupPage), IonicPageModule.forChild(CoreLoginEmailSignupPage),
TranslateModule.forChild() TranslateModule.forChild()
] ]

View File

@ -22,6 +22,7 @@ import { CoreUtilsProvider } from '../../../../providers/utils/utils';
import { CoreWSProvider } from '../../../../providers/ws'; import { CoreWSProvider } from '../../../../providers/ws';
import { CoreLoginHelperProvider } from '../../providers/helper'; import { CoreLoginHelperProvider } from '../../providers/helper';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { CoreUserProfileFieldDelegate } from '../../../user/providers/user-profile-field-delegate';
/** /**
* Page to signup using email. * Page to signup using email.
@ -55,7 +56,7 @@ export class CoreLoginEmailSignupPage {
constructor(private navCtrl: NavController, navParams: NavParams, private fb: FormBuilder, private wsProvider: CoreWSProvider, constructor(private navCtrl: NavController, navParams: NavParams, private fb: FormBuilder, private wsProvider: CoreWSProvider,
private sitesProvider: CoreSitesProvider, private loginHelper: CoreLoginHelperProvider, private sitesProvider: CoreSitesProvider, private loginHelper: CoreLoginHelperProvider,
private domUtils: CoreDomUtilsProvider, private translate: TranslateService, private utils: CoreUtilsProvider, private domUtils: CoreDomUtilsProvider, private translate: TranslateService, private utils: CoreUtilsProvider,
private textUtils: CoreTextUtilsProvider) { private textUtils: CoreTextUtilsProvider, private userProfileFieldDelegate :CoreUserProfileFieldDelegate) {
this.siteUrl = navParams.get('siteUrl'); this.siteUrl = navParams.get('siteUrl');
@ -228,26 +229,22 @@ export class CoreLoginEmailSignupPage {
} }
// Get the data for the custom profile fields. // Get the data for the custom profile fields.
// @todo: Implement it once profile fields are implemented. this.userProfileFieldDelegate.getDataForFields(this.settings.profilefields, true, 'email', this.signupForm.value).then((fieldsData) => {
// $mmUserProfileFieldsDelegate.getDataForFields(fields, true, 'email', $scope.data).then(function(fieldsData) { params.customprofilefields = fieldsData;
// params.customprofilefields = fieldsData;
this.wsProvider.callAjax('auth_email_signup_user', params, {siteUrl: this.siteUrl}).then((result) => { this.wsProvider.callAjax('auth_email_signup_user', params, {siteUrl: this.siteUrl}).then((result) => {
if (result.success) { if (result.success) {
// Show alert and ho back. // Show alert and ho back.
let message = this.translate.instant('core.login.emailconfirmsent', {$a: params.email}); let message = this.translate.instant('core.login.emailconfirmsent', {$a: params.email});
this.domUtils.showAlert(this.translate.instant('core.success'), message); this.domUtils.showAlert(this.translate.instant('core.success'), message);
this.navCtrl.pop(); this.navCtrl.pop();
} else {
if (result.warnings && result.warnings.length) {
this.domUtils.showErrorModal(result.warnings[0].message);
} else { } else {
this.domUtils.showErrorModal('core.login.usernotaddederror', true); this.domUtils.showErrorModalFirstWarning(result.warnings, 'core.login.usernotaddederror', true);
}
// Error sending, request another capctha since the current one is probably invalid now. // Error sending, request another capctha since the current one is probably invalid now.
this.requestCaptcha(true); this.requestCaptcha(true);
} }
});
}).catch((error) => { }).catch((error) => {
this.domUtils.showErrorModalDefault(error && error.error, 'core.login.usernotaddederror', true); this.domUtils.showErrorModalDefault(error && error.error, 'core.login.usernotaddederror', true);

View File

@ -244,12 +244,12 @@ export class CoreLoginHelperProvider {
* @return {any} Categories with the fields to show in each one. * @return {any} Categories with the fields to show in each one.
*/ */
formatProfileFieldsForSignup(profileFields: any[]) : any { formatProfileFieldsForSignup(profileFields: any[]) : any {
let categories = {};
if (!profileFields) { if (!profileFields) {
return categories; return [];
} }
let categories = {};
profileFields.forEach((field) => { profileFields.forEach((field) => {
if (!field.signup) { if (!field.signup) {
// Not a signup field, ignore it. // Not a signup field, ignore it.
@ -267,7 +267,9 @@ export class CoreLoginHelperProvider {
categories[field.categoryid].fields.push(field); categories[field.categoryid].fields.push(field);
}); });
return categories; return Object.keys(categories).map((index) => {
return categories[index];
});
} }
/** /**

View File

@ -15,6 +15,7 @@
import { Component, Input, ViewChild, ViewContainerRef, ComponentFactoryResolver, ComponentRef, OnInit } from '@angular/core'; import { Component, Input, ViewChild, ViewContainerRef, ComponentFactoryResolver, ComponentRef, OnInit } from '@angular/core';
import { CoreLoggerProvider } from '../../../../providers/logger'; import { CoreLoggerProvider } from '../../../../providers/logger';
import { CoreUserProfileFieldDelegate } from '../../providers/user-profile-field-delegate'; import { CoreUserProfileFieldDelegate } from '../../providers/user-profile-field-delegate';
import { CoreUtilsProvider } from '../../../../providers/utils/utils';
/** /**
* Directive to render user profile field. * Directive to render user profile field.
@ -27,13 +28,13 @@ export class CoreUserProfileFieldComponent implements OnInit {
@Input() field: any; // The profile field to be rendered. @Input() field: any; // The profile field to be rendered.
@Input() signup?: boolean = false; // True if editing the field in signup. Defaults to false. @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() 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() form?: any; // Form where to add the form control. Required if edit=true or signup=true.
@Input() registerAuth?: string; // Register auth method. E.g. 'email'. @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. // 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) { @ViewChild('userProfileField', { read: ViewContainerRef }) set userProfileField (el: ViewContainerRef) {
if (this.field) { if (this.field) {
this.createComponent(this.ufDelegate.getComponent(this.field, this.signup, this.registerAuth), el); this.createComponent(this.ufDelegate.getComponent(this.field, this.signup), el);
} else { } else {
// The component hasn't been initialized yet. Store the container. // The component hasn't been initialized yet. Store the container.
this.fieldContainer = el; this.fieldContainer = el;
@ -47,7 +48,7 @@ export class CoreUserProfileFieldComponent implements OnInit {
protected fieldInstance: any; protected fieldInstance: any;
constructor(logger: CoreLoggerProvider, private factoryResolver: ComponentFactoryResolver, constructor(logger: CoreLoggerProvider, private factoryResolver: ComponentFactoryResolver,
private ufDelegate: CoreUserProfileFieldDelegate) { private ufDelegate: CoreUserProfileFieldDelegate, private utilsProvider: CoreUtilsProvider) {
this.logger = logger.getInstance('CoreUserProfileFieldComponent'); this.logger = logger.getInstance('CoreUserProfileFieldComponent');
} }
@ -55,7 +56,7 @@ export class CoreUserProfileFieldComponent implements OnInit {
* Component being initialized. * Component being initialized.
*/ */
ngOnInit() { ngOnInit() {
this.createComponent(this.ufDelegate.getComponent(this.field, this.signup, this.registerAuth), this.fieldContainer); this.createComponent(this.ufDelegate.getComponent(this.field, this.signup), this.fieldContainer);
} }
/** /**
@ -86,8 +87,12 @@ export class CoreUserProfileFieldComponent implements OnInit {
// Set the Input data. // Set the Input data.
this.fieldInstance.field = this.field; this.fieldInstance.field = this.field;
this.fieldInstance.edit = this.edit; this.fieldInstance.edit = this.utilsProvider.isTrueOrOne(this.edit);
this.fieldInstance.model = this.model; if (this.edit) {
this.fieldInstance.signup = this.utilsProvider.isTrueOrOne(this.signup);
this.fieldInstance.disabled = this.utilsProvider.isTrueOrOne(this.field.locked);
this.fieldInstance.form = this.form;
}
return true; return true;
} catch(ex) { } catch(ex) {

View File

@ -8,8 +8,11 @@
"detailsnotavailable": "The details of this user are not available to you.", "detailsnotavailable": "The details of this user are not available to you.",
"editingteacher": "Teacher", "editingteacher": "Teacher",
"email": "Email address", "email": "Email address",
"emailagain": "Email (again)",
"errorloaduser": "Error loading user.", "errorloaduser": "Error loading user.",
"firstname": "First name",
"interests": "Interests", "interests": "Interests",
"lastname": "Surname",
"manager": "Manager", "manager": "Manager",
"newpicture": "New picture", "newpicture": "New picture",
"phone1": "Phone", "phone1": "Phone",

View File

@ -60,7 +60,6 @@ export class CoreUserHelperProvider {
let separator = this.translate.instant('core.listsep'); let separator = this.translate.instant('core.listsep');
roles.map((value) => { roles.map((value) => {
console.error(value);
let translation = this.translate.instant('core.user.' + value.shortname); let translation = this.translate.instant('core.user.' + value.shortname);
return translation.indexOf('core.user.') < 0 ? translation : value.shortname; return translation.indexOf('core.user.') < 0 ? translation : value.shortname;
}); });

View File

@ -23,22 +23,19 @@ export interface CoreUserProfileFieldHandler extends CoreDelegateHandler {
/** /**
* Return the Component to use to display the user profile field. * 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. * @return {any} The component to use, undefined if not found.
*/ */
getComponent(field: any, signup: boolean, registerAuth: string): any; getComponent(): any;
/** /**
* Get the data to send for the field based on the input data. * Get the data to send for the field based on the input data.
* @param {any} field User field to get the data for. * @param {any} field User field to get the data for.
* @param {boolean} signup True if user is in signup page. * @param {boolean} signup True if user is in signup page.
* @param {string} [registerAuth] Register auth method. E.g. 'email'. * @param {string} [registerAuth] Register auth method. E.g. 'email'.
* @param {any} model Model with the input data. * @param {any} formValues Form Values.
* @return {Promise<CoreUserProfileFieldHandlerData>|CoreUserProfileFieldHandlerData} Data to send for the field. * @return {Promise<CoreUserProfileFieldHandlerData>|CoreUserProfileFieldHandlerData} Data to send for the field.
*/ */
getData?(field: any, signup: boolean, registerAuth: string, model: any): getData?(field: any, signup: boolean, registerAuth: string, formValues: any):
Promise<CoreUserProfileFieldHandlerData> | CoreUserProfileFieldHandlerData; Promise<CoreUserProfileFieldHandlerData> | CoreUserProfileFieldHandlerData;
}; };
@ -80,12 +77,15 @@ export class CoreUserProfileFieldDelegate extends CoreDelegate {
* *
* @param {any} field User field to get the directive for. * @param {any} field User field to get the directive for.
* @param {boolean} signup True if user is in signup page. * @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. * @return {any} The component to use, undefined if not found.
*/ */
getComponent(field: any, signup: boolean, registerAuth: string) : any { getComponent(field: any, signup: boolean) : any {
let type = field.type || field.datatype; let type = field.type || field.datatype;
return this.executeFunction(type, 'getComponent', [field, signup, registerAuth]); if (signup) {
return this.executeFunction(type, 'getComponent');
} else {
return this.executeFunctionOnEnabled(type, 'getComponent');
}
} }
/** /**
@ -94,22 +94,22 @@ export class CoreUserProfileFieldDelegate extends CoreDelegate {
* @param {any} field User field to get the data for. * @param {any} field User field to get the data for.
* @param {boolean} signup True if user is in signup page. * @param {boolean} signup True if user is in signup page.
* @param {string} registerAuth Register auth method. E.g. 'email'. * @param {string} registerAuth Register auth method. E.g. 'email'.
* @param {any} model Model with the input data. * @param {any} formValues Form values.
* @return {Promise<any>} Data to send for the field. * @return {Promise<any>} Data to send for the field.
*/ */
getDataForField(field: any, signup: boolean, registerAuth: string, model: any): Promise<any> { getDataForField(field: any, signup: boolean, registerAuth: string, formValues: any): Promise<any> {
let handler = this.getHandler(field, signup); let type = field.type || field.datatype,
handler = this.getHandler(type, !signup);
if (handler) { if (handler) {
let name = 'profile_field_' + field.shortname; let name = 'profile_field_' + field.shortname;
if (handler.getData) { if (handler.getData) {
return Promise.resolve(handler.getData(field, signup, registerAuth, model)); return Promise.resolve(handler.getData(field, signup, registerAuth, formValues));
} else if (field.shortname && typeof model[name] != 'undefined') { } else if (field.shortname && typeof formValues[name] != 'undefined') {
// Handler doesn't implement the function, but the model has data for the field. // Handler doesn't implement the function, but the form has data for the field.
return Promise.resolve({ return Promise.resolve({
type: field.type || field.datatype, type: type,
name: name, name: name,
value: model[name] value: formValues[name]
}); });
} }
} }
@ -122,43 +122,25 @@ export class CoreUserProfileFieldDelegate extends CoreDelegate {
* @param {any[]} fields User fields to get the data for. * @param {any[]} fields User fields to get the data for.
* @param {boolean} [signup] True if user is in signup page. * @param {boolean} [signup] True if user is in signup page.
* @param {string} [registerAuth] Register auth method. E.g. 'email'. * @param {string} [registerAuth] Register auth method. E.g. 'email'.
* @param {any} model Model with the input data. * @param {any} formValues Form values.
* @return {Promise<any>} Data to send. * @return {Promise<any>} Data to send.
*/ */
getDataForFields(fields: any[], signup = false, registerAuth = "", model: any): Promise<any> { getDataForFields(fields: any[], signup = false, registerAuth = "", formValues: any): Promise<any> {
let result = [], let result = [],
promises = []; promises = [];
fields.forEach((field) => { fields.forEach((field) => {
this.getDataForField(field, signup, registerAuth, model).then((data) => { promises.push(this.getDataForField(field, signup, registerAuth, formValues).then((data) => {
result.push(data); if (data) {
result.push(data);
}
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); }));
}); });
return Promise.all(promises).then(() => { return Promise.all(promises).then(() => {
return result; 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];
}
} }

View File

@ -743,6 +743,20 @@ export class CoreDomUtilsProvider {
} }
} }
/**
* Show an alert modal with the first warning error message. It uses a default message if error is not a string.
*
* @param {any} warnings Warnings returned.
* @param {any} [defaultError] Message to show if the error is not a string.
* @param {boolean} [needsTranslate] Whether the error needs to be translated.
* @param {number} [autocloseTime] Number of milliseconds to wait to close the modal. If not defined, modal won't be closed.
* @return {Alert} The alert modal.
*/
showErrorModalFirstWarning(warnings: any, defaultError: any, needsTranslate?: boolean, autocloseTime?: number) : Alert {
let error = warnings && warnings.length && warnings[0].message;
return this.showErrorModalDefault(error, defaultError, needsTranslate, autocloseTime);
}
/** /**
* Displays a loading modal window. * Displays a loading modal window.
* *

View File

@ -145,4 +145,12 @@ export class CoreTimeUtilsProvider {
return Math.round(Date.now() / 1000); return Math.round(Date.now() / 1000);
} }
/**
* Return the localized ISO format (i.e DDMMYY) from the localized moment format. Useful for translations.
*
* @return {string} Localized ISO format
*/
getLocalizedDateFormat(lozalizedFormat) : string {
return moment.localeData().longDateFormat(lozalizedFormat);
}
} }