Search code examples
javascriptiframejstree

how to get jstree instance from iframe source?


I have prepare 2 tree view in separate iframe using jstree. The right tree view should control the left tree view. When user click one one the list in right tree view, the respective item folder will open and selected on left tree view. I can make it happen using div in single page. I control the left tree view using instance of left tree view in right jstree div var instance = $('#left').jstree(true);.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<!doctype html>
<html>

<head>
  
  <script src="jquery/jquery-2.2.3.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.11/jstree.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.11/themes/default/style.min.css" />

  <meta charset="UTF-8">
    <title>jstree basic demos</title>
    <style>
    html { margin:0; padding:0; font-size:62.5%; }
    body { max-width:800px; min-width:300px; margin:0 auto; padding:20px 10px; font-size:14px; font-size:1.4em; }
    h1 { font-size:1.8em; }
    .demo { overflow:auto; border:1px solid silver; min-height:100px; }
        
        .flex-container {
            display: flex;
        }
        .flex-child {
            flex: 1;
            border: 1px solid black;
        }  
        .flex-child:first-child {
            margin-right: 20px;
        } 
    </style>
</head>

<body>
  <h1>Tree Menu</h1>
<!--    <button id="evts_button">select node with id 1</button> <em>either click the button or a node in the tree</em>-->
        <div class="flex-container">

            <div class="flex-child magenta">
                <div id="left" class="demo">
                </div>
            </div>

            <div class="flex-child green">
                <div id="List">
                </div>
            </div>
  
        </div>
  <script>
    $('#left')
        .jstree({
            'core' : {
                'multiple' : false,
                'data' : [
                                            {
                                                "text":"A","id":"A","children":[
                                                    {"text":"Australia","id":"Aus"},
                                                    {"text":"America","id":"Ame"}
                                                ]                                             
                                            },                                        
                                            {
                                                "text":"B","id":"B","children":[
                                                    {"text":"Beirut","id":"Bei"},
                                                    {"text":"Brunei","id":"Bru"}
                                                ]
                                            }
                                        ]
            }
        });
    $('#List')
                .on("changed.jstree", function(e,data){
                    if(data.selected.length)
                    {
                        $("#left").jstree("close_all");
                        //console.log(data.selected);
                        selected_node=data.selected[0];//list-j2_1
                        console.log(selected_node);
                        var tm_id = selected_node.replace("j2_", "");//tree
                        var instance = $('#left').jstree(true);
                        instance.deselect_all();
                        instance.select_node(tm_id);
                        $("#left").jstree("open_all", tm_id);
                    }
                })
                .jstree({
                    'core':{
                        'multiple':false,
                        'data':[{"text":"Australia", "id":"Aus"},
                                {"text":"America", "id":"Ame"},
                                {"text":"Beirut","id":"Bei"},
                                {"text":"Brunei", "id":"Bru"}]
                    }
                })
        </script>
</body>

</html>

When using iframe, I could not get the instance of left tree view. I want to get left tree view instance in index-10_2.html(right iframe source) to select and open respective node. I had use left=$("#1").contents(); to get the iframe content, var instance=left.find('#left'); to get instance, and instance.select_node(tm_id); to select node. But, error instance.select_node is not a function shown.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <script src="jquery/jquery-2.2.3.min.js"></script>
        <script src="vakata-jstree-4a77e59/dist/jstree.min.js"></script>
        <link rel="stylesheet" href="vakata-jstree-4a77e59/dist/themes/default/style.min.css" />
    </head>
    <body>
        <iframe src="index-10_1.html" id="1"></iframe>
        <iframe src="index-10_2.html" id="2"></iframe>
    </body>
</html>

index-10_1.html

    <!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <script src="jquery/jquery-2.2.3.min.js"></script>
        <script src="vakata-jstree-4a77e59/dist/jstree.min.js"></script>
        <link rel="stylesheet" href="vakata-jstree-4a77e59/dist/themes/default/style.min.css" />
    </head>
    <body>
            <div class="content demo" id="left"></div>
            <script>
                $('#left')
        .jstree({
            'core' : {
                'multiple' : false,
                'data' : [
                                            {
                                                "text":"A","id":"A","children":[
                                                    {"text":"Australia","id":"Aus"},
                                                    {"text":"America","id":"Ame"}
                                                ]                                             
                                            },                                        
                                            {
                                                "text":"B","id":"B","children":[
                                                    {"text":"Beirut","id":"Bei"},
                                                    {"text":"Brunei","id":"Bru"}
                                                ]
                                            }
                                        ]
            }
        });
            </script>
    </body>
</html>

index-10_2.html

    <!DOCTYPE html>
