How to access function in a parent html(home in ionic) from child loaded html

Dear Friends,

iam creating an app with iionic angular. i have loaded an html file by clicking on a list item. when i click a text in that loaded child webpage i need to acccess a function in parent html that is our home page created with ionic. pls help me to get this done.

iam using code to load html file as below:

document.getElementById(‘ifr_ani’).setAttribute(‘src’,’./assets/content/’+this.selectedLesson.ani);

in selectedlesson.ani i have (sample.html). insde this sample.html i have some text if i click those text, i want to access a function in my home.ts file and load another html (mentioned in my json).

Thanks and Regards,
Syed Abdul Rahim

Hey,

first: You should not load the html via setAttribute. With Angular you have the benefit to not have to work directly on the html elements. You can set the src in the html to “./assets/content/{{this.selectedLesson.ani}}”.
It reloads automatically, when the Value changes.

for your Problem: You load a external HTML File. Does the text in there has a id? Try to add a Event Listener for the click Methode on the ID.

Dear Mr.EinfachHans,

Greetings! that text i gave as span as below

<span onclick="callParent()">Test click me</span>  

<script>
    function callParent(){
       // console.log(parent.document.scripts);
    }
</script>

inside the function i dont know what to give. pls help me to access the function in parent html.

Lets say the loaded HTML has a text like this:

<div id="textId">
  Test Click Me
</div>

After you loaded the HTML you should try something like this:

document.findElementById('textId').addEventListener('click', () => {
  //your code here
});

hi, pls check my edited one… already i gave click option, i said i dont know what to give in my funciton callParent(). What command to call a function inside a parent html

With your option you execute the method from the html, i don’t know if it is possible like this. Please try my answer above. The addEventListener ist in your main app, so you can execute whatever you want

k. Thks Mr.EinfachHans.

I’m unclear on what “load another html” means, but I would strongly urge you to reconsider this design, as it creates too tight coupling between pages. Pages declare their interface via @Input and @Output bindings, and that (along with mutually shared injected services) would make for considerably more idiomatic and maintainable code IMHO than any attempt to break encapsulation and start reaching into other pages directly.

Dear Friends,

I found a way to communicate between my child (loaded from asset) and parent (homepage.html) html pages. I used parent.postMessage() option. Find below my codes:

code i used in child (loaded) html:

> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
> <html xmlns="http://www.w3.org/1999/xhtml">
> <head>
> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
> <title>Manual 1 Lesson 1 _1 content</title>
> </head>
> Manul 1 Lesson 1 _1 content
> <body>
> <br>test content
> <br>
> <span  onclick="callParent()">Test click me</span>
> </body>
> <script>
>     var obj={"faultcode":0,"lessonName":4};
>     function callParent(){
>         obj.faultcode=2430
>         parent.postMessage(obj,"*");
>     }
> </script>
> </html>

Code i used in parent (home.page.ts) is:

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  fulldetails: Observable<any>;
  lessonDetails =[];
  selectedLesson = {
    "uid":"",
    "name":"", 
    "faultcode":"",
    "ani":"",
    "cont":"",
    "vid":"",
    "acti":""
  };
  searchVal = "";

  constructor(private router:Router, public httpClient: HttpClient, public sanitizer:DomSanitizer) {
    this.loadJsonData();
  }


  loadJsonData(){
    this.fulldetails = this.httpClient.get('./assets/jsons/sample_menu.json');
    this.fulldetails.subscribe(data =>{
      this.lessonDetails = data;
      this.selectedLesson = data[0]
    })
  }

  lesson_clicked(selItemDetails){
    console.log(selItemDetails);
    this.selectedLesson = selItemDetails;
    document.getElementById('ifr_ani').setAttribute('src','./assets/content/'+this.selectedLesson.ani);
    document.getElementById('ifr_cont').setAttribute('src','./assets/content/'+ this.selectedLesson.cont);
  }

  searchfun(inputTxt){
    if(inputTxt.length>0){
    let selectedCategory = this.lessonDetails.filter(searchresult => searchresult.faultcode === inputTxt);
    if(selectedCategory.length>0){
      this.selectedLesson = selectedCategory[0];
      this.lesson_clicked(this.selectedLesson);
    }
    }
  }
}

window.onmessage=function(evt)
  {
    var receivedMsg = evt.data;
    if(receivedMsg.faultcode !=0 && receivedMsg.faultcode !=undefined)
    {
    alert(receivedMsg.faultcode +"___"+receivedMsg.lessonName);   
    searchfun(faultcode);
    } 
  }

its working fine. But i cannot access the function within our class, “export class HomePage”. giving error. iam getting alert and its communicating between both html files. but i want to access the function in side the class.

pls help me to solve this issue friends…

Thanks and Regards,
Syed Abdul Rahim

This is extremely unidiomatic for an Angular app. If I understand what you are trying to do correctly, the “child” component wants to tell the “parent” component “hey, please select lesson X”. The way I would write it is more like so:

class ParentComponent {
  onLessonSelectionChanged(lesson: string): void {
    // do "searchfun" stuff
  }
}
class ChildComponent {
  @Output() lessonChange = new EventEmitter(string);
  buttonGotPressed(): {
    this.lesson.emit("foo");
  }
}
<child-selector (lessonChange)="onLessonSelectionChanged($event)">

Dear friends,

i make it work by changing below code. I just moved my receiving message function within constructor as below:

 constructor(public events: Events ,public httpClient: HttpClient) {

    window.addEventListener('message', (event) => {     
      console.log(event.data);
      this.searchfun(event.data.faultcode);
    });
  }

its working fine and receiving messages and data from loaded child html.

In my homepage.html i have below code when changing the selected menu:

<ion-list>
                  <ion-item *ngFor="let item of lessonDetails;" (click)="lesson_clicked(item)"  [ngClass]="item.uid == selectedLesson.uid ?'selItem':''">
                    {{item.name}}
                </ion-item>
 </ion-list>

this [ngClass] is working in browser… when i compile and loaded in tab its not working. all other things are working fine. when i click external html it sends message and parent homepage receives it and loading new page with same faultcode. but in ipad [ngClass] the class changing is nto working.

pls help me my friends…how can i make it work [ngClass] in ipad… iam calling same function search while clicking on search button its working fine.

Thanks and Regards,
Syed Abdul Rahim

OK, I’m going to try this one more time, and then let other people take over. Angular evolved in order to have a coherent strategy, well-tested and optimized code base designed to tackle web app organization. There is a nice tutorial that walks you through many of these core design principles with idiomatic sample code in the Tour of Heroes. It’s well worth going through in toto, but the particular sections that cover communication between components are chapter 3 on master/detail components and chapter 4 on services.