Using onLoad function

I have an app that I am currently rewriting, and it has a clock in it that loads a function startclock on <body onload="startclock()">.

I cannot figure out how to get the code to execute.

I have tried the following:

<script type="text/javascript">
        $(document).ready(function() {
            console.log('ready');
            setTimeout('startclock()', 1000);
        })

        window.onload = startclock();

    </script>

and

<div onload="startclock()">

and

<div load.delegate="startclock()">

None of them run the code.

What am I missing?

Thanks.

1 Like

when you do

<body onload="startclock()">

the startclock function needs to be accessible on global scope. Means you can do window.startclock = () => {...}

when you do

<div load.delegate="startclock()">

startclock needs to be accessible from bound view model. Though I’m not sure if it fires load on <div/>

Also, keep in mind that if you declare the function after load event has been fired, it won’t matter either.

Since this is some code that starts as your app comes up I feel the best place would be to put that code in your app.js/ts file inside the attached hook where you can be assured that the app is loaded and running plus the DOM is already rendered

1 Like

I can’t use it in app.js because it needs to load after I get customer information from an Ajax call. That was why I was trying it on the div tag.

My customer.html has this tag in it that I was trying to use as well:

 <template if.bind="customerRecord">
                <div class="tab-content">
                    <div id="customer_view" load.delegate="startclock()" 

Is there any way to attach it to this view instead of app?

1 Like

So why can’t you just call the function in then of your completed ajax request? Or the respective completed callback when using jQuery, or does this request happen outside of your control, e.g third party library?

1 Like

That’s a great idea. I don’t know why I didn’t think of that…

I just tried it, and it’s running.

I do have one problem, though.

I’ve declared my clockspot like so:

<input type="text" name="clockspot" id="clockspot"
                                        size="11" style="background-color: #ffffcc; text-align: center;">

and I am calling this:

var spot = document.getElementById("clockspot");

But it is null every time I try to view the object. When I log what document is, I get the whole document, and I can see the clockspot inside of it.

But I don’t know why getElementById doesn’t work?

1 Like

I think I just answered my question.

Because I am running it in the promise’s then section, the body of the page is not loaded.

So therefore, clockspot does not exist.

So I’m still stuck as to when to run clockspot.

1 Like

Ok. I have a workaround that is almost working.

I decided to do a hidden input element with the id ‘clockspot’, and then made startClock() async.

I have the following code inserted into the then part of my promise:

if (this.dbtr)
                  {
                    console.log('starting clock');
                    await self.startClock();
                  }

my startClock function:

    startClock()
      {
        var spot = document.getElementById("clockspot");

        //console.log( 'document', document );
        console.log( 'spot', spot);

        if (!spot)  return;
        
        var offset = 0;
        
        if (this.dbtr)
        {
          offset = this.dbtr.tz_offset;
        }
        
        

             var t = new Date();
             t.setHours(t.getHours() + offset);
             t.setMinutes(t.getMinutes() + ((offset - offset) * 60));
        
             var suffix = ' AM';
             var h = t.getHours();
             if (h == 12) {
                 suffix = ' PM';
             }
             else if (h > 12) {
                 suffix = ' PM';
                 t.setHours(h - 12);
             }
            var str = t.toTimeString().substr(0, 8);
            spot.value = str + suffix;
       
            if ((suffix == ' AM' && (h >= 1 && h < 8)) ||
                (suffix == ' PM' && (h > 8 && h <= 11))) {
                spot.style.backgroundColor = '#ff8888';
            } else {
                spot.style.backgroundColor = '#ffffcc';
            }
       
            console.log('setTimeout');

            window.setTimeout('startClock()', 1000);      
      }

I get the following error:

RangeError: Maximum call stack size exceeded
1 Like

Well you can’t access anything before it’s rendered to the DOM which is why I mentioned the attached hook that ensures that.

Where and how do you define your clockspot input? Is it inside an Aurelia custom element? If so than inside it’s attached it will be available. As for your ajax call, just store its promise in a property and inside the attached handler wait until it’s completed by adding the then block there.

1 Like

I have the clockspot defined inside a template tag.

And I was able to get it working by doing the following in my startClock() function:

window.setTimeout(function () { self.startClock(); }, 1000);

It was trying to access startClock before it was ready is my guess?

But it’s now displaying and updating itself properly.

Thanks for all the help.

I did move the promise return into its own variable, that way I can access part of it inside the startClock function.

1 Like

Well yeah the timeout is going to help since within that 1000 it hopefully will be rendered. Not the overall best solution but it seems to get the job done for you which is what matters :wink:

2 Likes