Web系開発メモ

Java, C#, HTML, CSS, JavaScript のことなどを書いてます。

SpringBoot アプリ開発 5.HTML・JavaScriptの作成

連載記事「SpringBoot アプリ開発」を読み進めると、サンプルの Webアプリを制作することができます。

今回は、HTMLとJavaScriptを作成していきます。

連載記事

SpringBoot アプリ開発の連載記事は以下の通りです。

  1. 概要・使用プロダクト
  2. プロジェクト作成・SQL作成
  3. モデル・リポジトリの作成
  4. コントローラー・メインの作成
  5. HTML・JavaScriptの作成(今回の記事)
  6. CSS・画像の作成
  7. テスト・動作確認

目次

  1. HTMLの作成
  2. JavaScriptの作成

1. HTMLの作成

以下のHTMLを作成します。

src/main/resources/static/index.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>つぶやきアプリ</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link href="css/tweet.css" rel="stylesheet">
</head>
<body>
<header>
  <div class="d-flex justify-content-center">
    <img src="img/logo.png">
  </div>
</header>

<main>
<div class="container">
  <div class="row">
    <div class="col-md-8 offset-md-2 col-lg-6 offset-lg-3">
      <div id="tweet-form">
        <textarea class="form-control" id="txt" rows="3" placeholder="メッセージ"></textarea>
        <div class="d-flex justify-content-end">
        <button type="button" id="create" class="btn btn-success">ツイート</button>
        </div>
      </div><!--  tweet-form -->
      <div id="tweet-list"></div>
    </div><!-- .col-* -->
  </div><!-- .row -->
</div>
</main>

<script id="tweet-template" type="x-tmpl-mustache">
{{#tweet}}
<div class="tweet" data-id="{{id}}">
  <div class="txt"><p>{{txt}}</p></div>
  <div class="d-flex justify-content-start">
    <button type="button" class="btn edit">
      <i class="bi-pencil"></i> 編集
    </button>
    <button type="button" class="btn delete">
      <i class="bi-trash3"></i> 削除
    </button>
    <div class="date">{{createTime}}</div>
  </div>
</div>
{{/tweet}}
</script>

<div class="modal fade" id="modal" tabindex="-1" aria-labelledby="modal-label" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="modal-label">編集</h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <form>
          <div class="form-group">
            <textarea class="form-control" rows="3" id="modal-txt"></textarea>
          </div>
        </form>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">キャンセル</button>
        <button type="button" id="modal-update" class="btn btn-success">更新</button>
      </div>
    </div>
  </div>
</div>

<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.min.js" integrity="sha384-fbbOQedDUMZZ5KreZpsbe1LCZPVmfTnH7ois6mU1QK+m14rQ1l2bGBq41eYeM/fS" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/4.1.0/mustache.min.js" integrity="sha512-HYiNpwSxYuji84SQbCU5m9kHEsRqwWypXgJMBtbRSumlx1iBB6QaxgEBZHSHEGM+fKyCX/3Kb5V5jeVXm0OglQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="js/tweet.js"></script>
</body>
</html>

bodyは以下の内容に分類できます。

  • ヘッダー
  • メイン
  • Mustacheテンプレート
  • Bootstrapモーダル

ヘッダーはロゴ、メインはツイートが表示されます。テンプレートはツイートを表示する際に、モーダルはツイートを編集する際に利用されます。

2. JavaScriptの作成

以下のJavaScriptを作成します。

src/main/resources/static/js/tweet.js

$(function() {
  // mustache template.
  const template = $('#tweet-template').html();
  Mustache.parse(template);

  // utilities.
  function render(tweet) {
    let rendered = Mustache.render(template, tweet);
    $('#tweet-list').prepend(rendered);
  }
  function deleteSec(dateString) {
    return dateString.substring(0, 16);
  }

  // onload.
  $('#txt').focus();
  $.ajax({
    url: '/tweet',
    method: 'get',
    cache: false
  }).then(function(data, status, jqxhr) {
    render(data);
    $('.date').each(function(index, e) {
      $(e).html(deleteSec($(e).html()));
    })
  });
  
  // create.
  $('#create').click(function() {
    let txt = $('#txt').val();
    if (txt === '') return;
    $.ajax({
      url: '/tweet',
      data: JSON.stringify({'txt':txt}),
      contentType: 'application/json',
      method: 'post',
      cache: false
    }).then(function(data, status, jqxhr) {
      render(data);
      let $date = $('.tweet:first').find('.date');
      $date.html(deleteSec($date.html()));
      $('#txt').val('').focus();
    });
  });

  // update.
  let $tweet;
  const modal = new bootstrap.Modal(
    document.getElementById('modal')
  );
  $('body').on('click', '.edit', function() {
    $tweet = $(this).closest('.tweet');
    $('#modal-txt').val($tweet.find('.txt p').html());
    modal.show();
  });
  $('#modal-update').click(function() {
    let txt = $('#modal-txt').val();
    let url = '/tweet/' + $tweet.data('id');
    $.ajax({
      url: url,
      data: {'txt':txt},
      method: 'put',
      cache: false
    }).then(function(data, status, jqxhr) {
      $('#modal').modal('hide');
      $tweet.find('.txt p').html(txt);
    });
  });

  // delete.
  $('body').on('click', '.delete', function() {
    if (!confirm("削除しますか?")) return;
    let $tweet = $(this).closest('.tweet');
    let url = '/tweet/' + $tweet.data('id');
    $.ajax({
      url: url,
      method: 'delete',
      cache: false
    }).then(function(data, status, jqxhr) {
      $tweet.remove();
    });
  });
});

JavaScriptの内容ですが、主にサーバーサイドの処理を呼び出すものとなっています。

例えば、オンロード時はサーバサイドの処理を呼び出してツイートを取得します。それからMustacheテンプレートを使って、画面にツイートを表示しています。

GitHubリポジトリ

アプリのコードは、以下のリポジトリにもあります。

spring-boot-tweet - GitHub

次の連載記事

6. CSS・画像の作成