Simulation Development

Custom Scripts

It is possible to write JavaScript in the slide. You will have full access to h:slide's functionality. You can get and set slide & model properties; and create and invoke functions. Custom Scripts are useful when you need a helper function on a slide but do not want to have to build up your own Action to do so.

Declaring a script

The best way to declare a script is as follows:

<script>
    (function (slide) {
        CONTENT HERE...
    }(this));
</script>

The keyword this is in reference to the slide. All code would be placed inside this closure.

Declaring local variables and functions

<script>
    (function (slide) {
        var name = 'John';

        function sum(a, b) {
            return a + b;
        }
    }(this));
</script>

Variables and functions you plan on using internally are declared with the var and function declaratives. Just make sure all your code resides inside the closure.

Working with slide properties

<script>
    (function (slide) {
        // get slide property
        var name = slide.val("name");

        ...

        // set slide property
        slide.val("name", "Jane");
    }(this));
</script>

Slides provides a val(key:String, value:*) function you can use to get and set properties on your slide. Using this function is equivalent to using h:set in h:function.

Working with model properties

<script>
    (function (slide) {
        // get model property
        var name = slide.val("models/app::name");

        ...

        // set model property
        slide.val("models/app::name", "Jane");
    }(this));
</script>

The val(key:String, value:*) function also supports model property syntax as you would define in XML tags.

Working with slide functions

<script>
    (function (slide) {
        // declare a function
        slide.func("sendMessage", function(evt, name, message){
            ...
        });

        ...

        // call a function
       var sendMessage = slide.func("sendMessage");
       sendMessage("Jane", "Hello, world!");
    }(this));
</script>

Slides provides the func(name:String, fn:Function) function to declare functions on the slide. Functions are only available on the slide and cannot be inherited.

Working with commands

<script>
    (function (slide) {
        // declare a command
        slide.command("commands/office::save", function(evt, targetSlide, data){
            ...
        });

        ...

        // call a command
       slide.exec("commands/office::save", {
            filename: 'Document1',
            data: {...}
       });
    }(this));
</script>

It is possible to declare commands in a slide. Since commands are event handlers, they receive the event that was dispatched, the target slide that invoked the command and any data as the payload to use in the command.

Working with external libraries

<script>

    // this example assumes we have included underscore.js

    (function (slide) {
        // declare a function
        slide.func("getLast", function(evt, list){
            _.last(list); // => returns last item in array
        });
    }(this));
</script>

In this example, you can see that using libraries you import work the same as in other environments.

timer Exercise: Convert h:virtual to using script

In this exercise we are going to convert everything in h:virtual to using script. This will help you see how the same thing can be achieved using code.

Launch in your browser http://localhost:8080/sandbox/#/tutorials/scripts/scripts_start. It should open a page with "Custom Scripts Tutorial" displayed.

Open sandbox/slides/tutorials/scripts/scripts_start.html in seed-exam in your editor. If you click on the button it will display an alert.

We are going to focus on the h:virtual section which currently looks like this:

<h:virtual>
    <h:properties>
        <message>Hello, world!</message>
    </h:properties>

    <h:function name="send" args="name, message">
        <h:exec command="commands/chat::send">
            {
            name: "{{name}}",
            message: "{{message}}"
            }
        </h:exec>
    </h:function>
</h:virtual>

As you look at the code above, you will see there is a property declared and a function that executes a command. We replace each one at a time.

First, let's create a script tag.

<script>
    (function (slide) {

    }(this));
</script>

Let's declare the property in our code.

<script>
    (function (slide) {
        slide.val("message", "Hello, world!");
    }(this));
</script>

Now, lets convert the function to a JavaScript function...

<script>
    (function (slide) {
        slide.val("message", "Hello, world!");

        slide.func("send", function(name, message) {

        });
    }(this));
</script>

At this point, we are ready to invoke a command...

<script>
    (function (slide) {
        slide.val("message", "Hello, world!");

        slide.func("send", function(name, message) {
            slide.exec("commands/chat::send", {
                name: name,
                message: message
            });
        });
    }(this));
</script>

You are now ready to remove the h:virtual tag and its content. Refresh the page and it should work as it did before when you click on the buttton.