LoginSignup
1
1

More than 3 years have passed since last update.

【ASP.NET Core MVC】ASP.NET Core MVCであみだくじを作ってみる 4 (cssの作成)

Last updated at Posted at 2019-11-04

概要

前回:【ASP.NET Core MVC】ASP.NET Core MVCであみだくじを作ってみる 3 (モデルの追加)
今回は、cssを使ってビューのレイアウトを作成していきます。
コントローラー間でのモデルデータの受け渡しも考えてみます。

コントローラー間でモデルを受け渡す

ASP.NET Core でのセッションとアプリの状態をざっと読み、TempDataを使うことにしました。
HomeControllerのIndexアクションに、モデルデータをTempDataにセットする処理を追加します。

HomeController.cs
using Newtonsoft.Json;

        /// <summary>
        /// HomeビューでPOSTした時のアクション
        /// </summary>
        /// <param name="name"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult Index(string name, KujiModel model)
        {
            // 入力エラーがある時は何もしない
            if (!ModelState.IsValid)
                return View(model);

            // [結果を設定する]ボタンを押下した場合
            if (name == "set")
            {
                // くじの数が減った場合は、結果入力欄を減らす
                while (model.NumberOfKuji < model.Result.Count)
                {
                    model.Result.RemoveAt(model.Result.Count - 1);
                }

                // くじの数が増えた場合は、結果入力欄を増やす
                while (model.NumberOfKuji > model.Result.Count)
                {
                    model.Result.Add(new ResultModel());
                }

                return View(model);
            }

            TempData["kuji"] = JsonConvert.SerializeObject(model);

            // くじコントローラーを呼ぶ
            return RedirectToAction("Index", "Kuji");
        }

TempData["kuji"] = model としたくなるところですが、オブジェクトはセットできないようです。
このため、JsonConvert.SerializeObjectでjson文字列に変換してからセットしました。

KujiController側で、TempData["kuji"]を受け取ります。

KujiController.cs
using Amidakuji.Models;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace Amidakuji.Controllers
{
    public class KujiController : Controller
    {
        [HttpGet]
        public IActionResult Index()
        {
            ModelState.Clear();

            // 受け取ったTempDataからデータを取得する
            var json = TempData["kuji"]?.ToString();
            if (json != null)
            {
                var model = JsonConvert.DeserializeObject<KujiModel>(json);
                return View(model);
            }

            return View(new KujiModel());
        }
    }
}

JsonConvert.DeserializeObjectで、json文字列をKujiModel型にデシリアライズしています。
デシリアライズ後のモデルをビューに渡すことで、Homeビューで入力したデータをKujiビューでも使えるようになります。

cssファイルを追加する

JavaScript、CSS、画像等の静的ファイルは、Webルート(既定ではwwwroot)ディレクトリに格納されています。
ASP.NET Core MVCでは、デフォルトのcssフレームワークとしてBootstrapが導入されていますが、
今回はオリジナルのcssを作ります。

ソリューションエクスプローラーの「wwwroot\css」を選択します。
右クリックでメニューを表示し、追加⇒新しい項目を選択します。
スタイルシートを選択します。ここでは、名前を「kuji.css」としました。
css.PNG
Home\Index.cshtmlやKuji\Index.cshtmlの<style>をcssに移動します。
各cshtmlの<style>~<\style>は削除しておきます。

kuji.css
/*あみだくじデータの設定領域*/
.kuji-items {
    display: grid; /*グリッドレイアウトにする*/
    grid-auto-columns: 100px; /*1列あたりの幅 100px*/
    grid-auto-rows: 36px; /*1行あたりの高さ 30px*/
    background-color: #99CCCC; /*背景色*/
    margin: 0px auto; /*中央寄せ*/
    padding: 10px;
}

/*あみだくじデータの設定領域の入力項目*/
.kuji-items > input {
    height: 30px; /*高さ*/
}

/*くじを作るボタン*/
.create_btn {
    font-weight: bold;  /*太文字*/
    padding: 0.25em 0.5em;  /*文字余白*/
    text-decoration: none;  /*文字装飾なし*/
    color: #FFF;    /*文字色*/
    background: #008080; /*背景色*/
    margin-left: 10px; /*左側余白*/
    height: 30px; /*高さ*/
}

