UI adding new elements timing problem

Trying to use the UI demo.
Works well on its own but if I try to add elements - looks like its trying to add them in prototype.initialize before main elements created - so getting nulls.
How do I ensure proper delay until html has been created - or am I misreading the problem ?

Here’s the demo that illustrates the problem

It’s the order of calls that is an issue here. You have a dependency that the initialise function is called on one script before another.

You shouldn’t really do this as it’s pretty difficult to guarantee what gets called first during development. Someone may move the entities in a different order for example that affects the order of calls.

To get around this somewhat is either have script/logic in place that manages the UI explicitly and therefore you can at least control the order of the events in one place or use postInitialise which gets called after initialise.

GUI.prototype.postInitialize = function() {
    var sel_list = ['Physics', 'Maths', 'Chemistry'];
    var test = document.getElementById('fac_list'); // getting a null here
    var ul = document.createElement('ul');
    test.appendChild(ul);
    //
    for (var i = 0; i < cars.length; i++) {
        var li = document.createElement('li');

        ul.appendChild(li);
        li.innerHTML = li.innerHTML + cars[i];
    }
};

Ahh thanks for the postInitialize() tip. Alas it doesn’t work in this particular case either. (link updated)
So that means managing it myself.

Am I to assume the “right way” is to check in the update(dt) function and if the element exists then call a function to build the UI?
Means a little extra overhead every frame but if there is no way to detect if the page is loaded, or a function to defer until the page is loaded, then this might be the right way to do it.??

OK. I amended the example to now work.
It tests each update(dt) to see if the html object is there.

Although it now works. I’d very much appreciate finding out if there is a better way to do this ?

GUI.prototype.Initialize = function() {
    var faculties = [];
};
GUI.prototype.update = function(dt) {
    this.faculties = document.getElementById('fac_list'); // getting a null here
    if (this.faculties) {
        // it exists so if it has no children then build them
        if (this.faculties.childElementCount === 0) {
            this.build_UI();
        }
        // rest of the update code goes in here
    }
};
GUI.prototype.build_UI = function() {
    var sel_list = ['Physics', 'Maths', 'Chemistry'];
    this.faculties = document.getElementById('fac_list'); // getting a null here
    var ul = document.createElement('ul');
    this.faculties.appendChild(ul);
    //
    for (var i = 0; i < sel_list.length; i++) {
        var li = document.createElement('li');

        ul.appendChild(li);
        li.innerHTML = li.innerHTML + sel_list[i];
    }
};

Looking over the sample, the actual HTML loading and adding to the document is done on the update call (or more specifically the template callback) and not the initialize function.

In this case, there are a couple of ways to solve this:

Ahh. brilliant. That explains a lot more about what’s going on.
The shape of the plain (not live update) code version is quite different.

I’m liking your this.app.fire('htmlhandler:retemplate'); event based solution very much. It adds only slightly to the code complexity but makes my gui.js much simpler.

Much appreciated.

Would it be worth trying to mod the existing UI example to work like this ?
What’s the process to get that to happen ?

Sorry, which UI example? And like ‘what’? :confused:

The UI sample project here:

I’m suggesting changing it to use your approach:

  • this.app.fire('htmlhandler:retemplate');

Specifically:
Changing html-Handler.js to be:

        this.bindEvents();
        this.app.fire('htmlhandler:retemplate'); // this line added
    }```
and adding a gui.js which added some html in exactly the way your fork did:
 - https://playcanvas.com/editor/scene/547602

If you are planning to do a lot of HTML and CSS work, yes I would recommend it as it’s useful to live update the UI while the app is running. Otherwise, use the other example project to keep things simple.