9月11日

Gitの練習

todo.jsp を変更してみる。

<body>
<h1>ToDo項目</h1>

<form method="post" action="input">
<input type="text" name="item">
<input type="submit" value="登録">
</form>

<h3>未完了</h3>
<div id="todo">
<c:if test="${list != null}">
  <form method="post" action="check">
    <c:forEach var="t" items="${list}">
      <c:if test="${t.done == null}">
        <div id="check${t.id}">
      	  <input type="checkbox" name="items" value="${t.id}" />${t.item} <span class="days">${t.days}日前</span>
        </div>
      </c:if>
    </c:forEach>
  </form>
</c:if>
</div>

変更して保存すると、プロジェクトエクスプローラ上のファイル名の左側に「>」が表示される。
これは、リポジトリの最新の状態から変更があったことを示す。

プロジェクトを右クリックして[チーム]-[コミット]を選択すると、todo.jsp がファイルリストに表示される。
todo.jspをダブルクリックすると変更箇所が確認できる。
変更内容が間違いなければ、コミットメッセージを入力してコミットを実行する。

未完了項目の経過日数表示

未完了項目の右側に登録してからの経過日数を表示するようにする。
経過日数はサーバー側で計算した方が実装が簡単そうなので、ToDoエンティティに経過日数を格納する days を追加する。
このデータはデータベースに保存する必要はないので @Transient アノテーションを追加しておく。

package jp.abc;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Transient;

@Entity
public class ToDo {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column
	private long id;

	@Column
	private String item;

	@Column
	private Date created;

	@Column
	private Date done;

	@Transient
	private int days;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getItem() {
		return item;
	}

	public void setItem(String item) {
		this.item = item;
	}

	public Date getCreated() {
		return created;
	}

	public void setCreated(Date created) {
		this.created = created;
	}

	public Date getDone() {
		return done;
	}

	public void setDone(Date done) {
		this.done = done;
	}

	public int getDays() {
		return days;
	}

	public void setDays(int days) {
		this.days = days;
	}
}

コントローラを見ると、あちこちで dao.getAll() を使っているので、コントローラではなくDAO実装内で追加すると一か所の変更で済ませることができる。

	public List<ToDo> getAll() {
		EntityManager manager = factory.createEntityManager();
		List<ToDo> list = null;
		CriteriaBuilder builder = manager.getCriteriaBuilder();
		CriteriaQuery<ToDo> q = builder.createQuery(ToDo.class);
		Root<ToDo> r = q.from(ToDo.class);
		q.select(r);
		list = (List<ToDo>)manager.createQuery(q).getResultList();
		manager.close();
		Date now = new Date();
		for (ToDo t : list) {
			long diff = now.getTime() - t.getCreated().getTime();
			diff = diff / (1000 * 60 * 60 * 24);
			t.setDays((int)diff);
		}
		return list;
	}

todo.jsp の未完了項目の右側に値を追加してみる。

<h3>未完了</h3>
<div id="todo">
<c:if test="${list != null}">
  <form method="post" action="check">
    <c:forEach var="t" items="${list}">
      <c:if test="${t.done == null}">
        <div id="check${t.id}">
      	  <input type="checkbox" name="items" value="${t.id}" />${t.item} ${t.days}日前
        </div>
      </c:if>
    </c:forEach>
  </form>
</c:if>
</div>

「○日前」の文字サイズや色を変更するために span タグで囲む。

      	  <input type="checkbox" name="items" value="${t.id}" />${t.item} <span class="days">${t.days}日前</span>

days クラス用のCSSを用意する。

<title>ToDoアプリ</title>
<style type="text/css">
span.days {
  font-size: 9pt;
  color: gray;
  margin-left: 20px;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

動作確認したら、プロジェクトを右クリックして[チーム]-[コミット]を選択する。
ToDo.java
ToDoDaoImpl.java
todo.jsp
の3ファイルがリストされる。
それぞれのファイルをダブルクリックして変更箇所を確認し、問題がなければコミットメッセージを入力してコミットを実行する。

完了済みの項目の経過日数

完了済みの項目の経過日数は、完了した日からの経過日数を表示する。

まずは、未完了項目と同じように、登録日からの経過日数を表示してみる。

<h3>完了済み</h3>
<div id="done">
<c:if test="${list != null}">
  <c:forEach var="t" items="${list}">
    <c:if test="${t.done != null}">
      <div id="check${t.id}">
        <input type="checkbox" name="items" value="${t.id}" checked="checked" />${t.item} <span class="days">${t.days}日前</span>
      </div>
    </c:if>
  </c:forEach>
</c:if>
</div>

完了項目に対しての days の値は、完了日からの経過日数となるように、サーバー側の ToDoDaoImpl.java で計算する。

	public List<ToDo> getAll() {
		EntityManager manager = factory.createEntityManager();
		List<ToDo> list = null;
		CriteriaBuilder builder = manager.getCriteriaBuilder();
		CriteriaQuery<ToDo> q = builder.createQuery(ToDo.class);
		Root<ToDo> r = q.from(ToDo.class);
		q.select(r);
		list = (List<ToDo>)manager.createQuery(q).getResultList();
		manager.close();
		Date now = new Date();
		for (ToDo t : list) {
			long from;
			if (t.getDone() == null) {
				from = t.getCreated().getTime();
			} else {
				from = t.getDone().getTime();
			}
			long diff = now.getTime() - from;
			diff = diff / (1000 * 60 * 60 * 24);
			t.setDays((int)diff);
		}
		return list;
	}

新しく項目を追加したり、チェックボックスをチェックすると「○日前」の表示が消えてしまう。
これは、上記操作をしたときに、jQueryでHTML要素を生成しなおしているため。
span要素を追加する処理を、jQueryで記述することで解決する。

function init() {
	$('input[name="items"]').change(function(){
		console.log($(this).prop('checked'));
		var url;
		if ($(this).prop('checked')) {
			url = 'done';
		} else {
			url = 'redo';
		}
		$.post(
			url,
			'id=' + $(this).val(),
			function(data) {
				console.log(data);
				$('#todo form').children().remove();
				$('#done').children().remove();
				for (var i = 0; i < data.length; i++) {
					var div = $('<div>');
					div.attr('id', 'check' + data[i].id);
					var cb = $('<input>')
								.attr('type', 'checkbox')
								.attr('name', 'items')
								.attr('value', data[i].id);
					div.append(cb).append(data[i].item)
					var s = $('<span>');
					s.addClass('days');
					s.text(data[i].days + '日前');
					div.append(s);
					if (data[i].done == null) {
						$('#todo form').append(div);
					} else {
						cb.attr('checked', 'checked');
						$('#done').append(div);
					}
				}
				init();
			});
	});
}

動作確認できたら、[チーム]-[コミット]で変更内容をGitリポジトリに反映させる。

これまでの変更内容は、[チーム]-[ヒストリーに表示]で確認できる。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です