This example builds on the previous example to build a slideshow control.

Click on the Source Markup button above to see the full script for the control.

Here's notes on how the script works:

getTagName()

We override getTagName, this time to return "img" - we want the slideshow control to generate a <img> tag on the page:

    #method getTagName() { return 'img'; }
    

onFirstRender()

The onFirstRender() method is called the first time a control is rendered on the page. Overriding this method is a useful place to do initialization work just before the first render.

In this case, for good form we first call the Control base class's onFirstRender() method, then we set imageIndex to 0 and call autoAdvance to start advancing the images.

    #method onFirstRender() {
        #call Control.onFirstRender();

        this.imageIndex = 0; 

        this.autoAdvance();
    }
    

onSetValue()

Slideshow overrides onSetValue to listen for changes to the ID_imageUrls property - if someone sets imageUrls, we call advance, ensuring that we start to see the new images immediately:

    #method onSetValue(idname, oldVal, newVal, sender) {
        if (idname == ID_imageUrls) {
            this.advance();
        }
        #call Control.onSetValue(idname, oldVal, newVal, sender);
    }
    

advance()

The advance() method does the work of obtaining an image URL from the list and setting it as the "src" attribute of the image:

    #method advance() {
        var imageUrls = this.getValue(ID_imageUrls);
        if (imageUrls == null) { return; }            

        var n = imageUrls.getLength();
        var i = (this.imageIndex++) % n;
        var imageUrl = imageUrls.getValue(i);

        this.setValue("@src", imageUrl);
    }
    

First, we obtain the image list, returning if it is null:

        var imageUrls = this.getValue(ID_imageUrls);
        if (imageUrls == null) { return; }            
    

These next three lines:

        var n = imageUrls.getLength();
        var i = (this.imageIndex++) % n;
        var imageUrl = imageUrls.getValue(i);
    

Calculate which image in the list to show. After executing these lines, imageUrl should be set to the url string of the next image to show. Notice that we increment imageIndex using (this.imageIndex++) - each time you call advance() it moves to the next image.

Then, we use setValue to set the "@src" attribute on ourselves:

    
        this.setValue("@src", imageUrl);
    

In Jitsu, if you call setValue on a control with a property name that starts with an "@" prefix, Jitsu automatically sets the corresponding attribute on the control's peer in the DOM - in this case, it sets the "src" attribute on the <img> tag in the DOM. See Control.setValue() for more details.

autoAdvance()

    #method autoAdvance() {

        this.advance();
        
        var delayMillis = this.getValue(ID_delay);
        if (delayMillis == null) delayMillis = 1000;

        var del = new Delegate(this, this.autoAdvance);
        del.invokeAfter(delayMillis);
    }
    

The autoAdvance() method simply calls advance(), then waits for a while, then calls advance() again.

These two lines determine how long to delay for, in milliseconds:

        var delayMillis = this.getValue(ID_delay);
        if (delayMillis == null) delayMillis = 1000;
    

Lastly, we use a nify feature of the Delegate class: The Delegate.invokeAfter() method.

        var del = new Delegate(this, this.autoAdvance);
        del.invokeAfter(delayMillis);
    

These two lines construct a delegate referring to this control's autoAdvance method, and then tell the delegate to invoke autoAdvance() after a delay of delayMillis - a very easy asynchronous notification mechanism.

Why not use setTimeout?

JavaScript applications typically use setTimeout function to call methods asynchronously. However, setTimeout requires that you pass it a string as a script - and doing this prevents the code from working with the Jitsu cruncher .

If you want your application to work with the cruncher, use delegate's invokeAfter mechanism rather than setTimeout. See here for more details.]