/*くじコンテナ*/
.kuji-container {
    height: 100px; /*高さ*/
    background-color: #CBFFD3; /*背景色*/
}

「Views\Shared\_Layout.cshtml」の<head>内にcssへのリンクを追加します。

_Layout.cshtml
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Amidakuji</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
    <!-- kuji.cssを追加 -->
    <link rel="stylesheet" href="~/css/kuji.css" />
</head>

cssにUIを定義する

試行錯誤の結果、あみだ部分はグリッドレイアウトを利用することにしました。
kuji.cssに以下を追加します。内容はコードにコメントで書きました。

kuji.css
・・・省略・・・

/*タイトル*/
.kuji-container > h1 {
    color: #000000; /*文字色*/
    background: #E6FFE9; /*背景色*/
    border-bottom: solid 3px #0000FF; /*下線*/
}

/*説明文*/
.kuji-container > p {
    color: #000000; /*文字色*/
    border-bottom: solid 3px #0000FF; /*下線*/
}

/*あみだくじの領域*/
.kuji-line {
    display: grid; /*グリッドレイアウトにする*/
    grid-auto-columns: minmax(10px, auto); /*1列あたりの幅 10px以上*/
    grid-auto-rows: minmax(25px, auto); /*1行あたりの高さ 25px以上*/
    background-color: #99CCCC; /*背景色*/
    position: relative; /*後述の「あみだを隠すためのマスク領域」の基準点とするためにrelativeを指定*/
}

/*あたり・はずれ等の結果*/
.kuji-line > div {
    margin: 0px auto; /*中央寄せ*/
}

/*縦線*/
.vertical-line {
    background-color: #000000; /*背景色*/
    width: 1px; /*幅*/
    height: auto; /*高さ*/
    margin: 0px auto; /*中央寄せ*/
}

/*横線*/
.horizontal-line {
    background-color: #000000; /*背景色*/
    width: 100%; /*幅*/
    height: 1px; /*高さ*/
    margin-left: 50%; /*左マージン 縦線を中央寄せしているため、幅50%分をずらして縦線の位置から始める*/
}

/*くじを辿る時の縦線*/
.vertical-line.follow {
    background-color: #FF0000; /*背景色*/
    width: 3px; /*幅*/
}

/*くじを辿る時の横線*/
.horizontal-line.follow {
    background-color: #FF0000; /*背景色*/
    height: 3px; /*幅*/
}

/*選択肢ボタン*/
.select-btn {
    color: #0000FF; /*文字色*/
    width: 25px; /*幅*/
    height: 25px; /*高さ*/
    border-radius: 50%; /*角丸 50%で円になる*/
    border: solid 2px #0000FF; /*枠線*/
    text-align: center; /*文字の中央寄せ*/
    margin: 0px auto; /*中央寄せ*/
}

/*選択肢ボタンのマウスオーバー時*/
.select-btn:hover {
    background-color: #6495ED; /*背景色*/
}

/*選択したボタン*/
.select-btn.selected {
    color: #FF0000; /*文字色*/
    border: solid 2px #FF0000; /*枠線*/
    background-color: #FFDDFF; /*背景色*/
}

