forked from CIT/Vmeda.Online
		
	MOBILE-2577 quiz: Fix position of drags when question contains images
This commit is contained in:
		
							parent
							
								
									ab1c124713
								
							
						
					
					
						commit
						c14d7ad04a
					
				| @ -7,7 +7,7 @@ | ||||
|             <ion-icon name="information-circle"></ion-icon> | ||||
|             {{ 'core.question.howtodraganddrop' | translate }} | ||||
|         </p> | ||||
|         <p><core-format-text [component]="component" [componentId]="componentId" [text]="question.text"></core-format-text></p> | ||||
|         <p><core-format-text [component]="component" [componentId]="componentId" [text]="question.text" #questiontext></core-format-text></p> | ||||
|         <core-format-text *ngIf="question.ddArea" [adaptImg]="false" [component]="component" [componentId]="componentId" [text]="question.ddArea" (afterRender)="questionRendered()"></core-format-text> | ||||
|     </ion-item> | ||||
| </section> | ||||
|  | ||||
| @ -12,7 +12,7 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Component, OnInit, OnDestroy, Injector, ElementRef } from '@angular/core'; | ||||
| import { Component, OnInit, OnDestroy, Injector, ElementRef, ViewChild } from '@angular/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreQuestionBaseComponent } from '@core/question/classes/base-question-component'; | ||||
| import { AddonQtypeDdMarkerQuestion } from '../classes/ddmarker'; | ||||
| @ -25,6 +25,7 @@ import { AddonQtypeDdMarkerQuestion } from '../classes/ddmarker'; | ||||
|     templateUrl: 'addon-qtype-ddmarker.html' | ||||
| }) | ||||
| export class AddonQtypeDdMarkerComponent extends CoreQuestionBaseComponent implements OnInit, OnDestroy { | ||||
|     @ViewChild('questiontext') questionTextEl: ElementRef; | ||||
| 
 | ||||
|     protected element: HTMLElement; | ||||
|     protected questionInstance: AddonQtypeDdMarkerQuestion; | ||||
| @ -87,9 +88,11 @@ export class AddonQtypeDdMarkerComponent extends CoreQuestionBaseComponent imple | ||||
|      */ | ||||
|     questionRendered(): void { | ||||
|         if (!this.destroyed) { | ||||
|             // Create the instance.
 | ||||
|             this.questionInstance = new AddonQtypeDdMarkerQuestion(this.loggerProvider, this.domUtils, this.textUtils, this.element, | ||||
|                     this.question, this.question.readOnly, this.dropZones); | ||||
|             this.domUtils.waitForImages(this.questionTextEl.nativeElement).then(() => { | ||||
|                 // Create the instance.
 | ||||
|                 this.questionInstance = new AddonQtypeDdMarkerQuestion(this.loggerProvider, this.domUtils, this.textUtils, | ||||
|                         this.element, this.question, this.question.readOnly, this.dropZones); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -1,10 +1,13 @@ | ||||
| <section ion-list *ngIf="question.text || question.text === ''"> | ||||
|     <ion-item text-wrap class="addon-qtype-ddwtos-container"> | ||||
|     <!-- Content is outside the core-loading to let the script calculate drag items position --> | ||||
|     <core-loading [hideUntil]="question.loaded"></core-loading> | ||||
| 
 | ||||
|     <ion-item text-wrap class="addon-qtype-ddwtos-container" [ngClass]="{invisible: !question.loaded}"> | ||||
|         <p *ngIf="!question.readOnly" class="core-info-card" icon-start> | ||||
|             <ion-icon name="information-circle"></ion-icon> | ||||
|             {{ 'core.question.howtodraganddrop' | translate }} | ||||
|         </p> | ||||
|         <p><core-format-text [component]="component" [componentId]="componentId" [text]="question.text"></core-format-text></p> | ||||
|         <p><core-format-text [component]="component" [componentId]="componentId" [text]="question.text" #questiontext></core-format-text></p> | ||||
|         <core-format-text *ngIf="question.answers" [component]="component" [componentId]="componentId" [text]="question.answers" (afterRender)="questionRendered()"></core-format-text> | ||||
|         <div class="drags"></div> | ||||
|     </ion-item> | ||||
|  | ||||
| @ -12,7 +12,7 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Component, OnInit, OnDestroy, Injector, ElementRef } from '@angular/core'; | ||||
| import { Component, OnInit, OnDestroy, Injector, ElementRef, ViewChild } from '@angular/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreQuestionBaseComponent } from '@core/question/classes/base-question-component'; | ||||
| import { AddonQtypeDdwtosQuestion } from '../classes/ddwtos'; | ||||
| @ -25,6 +25,7 @@ import { AddonQtypeDdwtosQuestion } from '../classes/ddwtos'; | ||||
|     templateUrl: 'addon-qtype-ddwtos.html' | ||||
| }) | ||||
| export class AddonQtypeDdwtosComponent extends CoreQuestionBaseComponent implements OnInit, OnDestroy { | ||||
|     @ViewChild('questiontext') questionTextEl: ElementRef; | ||||
| 
 | ||||
|     protected element: HTMLElement; | ||||
|     protected questionInstance: AddonQtypeDdwtosQuestion; | ||||
| @ -80,6 +81,8 @@ export class AddonQtypeDdwtosComponent extends CoreQuestionBaseComponent impleme | ||||
|             this.question.text += inputEl.outerHTML; | ||||
|             this.inputIds.push(inputEl.getAttribute('id')); | ||||
|         }); | ||||
| 
 | ||||
|         this.question.loaded = false; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -87,11 +90,15 @@ export class AddonQtypeDdwtosComponent extends CoreQuestionBaseComponent impleme | ||||
|      */ | ||||
|     questionRendered(): void { | ||||
|         if (!this.destroyed) { | ||||
|             // Create the instance.
 | ||||
|             this.questionInstance = new AddonQtypeDdwtosQuestion(this.loggerProvider, this.domUtils, this.element, this.question, | ||||
|                     this.question.readOnly, this.inputIds); | ||||
|             this.domUtils.waitForImages(this.questionTextEl.nativeElement).then(() => { | ||||
|                 // Create the instance.
 | ||||
|                 this.questionInstance = new AddonQtypeDdwtosQuestion(this.loggerProvider, this.domUtils, this.element, | ||||
|                         this.question, this.question.readOnly, this.inputIds); | ||||
| 
 | ||||
|             this.questionHelper.treatCorrectnessIconsClicks(this.element, this.component, this.componentId); | ||||
|                 this.questionHelper.treatCorrectnessIconsClicks(this.element, this.component, this.componentId); | ||||
| 
 | ||||
|                 this.question.loaded = true; | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -16,6 +16,7 @@ import { NgModule } from '@angular/core'; | ||||
| import { IonicModule } from 'ionic-angular'; | ||||
| import { TranslateModule } from '@ngx-translate/core'; | ||||
| import { CoreQuestionDelegate } from '@core/question/providers/delegate'; | ||||
| import { CoreComponentsModule } from '@components/components.module'; | ||||
| import { CoreDirectivesModule } from '@directives/directives.module'; | ||||
| import { AddonQtypeDdwtosHandler } from './providers/handler'; | ||||
| import { AddonQtypeDdwtosComponent } from './component/ddwtos'; | ||||
| @ -27,6 +28,7 @@ import { AddonQtypeDdwtosComponent } from './component/ddwtos'; | ||||
|     imports: [ | ||||
|         IonicModule, | ||||
|         TranslateModule.forChild(), | ||||
|         CoreComponentsModule, | ||||
|         CoreDirectivesModule | ||||
|     ], | ||||
|     providers: [ | ||||
|  | ||||
| @ -296,7 +296,7 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|                 this.calculateHeight(); | ||||
| 
 | ||||
|                 // Wait for images to load and calculate the height again if needed.
 | ||||
|                 this.waitForImages().then((hasImgToLoad) => { | ||||
|                 this.domUtils.waitForImages(this.element).then((hasImgToLoad) => { | ||||
|                     if (hasImgToLoad) { | ||||
|                         this.calculateHeight(); | ||||
|                     } | ||||
| @ -628,39 +628,6 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|         this.iframeUtils.treatFrame(iframe); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Wait for images to load. | ||||
|      * | ||||
|      * @return {Promise<boolean>} Promise resolved with a boolean: whether there was any image to load. | ||||
|      */ | ||||
|     protected waitForImages(): Promise<boolean> { | ||||
|         const imgs = Array.from(this.element.querySelectorAll('img')), | ||||
|             promises = []; | ||||
|         let hasImgToLoad = false; | ||||
| 
 | ||||
|         imgs.forEach((img) => { | ||||
|             if (img && !img.complete) { | ||||
|                 hasImgToLoad = true; | ||||
| 
 | ||||
|                 // Wait for image to load or fail.
 | ||||
|                 promises.push(new Promise((resolve, reject): void => { | ||||
|                     const imgLoaded = (): void => { | ||||
|                         resolve(); | ||||
|                         img.removeEventListener('loaded', imgLoaded); | ||||
|                         img.removeEventListener('error', imgLoaded); | ||||
|                     }; | ||||
| 
 | ||||
|                     img.addEventListener('load', imgLoaded); | ||||
|                     img.addEventListener('error', imgLoaded); | ||||
|                 })); | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         return Promise.all(promises).then(() => { | ||||
|             return hasImgToLoad; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Convenience function to extract YouTube Id to translate to embedded video. | ||||
|      * Based on http://stackoverflow.com/questions/3452546/javascript-regex-how-to-get-youtube-video-id-from-url
 | ||||
|  | ||||
| @ -1258,6 +1258,40 @@ export class CoreDomUtilsProvider { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Wait for images to load. | ||||
|      * | ||||
|      * @param {HTMLElement} element The element to search in. | ||||
|      * @return {Promise<boolean>} Promise resolved with a boolean: whether there was any image to load. | ||||
|      */ | ||||
|     waitForImages(element: HTMLElement): Promise<boolean> { | ||||
|         const imgs = Array.from(element.querySelectorAll('img')), | ||||
|             promises = []; | ||||
|         let hasImgToLoad = false; | ||||
| 
 | ||||
|         imgs.forEach((img) => { | ||||
|             if (img && !img.complete) { | ||||
|                 hasImgToLoad = true; | ||||
| 
 | ||||
|                 // Wait for image to load or fail.
 | ||||
|                 promises.push(new Promise((resolve, reject): void => { | ||||
|                     const imgLoaded = (): void => { | ||||
|                         resolve(); | ||||
|                         img.removeEventListener('load', imgLoaded); | ||||
|                         img.removeEventListener('error', imgLoaded); | ||||
|                     }; | ||||
| 
 | ||||
|                     img.addEventListener('load', imgLoaded); | ||||
|                     img.addEventListener('error', imgLoaded); | ||||
|                 })); | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         return Promise.all(promises).then(() => { | ||||
|             return hasImgToLoad; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Wrap an HTMLElement with another element. | ||||
|      * | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user