Stuck writing data to details page via JavaScript



  • I’ve got a list page working and can click on an item and open up the details page.

    In my controller file I use ajax to retrieve the data based on the item selected. This is working ok and I can retrieve data. The problem I’m stuck on is how to write my data out the page.

    I have this javascript to produce the toolbar:

                    var onsContact = document.createElement("ons-toolbar");
                    onsContact.setAttribute('modifier', "material");
                    onsContact.setAttribute('modifier', "contact-interface");
                    onsContact.innerHTML = 
                    '<div class="left">'
                    +'<ons-back-button>Back</ons-back-button>'
                    +'</div>'
                    + '<div class="center">' + data.displayName + '</div>'
                    + '';
                            document.getElementById('contactPage').appendChild(onsContact);
    

    What I’m struggling with then is to add a further div to the page where I can write out the item data. What I’m trying to do is document.createElement(‘div’) and set its innerHtml and then call the appendChild on the page again with the new item - just like in the above code. Unfortunately, it’s not working. It seems to display briefly when I press the back button. I’m sure what I’m doing isn’t right. Can anyone point me in the right direction?


  • Onsen UI

    @sc Just to make sure, you are not using Angular or any other framework, right?

    That looks like a correct way to do it. When and where are you appending the new element, to the current page or the previous one? Can you share that part of the code?



  • Thanks for the reply Fran. Here is more code where I try to append a div to the page. I’m sure I’m doing something stupid.

        contactPage: function(page) {
    
              jsonp(myApp.appServerUrl + '/rest/getPerson/' + myApp.selectedContact, function(data) {
                  
                    var photo = myApp.photoUrl + '/' + myApp.selectedContact.toLowerCase() + '.jpg';
    
                    var onsContact = document.createElement("ons-toolbar");
                        onsContact.setAttribute('modifier', "material");
                        onsContact.setAttribute('modifier', "contact-interface");
                        onsContact.innerHTML = 
                        '<div class="left">'
                        +'<ons-back-button>Back</ons-back-button>'
                        +'</div>'
                        + '<div class="center">' + data.displayName + '</div>'
                        + '';
                        
                        document.getElementById('contactPage').appendChild(onsContact);
                            
                    // Here I am trying to display a photo and a few details below the toolbar      
                    var div = document.createElement('div');
                        div.innerHTML = '<img src="' + photo + '" class="profile-image">'
                        +'<div class="profile-name">Dave Graham</div>'
                        +'<div class="profile-id">@davegraham</div>'
                        +'<div class="profile-desc">Freelance designer, software engineer and cyclist</div>';
                    
                        document.getElementById('contactPage').appendChild(div);                        
                        
                });
        },
        
        
        function jsonp(url, callback) {
            var callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());
            window[callbackName] = function(data) {
                delete window[callbackName];
                document.body.removeChild(script);
                callback(data);
            };
    
            var script = document.createElement('script');
            script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + callbackName;
            document.body.appendChild(script);
        }
    
    Thanks
    S
    


  • Wonder if it’s because I haven’t defined any class definition for the div and it’s randomly writing the data somewhere.

    Going to try a setAttribute on the div.



  • @Fran-Diox

    is angular not working with onsen???..

    when you stated up there that…(just to be sure he is not using angular).

    #curious.



  • No, I am using pure JavaScript and not using Angular at all. I think that’s why I’m struggling a bit since I’ve used jQuery for too long.



  • @meshileya There are no issues with Angular and Onsen, the concern in replying to answers without knowing all the frameworks is you could be giving wrong information. For instance, it may be how the elements are compiled in Angular vs Vanilla. @Fran-Diox , I believe, was just trying to determine the platform being used so he could best give an answer.


  • Onsen UI

    @meshileya @munsterlander Exactly, answers may vary depending on the used framework.

    @sc For the toolbar, I just thought that maybe there is some internal compilation problem with that approach. Try it this way:

    var div = document.createElement('div');
    div.innerHTML = 
      '<ons-toolbar>'
      + '<div class="left">'
      + '<ons-back-button>Back</ons-back-button>'
      + '</div>'
      + '<div class="center">' + data.displayName + '</div>'
      + '</ons-toolbar>';
    
    var toolbar = div.firstChild;
    

    The next div is probably correct, although I don’t know what is #contactPage element and when are you calling all of that :/



  • I would guess that the problem is not in the actual creation of the elements, but rather the place where they are being appended.

    A page in Onsen UI is supposed to have the following structure:

    <ons-page>
        <ons-toolbar></ons-toolbar>
        <div class="page__background"></div>
        <div class="page__content"></div>
    </ons-page>
    

    Generally if you just have some content inside your page when it becomes created it will ensure this structure (putting all non-toolbars in the content div).

    Most likely your code is executed after this point and you’re trying to add content to the page itself, so it’s there but it just remains hidden would be my guess.

    Probably #contactPage is the ons-page element and the code is executed on init event. As @Fran-Diox mentioned - make sure this code is being executed. (the event should be init, not pageinit).

    @sc if you want you could try adding the two extra divs yourself and later appending to .page__content. You could also inspect the dom to see what is happening exactly (right clickinspect element).



  • @Fran-Diox @IliaSky I think you are both right.

    #contactPage is the ons-page element and the code is executed on init event.

    My template is defined as:

        <ons-template id="contact.html">
         <ons-page id="contactPage"> 
         </ons-page>
        </ons-template>
    

    I’ve now updated my javascript code in my init handler to create the toolbar and a div all in one go as @Fran-Diox suggested:

                    var div = document.createElement('div');
                    div.innerHTML = 
                      '<ons-toolbar>'
                      + '<div class="left">'
                      + '<ons-back-button>Back</ons-back-button>'
                      + '</div>'
                      + '<div class="center">' + data.displayName + '</div>'
                      + '</ons-toolbar>'
                    
                    + '<div class="page__content"><img src="' + photo + '" class="profile-image">'
                    + '<div class="profile-name">Dave Graham</div>'
                    + '<div class="profile-id">@davegraham</div>'
                    + '<div class="profile-desc">Freelance designer, software engineer and cyclist</div></div>';
                    
                    document.getElementById('contactPage').appendChild(div);
    

    Seems like I also had to give my div a class of “page__content” as @IliaSky suggested to get the details to appear below the toolbar.

    Just got two other minor problems now:

    • When I click my back button, the contact detail page sits over the top of my listing page for a brief second and then disappears.
    • I need a spinning wait icon while the page loads. Just seen the loading message documentation.


  • Thought I’d got the mechanism of dynamically drawing some detail to an Onsen page using javascript working. However, I still have the problem when I click the back button in mytoolbar that the list page appears to slide in behind the details page and it stays there briefly until it disappears. Thought it might be something to do with the back button behaviour, but I thinking that it looks like the “page” I’ve drawn is perhaps not within the Onsen page I thought it was, if that makes sense, and it’s perhaps floating over the top of the page that’s coming in as a result of the clicking back.

    I’m using Onsen 2 with javascript.

    My init method for the details page is:

        contactPage: function(page) {
    
              // Make an ajax call to retrieve the person data
              jsonp(myApp.appServerUrl + '/rest/getPerson/' + myApp.selectedContact, function(data) {
                                  
                    var photo = myApp.photoUrl + '/' + myApp.selectedContact.toLowerCase() + '.jpg';
                    
                    var div = document.createElement('div');
                    div.innerHTML = 
                        // Create a toolbar
                        '<ons-toolbar>'
                        + '<div class="left">'
                        + '<ons-back-button>Back</ons-back-button>'
                        + '</div>'
                        + '<div class="center">' + data.displayName + '</div>'
                        + '</ons-toolbar>'
                    
                        // Create the page content
                        + '<div class="page__content">'
                        + '<div class="profile-card" style="margin-top: 20px;">'
                        + '<div class="image-cropper">'
                        + '<img src="' + photo + '" class="rounded">'
                        + '</div>'
                        + '<div class="profile-name">' + data.displayName + ' </div>'
                        + '<div class="profile-id">' + data.title + '</div>'
                        + '<div class="profile-desc">' + myApp.write(data.department) + '</div>'
                        + '</div>'
                        + '</div>';
                                    
                    document.getElementById('contactPage').appendChild(div);
                    
                    // Remove the spinner
                    var el = document.getElementById( 'wrapper' );
                    el.parentNode.removeChild( el );
    
                });
    
      },
    

    and in my html I have this page definition (all my pages are defined in one html file):

        <ons-template id="contacts.html">
         <ons-page id="contactsPage">
            <ons-toolbar>
              <div class="left">
                <ons-back-button>Back</ons-back-button>
              </div>
              <div class="center">CONTACTS</div>
            </ons-toolbar>
            
           <ons-list>
                #foreach ($contact in $personalContacts)
                   <ons-list-item modifier="chevron" data-logonId = "$contact.contactId">
                      <div class="left">
                        <img class="list__item__thumbnail" onerror='ImgError(this, #springUrl("/"))' src="$basepeopleThumbnailUrl/${contact.contactId.toLowerCase()}.jpg">
                      </div>
                      <div class="center"  class="test">
                        $!contact.name
                      </div>  
                     </ons-list-item>    
                #end        
            </ons-list>   
          </ons-page>
        </ons-template>
    
        <ons-template id="contact.html">
         <ons-page id="contactPage">  
         <div id="wrapper">
         <div class="wait-spinner">
             <ons-progress-circular indeterminate></ons-progress-circular>
         </div>
         </div>
         </ons-page>
        </ons-template>
    

    I’m just going to check the dom for the page to see where the page data is actually getting attached to, but has anyone got any ideas what might be wrong?



  • I think the problem is that my content is being attached at the wrong place.

    In the attached screenshot I can see the “page__content” div I created and also a “page__content” and “page__background” div that Onsen created. Presumably my dynamically generated code should be attached to the Onsen “page__content” div?

    I’ll try that.

    0_1466696638267_page-dom.png



  • Yes, that was the problem. I’ve changed my code to specifically write to the page__content div and it looks like it’s working. My init script now looks like:

        contactPage: function(page) {
    
              // Make an ajax call to retrieve the person data
              jsonp(myApp.appServerUrl + '/rest/getPerson/' + myApp.selectedContact, function(data) {
                                  
                    var photo = myApp.photoUrl + '/' + myApp.selectedContact.toLowerCase() + '.jpg';
                    
                    var div = document.createElement('div');
                    div.innerHTML = 
                        // Create a toolbar
                        '<ons-toolbar>'
                        + '<div class="left">'
                        + '<ons-back-button>Back</ons-back-button>'
                        + '</div>'
                        + '<div class="center">' + data.displayName + '</div>'
                        + '</ons-toolbar>';
                            
                    document.getElementById('contactPage').appendChild(div);
                    
                    div = document.createElement('div');
                    div.innerHTML = 
                        // Create the page content
                        '<div class="profile-card" style="margin-top: 20px;">'
                        + '<div class="image-cropper">'
                        + '<img src="' + photo + '" class="rounded">'
                        + '</div>'
                        + '<div class="profile-name">' + data.displayName + ' </div>'
                        + '<div class="profile-id">' + data.title + '</div>'
                        + '<div class="profile-desc">' + myApp.write(data.department) + '</div>'
                        + '</div>';         
                    //document.getElementById('contactPage .page__content').appendChild(div);
                    
                    var el = document.getElementById('contactPage');
                    el.getElementsByClassName('page__content')[0].appendChild(div);
                    
                    // Remove the spinner
                    el = document.getElementById( 'wrapper' );
                    el.parentNode.removeChild( el );
    
                });
    
      },
    

  • Onsen UI

    @sc Yes, I think you misunderstood what @IliaSky said. He meant that an ons-page, after compiling, has a .page__content element by default. You don’t need to add your own but to append things to the existing one :)
    Glad you could solve it!



  • Got there eventually :smile:


Log in to reply