/*あみだを隠すためのマスク領域*/
.mask {
    position: absolute; /*「あみだくじの領域」を基準点とするためにabsoluteを指定*/
    width: 90%; /*幅 「あみだくじの領域」の90%の幅*/
    height: 76%; /*高さ 「あみだくじの領域」の76%の高さ*/
    top: 12%; /*上位置 「あみだくじの領域」の上から12%の位置*/
    left: 5%; /*左位置 「あみだくじの領域」の左から5%の位置*/
    text-align: center; /*文字の中央寄せ*/
    border: solid 2px #808080; /*枠線*/
    background-color: #E6FFE9; /*背景色*/
    background-image: radial-gradient(#808080 10%, transparent 20%), radial-gradient(#808080 10%, transparent 20%); /*背景画像*/
    background-size: 10px 10px; /*背景画像のサイズ(幅 高さ)*/
}

「あみだを隠すためのマスク領域」についての説明を補足します。
背景画像に円形グラデーションを指定し、background-sizeで幅、高さを10pxに揃えることで円を描いています。
この円が、マスク領域のサイズ分繰り返されます。

定義したcssを使ってビューをあみだくじっぽくする

Kuji\Index.cshtmlを以下のように変更します。
くじの数は5本固定で、マスク領域を隠したり表示したりする機能はありません。
このあたりは、次回Razorの学習で改善していくつもりです。

Kuji\Index.cshtml
@model Amidakuji.Models.KujiModel

@{
    ViewData["Title"] = "あみだくじ";
}

<div class="kuji-container">
    <h1>@Model.Title</h1>
    <p>くじの数は、@Model.NumberOfKuji 本です。</p>

    <!--あみだくじの領域(グリッドレイアウト)-->
    <div class="kuji-line">
        <!--選択肢ボタン-->
        <a href="#" class="select-btn" style="grid-row:2;grid-column:1">1</a>
        <a href="#" class="select-btn" style="grid-row:2;grid-column:2">2</a>
        <a href="#" class="select-btn" style="grid-row:2;grid-column:3">3</a>
        <a href="#" class="select-btn" style="grid-row:2;grid-column:4">4</a>
        <a href="#" class="select-btn" style="grid-row:2;grid-column:5">5</a>

        <!--縦線-->
        <div class="vertical-line" style="grid-row:3 / span 15;grid-column:1"></div>
        <div class="vertical-line" style="grid-row:3 / span 15;grid-column:2"></div>
        <div class="vertical-line" style="grid-row:3 / span 15;grid-column:3"></div>
        <div class="vertical-line" style="grid-row:3 / span 15;grid-column:4"></div>
        <div class="vertical-line" style="grid-row:3 / span 15;grid-column:5"></div>

        <!--横線-->
        <p class="horizontal-line" style="grid-row:4;grid-column:1"></p>
        <p class="horizontal-line" style="grid-row:10;grid-column:1"></p>
        <p class="horizontal-line" style="grid-row:13;grid-column:1"></p>
        <p class="horizontal-line" style="grid-row:8;grid-column:2"></p>
        <p class="horizontal-line" style="grid-row:12;grid-column:2"></p>
        <p class="horizontal-line" style="grid-row:14;grid-column:2"></p>
        <p class="horizontal-line" style="grid-row:6;grid-column:3"></p>
        <p class="horizontal-line" style="grid-row:13;grid-column:3"></p>
        <p class="horizontal-line" style="grid-row:5;grid-column:4"></p>
        <p class="horizontal-line" style="grid-row:9;grid-column:4"></p>
        <p class="horizontal-line" style="grid-row:15;grid-column:4"></p>

        <!--結果-->
        <!--横幅を揃えるため、PadRightで5文字分に揃える-->
        <div style="grid-row:18;grid-column:1">@Model.Result[0].Item.PadRight(5, ' ')</div>
        <div style="grid-row:18;grid-column:2">@Model.Result[1].Item.PadRight(5, ' ')</div>
        <div style="grid-row:18;grid-column:3">@Model.Result[2].Item.PadRight(5, ' ')</div>
        <div style="grid-row:18;grid-column:4">@Model.Result[3].Item.PadRight(5, ' ')</div>
        <div style="grid-row:18;grid-column:5">@Model.Result[4].Item.PadRight(5, ' ')</div>

        <!--1行分を余白とする-->
        <div style="grid-row:19;grid-column:1 / span 5"></div>

        <!--あみだを隠すためのマスク領域-->
        <div class="mask"></div>
    </div>
</div>

「grid-row:2;grid-column:1」という書き方をしている箇所があります。
これは、グリッドレイアウトの中で、2行目の1列目、という意味です。
「grid-column:1 / span 5」等となっている箇所は、1列目から始めて5列分の領域という意味です。
Excelのセル結合を思い浮かべると分かりやすいかもしれません。

実行してみる

マスク領域あり
デザイン①.PNG
マスク領域なし
デザイン②.PNG

まとめ

今回は、cssを使ってビューのレイアウトを作成しました。
次回は、Razorを使ってマスク領域を隠したり表示したりする機能を作ります。
次回分はこちら⇒ASP.NET Core MVCであみだくじを作ってみる 5 (Razorを使う)

1
1
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
1
1