Calling JavaScript Functions From DotVVM With JS Directive

In this article you'll learn how to call JavaScript functions from DotVVM in ASP.NET, and vice versa, and how to use JS Directive when requesting two numbers from a web page, performing the operation in JavaScript, and displaying the results on that page.

What is JS Directive?

The JS directive is a feature set that provides a way to interact between DotVVM controls and JavaScript code. For example, with JS Directive we can call JavaScript functions from DotVVM, and send data from JavaScript to DotVVM.

Note
This functionality was incorporated into DotVVM 3.0.

Steps to follow,

In order to establish a communication between DotVVM and JavaScript, these are the steps we must follow:

  • Declare a JavaScript module with its respective functions.
  • Register that module in DotVVM Startup.
  • Import the module declared in our DotVVM views.
  • Let's get to work! Call JavaScript functions from DotVVM, or receive data.

Example

To see how JS Directive works in an example, let's follow the steps mentioned above to request two numbers from the user, call a JavaScript function that performs that operation, and finally display the result on the web page.

Our example would be visualized as follows,

Calling JavaScript functions from DotVVM with JS Directive

The first thing we must have is the JavaScript module with its corresponding functions, in this case, we have a file called JavaScript.js located in the wwwroot folder with the following definitions,

export default (contextApp) => new App(contextApp);
var WEB;
class App {
    constructor(contextApp) {
        this.contextApp = contextApp;
        WEB = contextApp;
    }
    operation(a, b) {
        let result = a + b;
        WEB.namedCommands["ResultOperation"](result);
    }
}

Here the operation function will be in charge of performing the sum and then put the result in the ResultOperation section defined in a view with DotVVVM.

With this App class, and its defined context, we can now register it in DotVVM to be able to make calls from DotVVM to JavaScript, and vice versa. In this sense, we must go to the DotVVM Startup class, and in the ConfigureResources method refers to the JavaScript file and name this record (in this case the name will be module):

private void ConfigureResources(DotvvmConfiguration config, string applicationPath) {
    //JS Directive
    config.Resources.Register("module", new ScriptModuleResource(new UrlResourceLocation("~/JavaScript.js")) {
        //Dependencies = new[] { "external/other-js-file" }
    });
}

With this definition, we can already use JS Directive. For the sum of the two numbers, we will define three variables in the ViewModel (in this case in the DefaultViewModel.cs):

@viewModel JSDirective.ViewModels.DefaultViewModel, JSDirective
@masterPage Views/MasterPage.dotmaster
@js module

<dot:Content ContentPlaceHolderID="MainContent">
    <div class="content">
        <div class="content__text">
            <h1>JS Directive Demo</h1>
            <h3>Add two numbers</h3>

            <ul class="content-page">
                <li><b>Number1: </b></li>
                <li><dot:TextBox Text="{value: Number1}" Type="Number" /></li>
                <li><b>Number2: </b></li>
                <li><dot:TextBox Text="{value: Number2}" Type="Number" /></li>
            </ul>

            <dot:Button Text="Calculate"
                        Click="{staticCommand:_js.Invoke("operation", Number1, Number2);}" />

            <dot:NamedCommand Name="ResultOperation" Command="{staticCommand: (int id) => _root.Result = id}" />
            <h3>Result: <b>{{value: Result}}</b></h3>
        </div>
    </div>
</dot:Content>

In this view, it is necessary to refer to the JavaScript module that we want to use, in this case, we can reference it with the identifier js, with the name of the module previously registered:

@js module

Then, in this view we can mention three important things,

  • To set the two numbers to add, two DotVVM controls of type TextBox have been used.
  • To call the JavaScript function we can do it with a Button, specifying the name of the function, and sending the respective parameters (Number1, and Number2).
  • The NamedCommand control allows us to invoke commands from JavaScript, in this case, a section has been defined with the name ResultOperation, to send the value of the operation from JavaScript and save it in the variable Result (defined in the ViewModel from DotVVM).

With this process, we have been able to call JavaScript functions from DotVVM and send values from JavaScript to DotVVM.

The full JS Directive documentation can be reviewed from the documentation in DotVVM: JS directive overview.

Thanks for reading

Thank you very much for reading, I hope you found this article interesting and that it may be useful in the future.

The source code for this example can be found in the following repository on GitHub: DotVVM JS Directive.

If you have any questions or ideas that you need to discuss, it will be a pleasure to be able to collaborate and together exchange knowledge with each other.

See you on Twitter! :)