Calling JavaScript functions from DotVVM with JS Directive
Tags: dotnet, html, javascript, csharp
Published: 2021-11-16 16:23:41

Hi! It's a pleasure to greet you. To learn how to call JavaScript functions from DotVVM in ASP.NET, and vice versa, in this tutorial article we will learn 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 for us 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:

![Web app example to add two numbers.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b3do5370hwupvttq5c14.png)

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:

```js
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 refer to the JavaScript file in question, and name this record (in this case the name will be `module`):

```csharp
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`):

```html
@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 the 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
@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](https://www.dotvvm.com/docs/3.0/pages/concepts/client-side-development/js-directive/overview
).

###**Thanks for reading** ###

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

The source code for this example can be found in the following repository on GitHub: [DotVVM JS Directive](https://github.com/esdanielgomez/DotVVMJSDirective).

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](https://twitter.com/esDanielGomez)! :)