<html>
    <head>
         <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <script src="jquery/jquery-2.2.3.min.js"></script>
        <script src="vakata-jstree-4a77e59/dist/jstree.min.js"></script>
        <link rel="stylesheet" href="vakata-jstree-4a77e59/dist/themes/default/style.min.css" />
    </head>
    <body>
        <div class="content" id="right"></div>
        <script>
            $('#right')
                    .on("changed.jstree", function(e,data){
                        if(data.selected.length)
                        {
                            $("#left").jstree("close_all");
                            console.log(data.selected);
                            selected_node=data.selected[0];//list-j2_1
                            console.log(selected_node);
                            var tm_id = selected_node.replace("j2_", "");//tree
                            left=$("#1").contents().find('#left');
                            instance=left.jstree(true);
                            instance.select_node(tm_id);
                            $("#left").jstree("open_all", tm_id);
                        }
                    })
                    .jstree({
                        'core':{
                            'multiple':false,
                            'data':[{"text":"Australia", "id":"Aus"},
                                    {"text":"America", "id":"Ame"},
                                    {"text":"Beirut","id":"Bei"},
                                    {"text":"Brunei", "id":"Bru"}]
                        }
                    })
        </script>
    </body>
</html>

Solution

  • I had used document.getElementById('1').contentWindow.jQuery('#left').jstree(true); to get instance from iframe with id='1'. In order to listen to right iframe(with id='2') if any menu has been clicked, I used document.getElementById('2').contentWindow.jQuery('#right').on("changed.jstree",function(e,data){}). I get the instance of left iframe within this function. By using this instance, I has deselect previous selection, select current selection, and open children of selected menu.

    index-12.html

        <!DOCTYPE html>
         <!--
           To change this license header, choose License Headers in Project Properties.
           To change this template file, choose Tools | Templates and open the template 
           in the editor.
        -->
        <html>
        <head>       
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <script src="jquery/jquery-2.2.3.min.js"></script>
            <script src="vakata-jstree-4a77e59/dist/jstree.min.js"></script>
            <link rel="stylesheet" href="vakata-jstree-4a77e59/dist/themes/default/style.min.css" />
        </head>
        <body>
            <iframe src="index-12_1.html" id="1"></iframe>
            <iframe src="index-12_2.html" id="2"></iframe>
            <script>
                sec_frm =document.getElementById('2');//second frame
                sec_frm.addEventListener("load",function(){//wait for second frame to load
                 
     fst_frm_jstinst=document.getElementById('1').contentWindow.jQuery('#left').jstree(true);//first frame jstree instance
                  
    document.getElementById('2').contentWindow.jQuery('#right').on("changed.jstree",function(e,data){
                      if(data.selected.length){
                          //close all menu in first frame
                          document.getElementById('1').contentWindow.jQuery('#left').jstree("close_all");
                          //get selected menu id from second frame
                          selected_node=data.selected[0];
                          //deselect any selected menu on first frame
                          fst_frm_jstinst.deselect_all();
                          //select node(country)
                          fst_frm_jstinst.select_node(selected_node);
                          document.getElementById('1').contentWindow.jQuery('#left').jstree("open_all",selected_node);
                          //console.log(selected_node);
                      }
                  })
    
                })
            </script>
        </body>
    </html>
    

    index-12_1

        <!DOCTYPE html>
    <!--
    To change this license header, choose License Headers in Project Properties.
    To change this template file, choose Tools | Templates
    and open the template in the editor.
    -->
        <html>
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <script src="jquery/jquery-2.2.3.min.js"></script>
            <script src="vakata-jstree-4a77e59/dist/jstree.min.js"></script>
            <link rel="stylesheet" href="vakata-jstree 4a77e59/dist/themes/default/style.min.css"/>
        </head>
        <body>
            <div class="content demo" id="left"></div>
            <script>
                $('#left')
            .jstree({
                'core' : {
                    'multiple' : false,
                    'data' : [
                                                {
                                                    "text":"A","id":"A","children":[
                                                        {"text":"Australia","id":"Aus"},
                                                        {"text":"America","id":"Ame"}
                                                    ]                                             
                                                },                                        
                                                {
                                                    "text":"B","id":"B","children":[
                                                        {"text":"Beirut","id":"Bei"},
                                                        {"text":"Brunei","id":"Bru"}
                                                    ]
                                                }
                                            ]
                }
            });
            </script>
        </body>
    </html>
    

    index-12_2.html

    <!DOCTYPE html>
    <!--
    To change this license header, choose License Headers in Project Properties.
    To change this template file, choose Tools | Templates
    and open the template in the editor.
    -->
    <html>
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
             <script src="jquery/jquery-2.2.3.min.js"></script>
            <script src="vakata-jstree-4a77e59/dist/jstree.min.js"></script>
            <link rel="stylesheet" href="vakata-jstree-4a77e59/dist/themes/default/style.min.css" />
        </head>
        <body>
            <div class="content" id="right"></div>
            <script>
                $('#right')
                        .jstree({
                                    'core':{
                                        'multiple':false,
                                        'data':[{"text":"Australia", "id":"Aus"},
                                                {"text":"America", "id":"Ame"},
                                                {"text":"Beirut","id":"Bei"},
                                                {"text":"Brunei", "id":"Bru"}]
                                    }
                                })
            </script>
        </body>
    </html>