9月4日

前回は、ToDo項目にチェックすると、AJAXでサーバーにデータを送信して、完了日時をエンティティに登録し、データベースを更新するところまで実装した。

この状態でToDo項目の画面にアクセスすると、完了済みの項目が未完了に表示されてしまう。

未完了のToDo項目と、完了済みのToDo項目をそれぞれの領域に表示するよう修正する。

<!DOCTYPE html>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ToDoアプリ</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
	$('input[name="item"]').change(function(){
		console.log($(this).parent());
		$('#done').append($(this).parent());
		$.post('done', 'id=' + $(this).val());
	});
})
</script>
</head>
<body>
<h1>ToDo項目</h1>

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

<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="item" value="${t.id}" />${t.item}
        </div>
      </c:if>
    </c:forEach>
  </form>
</c:if>

<hr />
<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="item" value="${t.id}" checked="checked" />${t.item}
      </div>
    </c:if>
  </c:forEach>
</c:if>
</div>



</body>
</html>

テキストフィールドに入力して「登録」ボタンを押すと、テキストフィールドが完了済みに移動してしまう問題を解決する。

jQueryで input[name=”item”] というセレクタを指定していると、これがテキストフィールドにも該当してしまう。
チェックボックスのnameをitemsに変更してchangeイベントを拾うところもinput[name=”items”]とする。

<!DOCTYPE html>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ToDoアプリ</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
	$('input[name="items"]').change(function(){
		console.log($(this).parent());
		$('#done').append($(this).parent());
		$.post('done', 'id=' + $(this).val());
	});
})
</script>
</head>
<body>
<h1>ToDo項目</h1>

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

<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}
        </div>
      </c:if>
    </c:forEach>
  </form>
</c:if>

<hr />
<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}
      </div>
    </c:if>
  </c:forEach>
</c:if>
</div>



</body>
</html>

pom.xmlにJSONを扱うためのライブラリを追加する。

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.8.8</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.8.9</version>
		</dependency>

追加したら、[maven]-[プロジェクトの更新]と[実行]-[maven install]を実行する。

ToDo項目を更新するための /done に対してPOST送信したら、その応答で、JSONデータを返すようにする。

	@RequestMapping(value = "/done", method = RequestMethod.POST)
	@ResponseBody
	@ResponseStatus(value = HttpStatus.OK)
	public List<ToDo> done(@RequestParam(value = "id") String id, Model model) {
		ToDoDao<ToDo> dao = new ToDoDaoImpl();
		ToDo todo = dao.findById(Long.parseLong(id));
		todo.setDone(new Date());
		dao.update(todo);
		List<ToDo> list = dao.getAll();
		return list;
	}

jQueryでPOSTしたときに応答を受信してJavaScriptコンソールにデータを出力してみる。

<script type="text/javascript">
$(function(){
	$('input[name="items"]').change(function(){
		console.log($(this).parent());
		$('#done').append($(this).parent());
		$.post(
			'done',
			'id=' + $(this).val(),
			function(data) {
				console.log(data);
			});
	});
})
</script>

チェックして、サーバーからデータを受け取ったら、受け取ったデータに基づいてToDo項目を更新する。
まずは、既存の項目をすべて削除する。

<script type="text/javascript">
$(function(){
	$('input[name="items"]').change(function(){
		console.log($(this).parent());
		$('#done').append($(this).parent());
		$.post(
			'done',
			'id=' + $(this).val(),
			function(data) {
				console.log(data);
				$('#todo form').children().remove();
				$('#done').children().remove();
			});
	});
})
</script>

受信したJSONデータにもとづいてdiv要素を作り直す。
完了日時が設定されていなければ未完了側に、設定されていれば完了側にdiv要素を追加する。

$(function(){
	$('input[name="items"]').change(function(){
		console.log($(this).parent());
		$('#done').append($(this).parent());
		$.post(
			'done',
			'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);
					if (data[i].done == null) {
						$('#todo form').append(div);
					} else {
						cb.attr('checked', 'checked');
						$('#done').append(div);
					}
				}
			});
	});
})
</script>

コメントを残す

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