酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

ASP.NET MVC 4でjQueryを使って動的に部分ビューを更新させる

今日、タイムラインを見ていたら七夕ということもあってか、Twitterで短冊を作って遊んでる方が沢山いました。だるさんがWebMatrixを使って短冊ヘルパーを作っていたので、負けじとASP.NET MVCを使ってかなり雑な短冊メーカーを作りました。

ツイート機能は入れないといけないと思い実装しましたが、Ajaxで動的に内容を差し替えるツイートボタンの実装は難易度が高かったです。

なんで雑かというと、横書き用の「、」「。」や半角アルファベットなどに関しては適切な文字への置き換えをおこなっていません。脇が甘いのはいつものことなのでご容赦ください。

メーカーの「ー」に関しては気付いたので、縦書きへ変換する際に置換するようにしています。文字コードが異なる横棒だと置換されないと思います。

雑な短冊メーカーを作るのに用意したもの

さて、短冊メーカーを作るのに使っているのは以下のものです。最近、ASP.NET MVCとBootstrapを使うとサクサクっとサイトを構築できるのに気付いて重宝しています。

  • Microsoft Azure WebSites *1
  • Bootstrap 3.2.0
  • ASP.NET MVC 4 *2

画面の構成

1画面だけの単純な構成なので、特に説明は不要かと思いますが、順番に説明していきます。

全部のページのベースとなる「_Layout.cshtml」です。。ここにはhtmlの<head><body>のなど全ページに共通の要素を入れます。

次に、該当するページ独自のHTMLを書く「Index.cshtml」です。ここにはテキストボックスやsubmitボタンなどの要素を配置します。

最後に「短冊を作成する」ボタンが押されると、Ajaxで短冊とツイートボタンを表示させる部分ビューの「NagaigotoResultView.cshtml」の更新をおこないます。

f:id:ch3cooh393:20140707192605p:plain

ASP.NET MVCでのページの書き方とかに関しては追々書いていきますので、ここでは重要な「どのようにしてAjaxを使って動的に部分ビューを更新するのか」について説明を書きたいと思います。

ASP.NET MVC 4でjQueryを使って動的に部分ビューを更新させる

_Layout.cshtml

jqueryを使うので以下のjsを読み込み込んでおきます。

    <script src="~/Scripts/jquery-1.8.2.min.js"></script>
    <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>

Index.cshtml

Ajax.BeginFormメソッドを使用することで、非同期でサーバーと通信をおこない、結果をAjaxOptionsクラスのUpdateTargetIdプロパティで指定したIDの要素に反映します。

@using (Ajax.BeginForm("Nagaigoto", "Home",
    new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "result" }))
{
    <div class="form-group">
        <label for="inputMessage" class="col-xs-2 control-label">願いごと</label>
        <div class="col-xs-10">
            <input class="form-control" id="negaigotoText" 
                name="message" type="text" value="" />
        </div>
    </div>

    <div class="form-group">
        <div class="col-xs-10">
        </div>
        <div class="col-xs-2">
            <input class="btn btn-default" type="submit" 
                style="margin-top:8px" value="短冊を作る" />
        </div>
    </div>
}

<div id="result">ここに作成した短冊が表示されます</div></div>

Submitボタンが押されると、HomeコントローラーのNagaigotoというアクションが実行され、部分ビューNagaigotoResultView.cshtmlの内容が返ってきます*3

HomeController.cs

Homeコントローラーの実装は以下のようになっています。Indexメソッドは、そのままViews/Home/Index.cshtmlを返します。

Ajaxで非同期で実行されるのがIndexメソッドの下にあるNagaigotoメソッドです。このNagaigotoメソッドでは渡されたテキストが空の場合、または非同期実行(Request.IsAjaxRequestメソッドで判定)の場合には空のビューを返します。*4

Nagaigotoメソッドでは与えられたテキストから短冊を生成して、NagaigotoResultViewを部分ビューとして返しています。

using System.Linq;
using System.Web.Mvc;
using Tanzaku.Models;

namespace Tanzaku.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Nagaigoto(FormCollection collection)
        {
            var text = collection["message"];
            if (string.IsNullOrEmpty(text))
            {
                return new EmptyResult();
            }
            text = text.Replace("ー", "|");
            text = text.Replace("~", "|");

            if (!Request.IsAjaxRequest())
            {
                return new EmptyResult();
            }

            var sb = new System.Text.StringBuilder();
            sb.AppendLine(" ┏┷┓");
            sb.AppendLine(" ┃ ┃");
            sb.AppendLine(string.Join("\r\n", text.Select(_ => " ┃" + _ + "┃")));
            sb.AppendLine(" ┃ ┃");
            sb.AppendLine(" ╰̚━┛⁾⁾");

            var model = new TanzakuModel();
            model.Message = sb.ToString();
            return PartialView("NagaigotoResultView", model);
        }
    }
}

NagaigotoResultView.cshtml

@Model.Messageの部分に、短冊化したテキストが入ります。

@model Tanzaku.Models.TanzakuModel

<div class="row">
    <div class="col-xs-6 col-xs-push-3">
        <textarea class="form-control" rows="20">@Model.Message</textarea>
    </div>
</div>

おわり。

さいごに

縦書き用の句読点は文字コードが異なるようなので、完成度を上げたい方は「Unicode - 縦書き用句読点 (Vertical forms)」で句読点の置換をおこなうと良いと思います。

jsを読める方は「七夕なので短冊メーカーを作ってみた | 忘れたらググればいい」を参考にすると良いかもしれません。これをみて思ったんだけど、もしかして、Twitterで短冊ツイートが始まったのってにべべが最初なんだろうか?

にべべめ……

*1:無料モード

*2:Visual Studio 2013のテンプレートに入ってるやつ

*3:ソースを見ると分かりますが、styleを使ってマージンを調整しているのも雑なところです

*4:雑なのでNegaigotoじゃなくてNagaigotoになってる