PushPage's Title and JSON Ajax problem



  • Hello,

    I am new to Onsen UI, and choose to trying Onsen UI with JavaScript and use JQuery. I am making a application to display product list. I already success make the main page (lets call it as home.html) of my application. I am do it with <ons-list></ons-list>. And fetched the data from JSON as <ons-list-item></ons-list-item>.

    Now, the problem is when i tap/click a list then a new ons-page will appear with .pushPage function (lets call it as product.html), but i can’t make my ons-toolbar in product.html title changed based on my ons-list-item's name, instead the one in home.html is changed to my ons-list-item's name after it.

    And the other problem is, how to pass the data to that product.html ? because i want to call JSON via ajax based on id from ons-list-item in my home.html.

    what i already use in this application is ons-splitter and ons-navigator.

    Thanks for your help.



  • this is my code

    <ons-splitter>
        <ons-splitter-side id="menu" side="left" width="85%" collapse swipeable>
            <ons-page>
                <ons-list class="mainmenu">
                    <ons-list-item onclick="fn.load('home.html');loadproduk()" tappable ripple>
                        <ons-ripple color="#bb8fce" background="#85c1e9"></ons-ripple>
                            <i class="fa fa-fw fa-home"></i> 
                        <span class="listmainmenu">Home</span>
                    </ons-list-item>
                    <ons-list-item onclick="fn.load('about.html')" tappable ripple>
                        <ons-ripple color="#bb8fce" background="#85c1e9"></ons-ripple>
                        <i class="fa fa-fw fa-info"></i>
                        <span class="listmainmenu">About</span>
                    </ons-list-item>
                </ons-list>
            </ons-page>
        </ons-splitter-side>
        <ons-splitter-content id="content" page="home.html"></ons-splitter-content>
    </ons-splitter> 
    
    <ons-template id="home.html"> 
                 <ons-navigator id="coreNavigator" animation="slide" page="home.html"> 
                    <ons-page id="home">
                        <ons-toolbar>
                            <div class="left">
                                <ons-toolbar-button onclick="fn.open()">
                                    <ons-icon icon="ion-navicon, material:md-menu"></ons-icon>
                                </ons-toolbar-button>
                            </div>
                            <div class="center">Home</div>  
                        </ons-toolbar>
                        <ons-pull-hook id="pull-hook" threshold-height="120px">
                            <ons-icon id="pull-hook-icon" size="22px" class="pull-hook-content" icon="fa-arrow-down"></ons-icon>
                        </ons-pull-hook>
                        <ons-progress-bar indeterminate id="prosesloadingproduk"></ons-progress-bar>
                         <ons-list id="datalist"> 
                         </ons-list>
                    </ons-page>
                 </ons-navigator> 
             </ons-template> 
    
              <ons-template id="harga.html">
                <ons-page id="harga">
                    <ons-toolbar>
                        <div class="left">
                            <ons-back-button>
                                <ons-icon icon="ion-arrow-left, material:md-arrow-left"></ons-icon>
                            </ons-back-button>
                        </div>
                        <div class="center judulharga" id="judulharga">
                            Judul
                        </div>
                    </ons-toolbar>
                    <div>
                        <p id="judulproduk">abcd</p>
                    </div>
                </ons-page>
            </ons-template>  
    
            <ons-alert-dialog id="dialogerror">
                <div class="alert-dialog-title"><i class="fa fa-fw fa-exclamation-triangle"></i> Error</div>
                <div class="alert-dialog-content">
                    <p id="pesanerror1"></p>
                    <p id="pesanerror2"></p>
                    <p id="pesanerror3"></p>
                </div>
                <button class="alert-dialog-button" onclick="hideDialog('dialogerror')">OK</button>
            </ons-alert-dialog> 
    

    and this is my ajax

    $(document).ready(function(){
        loadproduk();
    })
    
    function loadproduk(){
        $.ajax({
        type: "GET",
        url: 'http://localhost/program/getjson/produk',
        dataType: "JSON",
        timeout: 10000,
        cache: false,
        success: function(result){
            var page = event.target;
            $.each(result[0], function(index, el){
                var nama = el.nama;
                const listItem = $('<ons-list-item modifier="chevron" tappable ripple class="tombolmenu">');
                const p = $('<p>');
                p.text(el.nama);
                listItem.append(p);
                listItem.click(
                    function bukapaket() {
                        document.querySelector('#coreNavigator').pushPage('harga.html');
                        console.log("ID dari halaman ini adalah "+el.id+" , dan Nama dari halaman ini adalah "+el.nama+" , dan ini adalah Halaman Harga");
                    }
                );
                $('#datalist').append(listItem);
                $('#prosesloadingproduk').hide();
                console.log(el.nama);
                console.log(el.id);
            });
        },
            error: function(xhr, textStatus, thrownError) {
                $('#prosesloadingproduk').hide();
                $('#dialogerror').show();
                $("#pesanerror1").html("Terjadi Masalah, Silahkan Periksa Kembali Koneksi Internet Anda.");
                $("#pesanerror2").html(xhr.error);
                $("#pesanerror3").html("");
                console.log("error,",xhr.error);
            }
        });
    };
    

  • Onsen UI

    @dvlwjoffice Hi! A few things I’d change:

    1. ons.ready(callback) waits for “DOMContentLoaded”, for Cordva’s “deviceready” and for some internal setup in Onsen UI, so it is probably better than $(document).ready.

    2. You are loading data after the Ajax request is done, but you cannot ensure that #datalist is there at that moment because <ons-splitter-content page="..."> is loading the page asynchronously as well. Perhaps you can consider checking page’s lifecycle events to make sure #home is attached.

    3. For versions >= 2.4.0, <template> is a better option than <ons-template> since it is native.

    About your questions, I don’t see how are you trying to change the toolbar title, but the right way is to use page’s lifecycle events again. Specifically, the init event:

    document.addEventListener('init', function(event) {
      var page = event.target;
      if (page.matches('#home') {
        page.querySelector('ons-toolbar .center').innerHTML = '...';
      }
    });
    

    For passing information, pushPage methods accepts a second parameter options which can contain options.data object:

    myNavigator.pushPage('page.html', { data: { customID: '...' } });
    

    The data object will be available as a property of the page element. In the init event, for example, you can check event.target.data and use it to set up the content.

    Hope it helps!



  • @Fran-Diox said:

    @dvlwjoffice Hi! A few things I’d change:

    1. ons.ready(callback) waits for “DOMContentLoaded”, for Cordva’s “deviceready” and for some internal setup in Onsen UI, so it is probably better than $(document).ready.

    2. You are loading data after the Ajax request is done, but you cannot ensure that #datalist is there at that moment because <ons-splitter-content page="..."> is loading the page asynchronously as well. Perhaps you can consider checking page’s lifecycle events to make sure #home is attached.

    3. For versions >= 2.4.0, <template> is a better option than <ons-template> since it is native.

    About your questions, I don’t see how are you trying to change the toolbar title, but the right way is to use page’s lifecycle events again. Specifically, the init event:

    document.addEventListener('init', function(event) {
      var page = event.target;
      if (page.matches('#home') {
        page.querySelector('ons-toolbar .center').innerHTML = '...';
      }
    });
    

    For passing information, pushPage methods accepts a second parameter options which can contain options.data object:

    myNavigator.pushPage('page.html', { data: { customID: '...' } });
    

    The data object will be available as a property of the page element. In the init event, for example, you can check event.target.data and use it to set up the content.

    Hope it helps!

    Hello @Fran-Diox ! Thanks for reply.

    I doesn’t know why when i using ons.ready the script will not run. I already include onsen-ui 's core like what documentation said. But, I will try it again today.

    Yes, you are right, i am using 2.4.2, I doesn’t know that they add <template> im just following their guide in the site.

    And yes, i deleted my line of code for changing title when posting it here, because i think my code is the main fault and it useless to post it.

    Well, Thanks for everything Fran. I will try it first, then i will make sure i will tell u the update of my case.
    Once again, Thanks !



  • Yo @Fran-Diox , me already test what you suggest. I got some problem with that passing data when push page, i copy my whole code below, can you see what i do wrong with it? Thanks

    /* OnsenUI */
    
    //Menu Splitter
    window.fn = {};
    
    window.fn.open = function() {
      var menu = document.getElementById('menu');
      menu.open();
    };
    
    window.fn.load = function(page) {
      var content = document.getElementById('content');
      var menu = document.getElementById('menu');
      content.load(page)
        .then(menu.close.bind(menu));
    };
    
    //PopUp Error
    var showDialog = function (id) {
      document
        .getElementById(id)
        .show();
    };
    
    var hideDialog = function (id) {
      document
        .getElementById(id)
        .hide();
    };
    
    //Pull Hook
    document.addEventListener("init",function(event){
        if(event.target.id == "home"){
            var pullHook = document.getElementById('pull-hook');
            var icon = document.getElementById('pull-hook-icon');
            pullHook.addEventListener('changestate', function (event) {
                switch (event.state) {
                case 'initial':
                    icon.setAttribute('icon', 'fa-arrow-down');
                    icon.removeAttribute('rotate');
                    icon.removeAttribute('spin');
                    break;
                case 'preaction':
                    icon.setAttribute('icon', 'fa-arrow-down');
                    icon.setAttribute('rotate', '180');
                    icon.removeAttribute('spin');
                    break;
                case 'action':
                    icon.setAttribute('icon', 'fa-spinner');
                    icon.removeAttribute('rotate');
                    icon.setAttribute('spin', true);
                    break;
                }
            });
            pullHook.onAction = function (done) {
                setTimeout(function(){
                    location.reload();
                }, 2000);
            }
        }
    });
    
    //Change harga.html title to field nama
    document.addEventListener('init', function(event) {
      var page = event.target;
      if (page.matches('#harga')){
        page.querySelector('ons-toolbar .center').innerHTML = nama;
      }
    });
    
    /*JQuery JSON*/
    
    //Call JSON when document ready
    
    ons.ready(function(){
        console.log("device is ready");
        loadproduk();
    })
    
    //Call JSON Menu Produk
    function loadproduk(){
        $.ajax({
        type: "GET",
        url: 'my url',
        dataType: "JSON",
        timeout: 10000,
        cache: false,
        success: function(result){
            var page = event.target;
            $.each(result[0], function(index, el){
                var nama = el.nama;
                const listItem = $('<ons-list-item modifier="chevron" tappable ripple class="tombolmenu">');
                const p = $('<p>');
                p.text(el.nama);
                listItem.append(p);
                listItem.click(
                    function bukapaket() {
    //passing data field of id and nama when click menu
                        document.querySelector('#coreNavigator').pushPage('harga.html', {data: {ID: 'id',nama: 'nama'}});
                        console.log("ID dari halaman ini adalah "+el.id+" , dan Nama dari halaman ini adalah "+el.nama+" , dan ini adalah Halaman Harga");
                    }
                );
                $('#datalist').append(listItem);
                $('#prosesloadingproduk').hide();
                console.log(el.nama);
                console.log(el.id);
            });
        },
            error: function(xhr, textStatus, thrownError) {
                $('#prosesloadingproduk').hide();
                $('#dialogerror').show();
                $("#pesanerror1").html("Terjadi Masalah, Silahkan Periksa Kembali Koneksi Internet Anda.");
                $("#pesanerror2").html(xhr.error);
                $("#pesanerror3").html("");
                console.log("error,",xhr.error);
            }
        });
    };
    

    and this is my json format :

    [[
    {"id":1,"nama":"Produk A"},
    {"id":2,"nama":"Produk B"},
    {"id":3,"nama":"Produk C"},
    {"id":4,"nama":"Produk D"},
    {"id":5,"nama":"Produk E"},
    {"id":7,"nama":"Produk G"},
    {"id":6,"nama":"Produk F"}
    ]]
    

    Thanks for your help , i am waiting your reply @Fran-Diox , really need your help ;)


  • Onsen UI

    @dvlwjoffice said:

    {data: {ID: ‘id’,nama: ‘nama’}}

    You are passing strings there, not variables.

    page.querySelector(‘ons-toolbar .center’).innerHTML = nama;

    That nama variable does not exist in that scope. Perhaps you mean page.data.nama?



  • @Fran-Diox said:

    @dvlwjoffice said:

    {data: {ID: ‘id’,nama: ‘nama’}}

    You are passing strings there, not variables.

    page.querySelector(‘ons-toolbar .center’).innerHTML = nama;

    That nama variable does not exist in that scope. Perhaps you mean page.data.nama?

    err, so how? i fetched the data from JSON to make a list, and every list have their id and nama like in my JSON format, do me need to make a variable just for it ? sorry i am a little bit new to JavaScript.

    and why page.data.nama ? from where its come? i want to rename the title based on the data passed from pushpage (that {data: {ID: 'id',nama: 'nama'}}).

    Can you explain it to me? Thanks.

    edit : its work, but i still doesn’t understand about that page.data.nama can you explain it for me? thanks


  • Onsen UI

    @dvlwjoffice

    its work, but i still doesn’t understand about that page.data.nama can you explain it for me? thanks

    I mentioned it before:

    The data object will be available as a property of the page element. In the init event, for example, you can check event.target.data and use it to set up the content.

    Therefore, event.target.data.nama is the value you are passing. Or var page = event.target; page.data.nama.

    For the other question, in your app you are doing this:

     $.each(result[0], function(index, el){
       var nama = el.nama;
    
       // ...   
       // on item click:
       document.querySelector('#coreNavigator').pushPage('harga.html', {data: {ID: 'id',nama: 'nama'}});
    

    This is the data object you are passing:

      data: {
        ID: 'id',
        nama: 'nama'
      }
    

    In JavaScript, the right parts of that object declaration are the values, and the left parts are the keys that you will use later on to access the values. However, here your values are strings, not variables. Every pushed page will get page.data.ID with value 'id' and page.data.nama with value 'nama'. I believe you want to pass a dynamic value, not just a static string. You had a nama variable in the code wrote before, so I’m guessing you want to pass that variable’s content to pages instead, so just remove the quotes:

      data: {
        ID: 'id',
        nama: nama
      }
    


  • @Fran-Diox Ahh, i see. Thanks for make a very great explanation just for me. I think this thread can closed now. Thank you very much !