Blazor Serverの初期プロジェクトに設けられているサンプルのボタンは、submitするボタンなので、それを元に画面にボタンを追加して行くと、追加した全てのボタンがsubmitしてしまい、submitするボタン/submitしないボタン、どちらも画面に設けたい場合にハマるという事が起こりがちです。
submitボタン、通常ボタン、リンクボタンの実装を比較できるようにサンプルを作成しました。
ソースコードはGitHubで公開しています。
ボタンのパターンについて
submitボタン
・submit時に<ValidationMessage><ValidationSummary>が実行される。
・<button>に type=”submit” を設定するとsubmitする。
・typeを何も設定していない場合、デフォルトでsubmitする。
・@onclickイベントハンドラを加えると、submitとイベントハンドラの両方が実行される。
1 2 3 4 5 |
<button type="submit" class="btn btn-min btn-primary">Submitするボタン</button> <button class="btn btn-min btn-primary">Submitするボタン</button> <button class="btn btn-primary" @onclick="IncrementCount">Submitとonclickイベント両行するボタン</button> |
submitしない通常ボタン
・<button>に type=”button” を設定するとsubmitしなくなる。
・@onclickイベントハンドラは実行される。
1 2 3 |
<button type="button" class="btn btn-primary" @onclick="IncrementCount">onclickイベントのみするボタン</button> |
リンクボタン
・<a>リンクタグの見た目をボタン化したもの。
・<a>に target=”_blank” を設定することで、簡単に遷移先URLを別タブで開くボタンを実装できる。
1 2 3 |
<a class="btn btn-primary py-1" href="https://www.google.co.jp/" target="_blank">リンク先を別タブで開くボタン</a> |
ソースコード構成
ソースコード変更内容を解説
Const/Message.cs
・Validationで表示するメッセージを定数として追加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace WebApplication1.Const { public static class Message { public const string RequiredErrorMessage = "{0}は必須です。"; } } |
Model/DataModel1.cs
・画面にBindするデータクラスを追加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; using WebApplication1.Const; namespace WebApplication1.Model { public class DataModel1 { [Display(Name = "入力欄A")] [Required(ErrorMessage = Message.RequiredErrorMessage)] public string InputA { get; set; } } } |
Pages/ButtonPattern.razor
・ボタンパターンを実装したサンプル画面を追加。
・submitで実行されるイベントハンドラはValidSubmit()、クリックで実行されるイベントハンドラはIncrementCount()にしています
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
@page "/ButtonPattern" <h1>Counter</h1> <p>Current count: @currentCount</p> <EditForm Model="@_DataModel1" OnValidSubmit="@ValidSubmit"> <DataAnnotationsValidator /> <ValidationMessage For="@(() => _DataModel1.InputA)" /> <div class="row"> <label class="col-auto col-form-label nowrap">入力欄A<font class="" color="red">*</font></label> <div class="form-group col-sm-2"> <input type="text" class="form-control" @bind="_DataModel1.InputA" /> </div> </div> <br> <button type="submit" class="btn btn-min btn-primary">Submitするボタン</button><br><br> <button class="btn btn-primary" @onclick="IncrementCount">Submitとonclickイベント両行するボタン</button><br><br> <button type="button" class="btn btn-primary" @onclick="IncrementCount">onclickイベントのみするボタン</button><br><br> <a class="btn btn-primary py-1" href="https://www.google.co.jp/" target="_blank">リンク先を別タブで開くボタン</a> </EditForm> @code { private DataModel1 _DataModel1 = new DataModel1(); private int currentCount = 0; private void IncrementCount() { currentCount++; } private async Task ValidSubmit() { currentCount++; } } |
Shared/NavMenu.razor
・サンプル画面へのリンクを追加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<div class="top-row pl-4 navbar navbar-dark"> <a class="navbar-brand" href="">WebApplication1</a> <button class="navbar-toggler" @onclick="ToggleNavMenu"> <span class="navbar-toggler-icon"></span> </button> </div> <div class="@NavMenuCssClass" @onclick="ToggleNavMenu"> <ul class="nav flex-column"> <li class="nav-item px-3"> <NavLink class="nav-link" href="" Match="NavLinkMatch.All"> <span class="oi oi-home" aria-hidden="true"></span> Home </NavLink> </li> <li class="nav-item px-3"> <NavLink class="nav-link" href="counter"> <span class="oi oi-plus" aria-hidden="true"></span> Counter </NavLink> </li> <li class="nav-item px-3"> <NavLink class="nav-link" href="fetchdata"> <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data </NavLink> </li> <li class="nav-item px-3"> <NavLink class="nav-link" href="ButtonPattern"> <span class="oi oi-list-rich" aria-hidden="true"></span> Button pattern </NavLink> </li> ButtonPattern </ul> </div> @code { private bool collapseNavMenu = true; private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; private void ToggleNavMenu() { collapseNavMenu = !collapseNavMenu; } } |
_Imports.razor
・データクラスへの参照を追加。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@using System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using WebApplication1 @using WebApplication1.Shared @using WebApplication1.Model |
コメント