Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional JS initializer scenarios #28492

Merged
merged 10 commits into from
Mar 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 100 additions & 38 deletions aspnetcore/blazor/components/event-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,32 +97,51 @@ Custom events with custom event arguments are generally enabled with the followi
}
```

1. Register the custom event with the preceding handler in `wwwroot/index.html` (Blazor WebAssembly) or `Pages/_Host.cshtml` (Blazor Server) immediately after the Blazor `<script>`:
1. Register the custom event with the preceding handler in a [JavaScript initializer](xref:blazor/fundamentals/startup#javascript-initializers).

```html
<script>
Blazor.registerCustomEventType('customevent', {
`wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js`:

```javascript
export function afterStarted(blazor) {
blazor.registerCustomEventType('customevent', {
createEventArgs: eventArgsCreator
});
</script>
}
```

In the preceding example, the `{PACKAGE ID/ASSEMBLY NAME}` placeholder of the file name represents the package ID or assembly name of the app.

> [!NOTE]
> The call to `registerCustomEventType` is performed in a script only once per event.
>
> For the call to `registerCustomEventType`, use the `blazor` parameter (lowercase `b`) provided by `afterStarted`. Although the registration is valid when using the `Blazor` object (uppercase `B`), the preferred approach is to use the parameter.

1. Define a class for the event arguments:

```csharp
namespace BlazorSample.CustomEvents;

public class CustomEventArgs : EventArgs
{
public string? CustomProperty1 {get; set;}
public string? CustomProperty2 {get; set;}
}
```

1. Wire up the custom event with the event arguments by adding an <xref:Microsoft.AspNetCore.Components.EventHandlerAttribute> attribute annotation for the custom event. The class doesn't require members. Note that the class *must* be called `EventHandlers` in order to be found by the Razor compiler, but you should put it in a namespace specific to your app:
1. Wire up the custom event with the event arguments by adding an <xref:Microsoft.AspNetCore.Components.EventHandlerAttribute> attribute annotation for the custom event:

* In order for the compiler to find the `[EventHandler]` class, it must be placed into a C# class file (`.cs`), making it a normal top-level class.
* Mark the class `public`.
* The class doesn't require members.
* The class *must* be called "`EventHandlers`" in order to be found by the Razor compiler.
* Place the class under a namespace specific to your app.
* Import the namespace into the Razor component (`.razor`) where the event is used.

```csharp
using Microsoft.AspNetCore.Components;

namespace BlazorSample.CustomEvents;

[EventHandler("oncustomevent", typeof(CustomEventArgs), enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
{
Expand All @@ -132,6 +151,8 @@ Custom events with custom event arguments are generally enabled with the followi
1. Register the event handler on one or more HTML elements. Access the data that was passed in from JavaScript in the delegate handler method:

```razor
@using namespace BlazorSample.CustomEvents

<button @oncustomevent="HandleCustomEvent">Handle</button>

@code
Expand Down Expand Up @@ -159,6 +180,10 @@ Declare a custom name (`oncustompaste`) for the event and a .NET class (`CustomP
`CustomEvents.cs`:

```csharp
using Microsoft.AspNetCore.Components;

namespace BlazorSample.CustomEvents;

[EventHandler("oncustompaste", typeof(CustomPasteEventArgs),
enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
Expand All @@ -172,24 +197,29 @@ public class CustomPasteEventArgs : EventArgs
}
```

Add JavaScript code to supply data for the <xref:System.EventArgs> subclass. In the `wwwroot/index.html` or `Pages/_Host.cshtml` file, add the following `<script>` tag and content immediately after the Blazor script. The following example only handles pasting text, but you could use arbitrary JavaScript APIs to deal with users pasting other types of data, such as images.
Add JavaScript code to supply data for the <xref:System.EventArgs> subclass with the preceding handler in a [JavaScript initializer](xref:blazor/fundamentals/startup#javascript-initializers). The following example only handles pasting text, but you could use arbitrary JavaScript APIs to deal with users pasting other types of data, such as images.

`wwwroot/index.html` (Blazor WebAssembly) or `Pages/_Host.cshtml` (Blazor Server) immediately after the Blazor script:
`wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js`:

```html
<script>
Blazor.registerCustomEventType('custompaste', {
browserEventName: 'paste',
createEventArgs: event => {
return {
eventTimestamp: new Date(),
pastedData: event.clipboardData.getData('text')
};
}
```javascript
export function afterStarted(blazor) {
blazor.registerCustomEventType('custompaste', {
browserEventName: 'paste',
createEventArgs: event => {
return {
eventTimestamp: new Date(),
pastedData: event.clipboardData.getData('text')
};
}
});
</script>
}
```

In the preceding example, the `{PACKAGE ID/ASSEMBLY NAME}` placeholder of the file name represents the package ID or assembly name of the app.

> [!NOTE]
> For the call to `registerCustomEventType`, use the `blazor` parameter (lowercase `b`) provided by `afterStarted`. Although the registration is valid when using the `Blazor` object (uppercase `B`), the preferred approach is to use the parameter.

The preceding code tells the browser that when a native [`paste`](https://developer.mozilla.org/docs/Web/API/Element/paste_event) event occurs:

* Raise a `custompaste` event.
Expand All @@ -208,6 +238,7 @@ In a Razor component, attach the custom handler to an element.

```razor
@page "/custom-paste-arguments"
@using BlazorSample.CustomEvents

<label>
Try pasting into the following text box:
Expand Down Expand Up @@ -434,32 +465,51 @@ Custom events with custom event arguments are generally enabled with the followi
}
```

1. Register the custom event with the preceding handler in `wwwroot/index.html` (Blazor WebAssembly) or `Pages/_Layout.cshtml` (Blazor Server) immediately after the Blazor `<script>`:
1. Register the custom event with the preceding handler in a [JavaScript initializer](xref:blazor/fundamentals/startup#javascript-initializers).

```html
<script>
Blazor.registerCustomEventType('customevent', {
`wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js`:

```javascript
export function afterStarted(blazor) {
blazor.registerCustomEventType('customevent', {
createEventArgs: eventArgsCreator
});
</script>
}
```

In the preceding example, the `{PACKAGE ID/ASSEMBLY NAME}` placeholder of the file name represents the package ID or assembly name of the app.

> [!NOTE]
> The call to `registerCustomEventType` is performed in a script only once per event.
>
> For the call to `registerCustomEventType`, use the `blazor` parameter (lowercase `b`) provided by `afterStarted`. Although the registration is valid when using the `Blazor` object (uppercase `B`), the preferred approach is to use the parameter.

1. Define a class for the event arguments:

```csharp
namespace BlazorSample.CustomEvents;

public class CustomEventArgs : EventArgs
{
public string? CustomProperty1 {get; set;}
public string? CustomProperty2 {get; set;}
}
```

1. Wire up the custom event with the event arguments by adding an <xref:Microsoft.AspNetCore.Components.EventHandlerAttribute> attribute annotation for the custom event. The class doesn't require members. Note that the class *must* be called `EventHandlers` in order to be found by the Razor compiler, but you should put it in a namespace specific to your app:
1. Wire up the custom event with the event arguments by adding an <xref:Microsoft.AspNetCore.Components.EventHandlerAttribute> attribute annotation for the custom event:

* In order for the compiler to find the `[EventHandler]` class, it must be placed into a C# class file (`.cs`), making it a normal top-level class.
* Mark the class `public`.
* The class doesn't require members.
* The class *must* be called "`EventHandlers`" in order to be found by the Razor compiler.
* Place the class under a namespace specific to your app.
* Import the namespace into the Razor component (`.razor`) where the event is used.

```csharp
using Microsoft.AspNetCore.Components;

namespace BlazorSample.CustomEvents;

[EventHandler("oncustomevent", typeof(CustomEventArgs), enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
{
Expand All @@ -469,6 +519,8 @@ Custom events with custom event arguments are generally enabled with the followi
1. Register the event handler on one or more HTML elements. Access the data that was passed in from JavaScript in the delegate handler method:

```razor
@using namespace BlazorSample.CustomEvents

<button @oncustomevent="HandleCustomEvent">Handle</button>

@code
Expand Down Expand Up @@ -496,6 +548,10 @@ Declare a custom name (`oncustompaste`) for the event and a .NET class (`CustomP
`CustomEvents.cs`:

```csharp
using Microsoft.AspNetCore.Components;

namespace BlazorSample.CustomEvents;

[EventHandler("oncustompaste", typeof(CustomPasteEventArgs),
enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
Expand All @@ -509,24 +565,29 @@ public class CustomPasteEventArgs : EventArgs
}
```

Add JavaScript code to supply data for the <xref:System.EventArgs> subclass. In the `wwwroot/index.html` or `Pages/_Layout.cshtml` file, add the following `<script>` tag and content immediately after the Blazor script. The following example only handles pasting text, but you could use arbitrary JavaScript APIs to deal with users pasting other types of data, such as images.
Add JavaScript code to supply data for the <xref:System.EventArgs> subclass with the preceding handler in a [JavaScript initializer](xref:blazor/fundamentals/startup#javascript-initializers). The following example only handles pasting text, but you could use arbitrary JavaScript APIs to deal with users pasting other types of data, such as images.

`wwwroot/index.html` (Blazor WebAssembly) or `Pages/_Layout.cshtml` (Blazor Server) immediately after the Blazor script:
`wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js`:

```html
<script>
Blazor.registerCustomEventType('custompaste', {
browserEventName: 'paste',
createEventArgs: event => {
return {
eventTimestamp: new Date(),
pastedData: event.clipboardData.getData('text')
};
}
```javascript
export function afterStarted(blazor) {
blazor.registerCustomEventType('custompaste', {
browserEventName: 'paste',
createEventArgs: event => {
return {
eventTimestamp: new Date(),
pastedData: event.clipboardData.getData('text')
};
}
});
</script>
}
```

In the preceding example, the `{PACKAGE ID/ASSEMBLY NAME}` placeholder of the file name represents the package ID or assembly name of the app.

> [!NOTE]
> For the call to `registerCustomEventType`, use the `blazor` parameter (lowercase `b`) provided by `afterStarted`. Although the registration is valid when using the `Blazor` object (uppercase `B`), the preferred approach is to use the parameter.

The preceding code tells the browser that when a native [`paste`](https://developer.mozilla.org/docs/Web/API/Element/paste_event) event occurs:

* Raise a `custompaste` event.
Expand All @@ -545,6 +606,7 @@ In a Razor component, attach the custom handler to an element.

```razor
@page "/custom-paste-arguments"
@using BlazorSample.CustomEvents

<label>
Try pasting into the following text box:
Expand Down
28 changes: 28 additions & 0 deletions aspnetcore/blazor/components/js-spa-frameworks.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,34 @@ Quote &copy;1988-1999 Satellite of Love LLC: [*Mystery Science Theater 3000*](ht
> rootComponent.dispose();
> ```

The preceding example dynamically renders the root component when the `showQuote()` JS function is called. To render a root component into a container element when Blazor starts, use a [JavaScript initializer](xref:blazor/fundamentals/startup#javascript-initializers) to render the component, as the following example demonstrates.

The following example builds on the preceding example, using the `Quote` component, the root component registration in `Program.cs`, and the initialization of `jsComponentInitializers.js`. The `showQuote()` function (and the `script.js` file) aren't used.

In HTML, place the target container element, `quoteContainer2` for this example:

```html
<div id="quoteContainer2"></div>
```

Using a [JavaScript initializer](xref:blazor/fundamentals/startup#javascript-initializers), add the root component to the target container element.

`wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js`:

```javascript
export function afterStarted(blazor) {
let targetElement = document.getElementById('quoteContainer2');
blazor.rootComponents.add(targetElement, 'quote',
{
text: "Crow: I have my doubts that this movie is actually 'starring' " +
"anybody. More like, 'camera is generally pointed at.'"
});
}
```

> [!NOTE]
> For the call to `rootComponents.add`, use the `blazor` parameter (lowercase `b`) provided by `afterStarted`. Although the registration is valid when using the `Blazor` object (uppercase `B`), the preferred approach is to use the parameter.

For an advanced example with additional features, see the example in the `BasicTestApp` of the ASP.NET Core reference source (`dotnet/aspnetcore` GitHub repository):

* [`JavaScriptRootComponents.razor`](https://github.com/dotnet/aspnetcore/blob/main/src/Components/test/testassets/BasicTestApp/JavaScriptRootComponents.razor)
Expand Down
Loading