LoginSignup
28
41

More than 5 years have passed since last update.

複数ボタンのあるFormで押されたボタンを判断する

Last updated at Posted at 2017-02-03

判断方法

  • ボタンにname属性を利用して、モデルバインディングで取得する。
  • JavaScriptでResponsデータを操作する。
  • セレクター属性を作成し、必要なアクションにそのセレクター属性を設定する。

2番目のJavaScriptによる方法については、個人的には利用しないので説明しません。

ボタンにname属性を利用する(nameがボタン毎に異なる場合)

ビューのコード
@using(Html.BeginForm())
{
    @Html.AntiForgeryToken();

    // テキストボックス等の入力項目の設定

    <input type="submit" name="Search" value="検索">
    <input type="submit" name="Clear" value="クリア">
}
コントローラーのコード
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(string search, string clear)
{
    if (search != null)
    {
        // 検索ボタンが押された場合の処理
    } 

    if (clear != null)
    {
        // クリアボタンが押された場合の処理
    } 
}
  • ActionResult Indexのパラメーター(search、clear)には、ボタンのvalue属性の値を受け取れます。 (searchボタンを押した場合は、パラメーターsearchに”検索”が入り、clearはブランクです。  clearボタンを押した場合は、パラメーターclearに”クリア”が入り、searchはブランクです。)
  • ・name属性とパラメーターで大文字、小文字の違いがあっても正常にモデルバインディングされます。

ボタンにname属性を利用する(nameが全てのボタンで同じ場合)

ビューのコード
@using(Html.BeginForm())
{
    @Html.AntiForgeryToken();

    // テキストボックス等の入力項目の設定

    <input type="submit" name="cmd" value="検索">
    <input type="submit" name="cmd" value="クリア">
}
コントローラーのコード
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(string cmd)
{
    if (cmd == "検索")
    {
        // 検索ボタンが押された場合の処理
    } 

    if (cmd == "クリア")
    {
        // クリアボタンが押された場合の処理
    } 

この方法ではValue属性が同一のボタンが複数ある場合は正しく認識できません。
(検索ボタンが2個ある場合など)

セレクター属性を作成する

この例では、ExtensionsフォルダにButtonAttributeクラスファイルを作成します。
(実際はどのフォルダでも問題ありません)

セレクター属性のコード
using System.Reflection;
using System.Web.Mvc;

namespace Project.Extensions
{
    public class ButtonAttribute : ActionMethodSelectorAttribute
    {
        // アクションメソッド付加時に設定したボタン名を保存
        public string ButtonName { get; set; }

        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
        {
            // 設定したボタン名と同名のデータが存在するかチェック(Requestで返ってきているか)
            return controllerContext.Controller.ValueProvider.GetValue(ButtonName) != null;
        }
    }
}
ビューのコード
@using(Html.BeginForm())
{
    @Html.AntiForgeryToken();

    // テキストボックス等の入力項目の設定

    <input type="submit" name="Search" value="検索">
    <input type="submit" name="Clear" value="クリア">
}
コントローラーのコード
using Project.Extensions;

[HttpPost]
[Button(ButtonName = "Search")]
[ValidateAntiForgeryToken]
public ActionResult Index()
{
    // 検索ボタンが押された場合の処理
}
  • アクションメソッドに[Button(ButtonName = "XXXXX")]を付加する。
  • ”XXXXX"には、このアクションメソッドを実行させたいボタンのname属性値を設定する。
  • ボタンのname属性値と[Button(ButtonName = "XXXXX")]で大文字、小文字の違いがあっても 正常に機能します。

どれを使えばいいのか

セレクター属性を作成して押されたボタンを判断するのがMVC的な方法なのかと思います。

28
41
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
41