酢ろぐ!

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

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

今日は7月7日、七夕ですね。Twitterのタイムラインを見ていたら七夕ということもあってか短冊を作って遊んでる方が沢山いました。

だるさんがWebMatrixを使って短冊ヘルパーを作っていたので、僕も負けじとASP.NET MVCを使ってかなり雑な短冊メーカーを作りました。

  • 短冊メーカー (Microsoft Azureが自由に使えなくなったので閉鎖しました)

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

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

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

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

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

  • Microsoft Azure Webサイト *1
  • Bootstrap 3.2.0 *2
  • ASP.NET MVC 4 *3

画面の構成

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の内容が返ってきます*4

HomeController.cs

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

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

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

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)
        {
            if (!Request.IsAjaxRequest())
            {
                return new EmptyResult();
            }

            var text = collection["message"];
            if (string.IsNullOrEmpty(text))
            {
                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

HomeController側で作成した短冊をModelに突っ込んでいるので、@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>

おわり。

さいごに

表題とは異なるけど、短冊メーカーの完成度を上げるとしたら「縦書き対応」と「複数行対応」だと思います。

縦書き用の句読点は文字コードが異なるようなので、「http://homepage2.nifty.com/k_maeda/code/uni/uni115.html」を参考にして、句読点の置換をおこなうと良いと思います。なかなか横文字→縦文字変換って難しいね。

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

にべべめ……

  • (追記)にべべに聞くと、誰かのを見て真似て作ったと教えてもらった。googleで検索する限り、一番古い短冊テンプレはどうやら以下のツイートのようだ。

きちんと調べたことはないけど、Twitterでの短冊遊びとか突然の死とかも(2chとかの)AA文化を起源にしているのかもしれませんね。

追記

続きのエントリを書きました。

*1:無料モード

*2:最近Viewを作るのにこればっかり使ってる

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

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

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