From 91b020e2fbdc5ec708fdea7569ca6817f9309389 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 20 Feb 2018 15:35:53 +0100 Subject: [PATCH] MOBILE-2333 siteaddons: Allow sending form data --- .../siteaddons/classes/call-ws-directive.ts | 36 ++++++++++++------ src/core/siteaddons/directives/new-content.ts | 11 +++++- src/providers/utils/dom.ts | 37 +++++++++++++++++++ 3 files changed, 70 insertions(+), 14 deletions(-) diff --git a/src/core/siteaddons/classes/call-ws-directive.ts b/src/core/siteaddons/classes/call-ws-directive.ts index 45069b43d..be26166fb 100644 --- a/src/core/siteaddons/classes/call-ws-directive.ts +++ b/src/core/siteaddons/classes/call-ws-directive.ts @@ -31,6 +31,8 @@ export class CoreSiteAddonsCallWSBaseDirective implements OnInit, OnDestroy { @Input() confirmMessage: string; // Message to confirm the action. If not supplied, no confirmation. If empty, default message. @Input() useOtherDataForWS: any[]; // Whether to include other data in the params for the WS. // @see CoreSiteAddonsProvider.loadOtherDataInArgs. + @Input() form: string; // ID or name to identify a form. The form will be obtained from document.forms. + // If supplied and form is found, the form data will be retrieved and sent to the WS. protected element: HTMLElement; protected invalidateObserver: Subscription; @@ -73,13 +75,8 @@ export class CoreSiteAddonsCallWSBaseDirective implements OnInit, OnDestroy { * @return {Promise} Promise resolved when done. */ protected callWS(): Promise { - const modal = this.domUtils.showModalLoading(); - - let params = this.params; - - if (this.parentContent) { - params = this.siteAddonsProvider.loadOtherDataInArgs(params, this.parentContent.otherData, this.useOtherDataForWS); - } + const modal = this.domUtils.showModalLoading(), + params = this.getParamsForWS(); return this.siteAddonsProvider.callWS(this.name, params, this.preSets).then((result) => { return this.wsCallSuccess(result); @@ -90,6 +87,25 @@ export class CoreSiteAddonsCallWSBaseDirective implements OnInit, OnDestroy { }); } + /** + * Get the params for the WS call. + * + * @return {any} Params. + */ + protected getParamsForWS(): any { + let params = this.params || {}; + + if (this.parentContent) { + params = this.siteAddonsProvider.loadOtherDataInArgs(params, this.parentContent.otherData, this.useOtherDataForWS); + } + + if (this.form && document.forms[this.form]) { + params = Object.assign(params, this.domUtils.getDataFromForm(document.forms[this.form])); + } + + return params; + } + /** * Function called when the WS call is successful. * @@ -105,11 +121,7 @@ export class CoreSiteAddonsCallWSBaseDirective implements OnInit, OnDestroy { * @return {Promise} Promise resolved when done. */ invalidate(): Promise { - let params = this.params; - - if (this.parentContent) { - params = this.siteAddonsProvider.loadOtherDataInArgs(params, this.parentContent.otherData, this.useOtherDataForWS); - } + const params = this.getParamsForWS(); return this.siteAddonsProvider.invalidateCallWS(this.name, params, this.preSets); } diff --git a/src/core/siteaddons/directives/new-content.ts b/src/core/siteaddons/directives/new-content.ts index f809148e6..4db053f85 100644 --- a/src/core/siteaddons/directives/new-content.ts +++ b/src/core/siteaddons/directives/new-content.ts @@ -14,6 +14,7 @@ import { Directive, Input, OnInit, ElementRef, Optional } from '@angular/core'; import { NavController } from 'ionic-angular'; +import { CoreDomUtilsProvider } from '../../../providers/utils/dom'; import { CoreUtilsProvider } from '../../../providers/utils/utils'; import { CoreSiteAddonsProvider } from '../providers/siteaddons'; import { CoreSiteAddonsAddonContentComponent } from '../components/addon-content/addon-content'; @@ -48,11 +49,13 @@ export class CoreSiteAddonsNewContentDirective implements OnInit { @Input() title: string; // The title to display with the new content. Only if samePage=false. @Input() samePage: boolean | string; // Whether to display the content in same page or open a new one. Defaults to new page. @Input() useOtherData: any[]; // Whether to include other data in the args. @see CoreSiteAddonsProvider.loadOtherDataInArgs. + @Input() form: string; // ID or name to identify a form. The form will be obtained from document.forms. + // If supplied and form is found, the form data will be retrieved and sent to the new content. protected element: HTMLElement; constructor(element: ElementRef, protected utils: CoreUtilsProvider, protected navCtrl: NavController, - @Optional() protected parentContent: CoreSiteAddonsAddonContentComponent, + @Optional() protected parentContent: CoreSiteAddonsAddonContentComponent, protected domUtils: CoreDomUtilsProvider, protected siteAddonsProvider: CoreSiteAddonsProvider) { this.element = element.nativeElement || element; } @@ -65,12 +68,16 @@ export class CoreSiteAddonsNewContentDirective implements OnInit { ev.preventDefault(); ev.stopPropagation(); - let args = this.args; + let args = this.args || {}; if (this.parentContent) { args = this.siteAddonsProvider.loadOtherDataInArgs(this.args, this.parentContent.otherData, this.useOtherData); } + if (this.form && document.forms[this.form]) { + args = Object.assign(args, this.domUtils.getDataFromForm(document.forms[this.form])); + } + if (this.utils.isTrueOrOne(this.samePage)) { // Update the parent content (if it exists). if (this.parentContent) { diff --git a/src/providers/utils/dom.ts b/src/providers/utils/dom.ts index 72843064c..f28c8b5e7 100644 --- a/src/providers/utils/dom.ts +++ b/src/providers/utils/dom.ts @@ -264,6 +264,43 @@ export class CoreDomUtilsProvider { } } + /** + * Get the data from a form. It will only collect elements that have a name. + * + * @param {HTMLFormElement} form The form to get the data from. + * @return {any} Object with the data. The keys are the names of the inputs. + */ + getDataFromForm(form: HTMLFormElement): any { + if (!form || !form.elements) { + return {}; + } + + const data = {}; + + for (let i = 0; i < form.elements.length; i++) { + const element: any = form.elements[i], + name = element.name || ''; + + // Ignore submit inputs. + if (!name || element.type == 'submit' || element.tagName == 'BUTTON') { + return; + } + + // Get the value. + if (element.type == 'checkbox') { + data[name] = !!element.checked; + } else if (element.type == 'radio') { + if (element.checked) { + data[name] = element.value; + } + } else { + data[name] = element.value; + } + } + + return data; + } + /** * Returns height of an element. *