intra-mart Accel Platform TERASOLUNA Server Framework for Java (5.x) プログラミングガイド 第17版 2022-12-01

実装例:一覧画面を作る

この項では、TODO登録画面で登録したTODOをスマートフォンで一覧表示する画面の実装例を紹介します。

前提条件

  • intra-mart Accel Platform をインストールし、初期設定までが完了していること。

  • ベースモジュールに TERASOLUNA Server Framework for Java (5.x) for Accel Platform 、および、IM-Mobile Frameworkモジュールを含めて環境を作成してください。
    実行環境は単体テスト用で作成してください。
  • 実装例:登録画面を作る を参考に事前にテーブル作成、および、サンプル画面を作成しておいてください。

画面の用意

ソースの準備と配置

まず、以下2点のファイルを作成します。

  • jp.co.intra_mart.sample.spring.imsp.app.list.ListController.java

    package jp.co.intra_mart.sample.spring.imsp.app.list;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping("sample/spring/sp/list")
    public class ListController {
        
        @RequestMapping({"", "/"})
        public String index(Model model) {
            return "sample/spring/imsp/list/index.jsp";
        }
    }
    
  • %CONTEXT_PATH%/WEB-INF/views/sample/spring/imsp/list/index.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
    <%@ taglib prefix="imsp" uri="http://www.intra-mart.co.jp/taglib/imsp" %>
    <%@ taglib prefix="imui" uri="http://www.intra-mart.co.jp/taglib/imui" %>
    <imui:head>
      <title>TODO一覧</title>
    </imui:head>
    <div data-role="page" id="main" data-theme="a">
      <imsp:headerWithLink headerText="TODO一覧" />
      <div data-role="content">
      </div>
      <imsp:commonFooter dataPosition="fixed"/>
    </div>
    

メニューの設定

登録画面と同様に一覧画面をメニューに追加します。パスは”sample/spring/sp/list”とします。

メニューに追加

クライアントタイプをスマートフォンに切り替えグローバルナビ画面を表示します。

グローバルナビ

TODO一覧を選択します。先ほど作ったブランク画面が表示されました。

ブランク画面

一覧表示部品を配置する

一覧表示を実現するには、<ul>タグ、および、<li>タグを使用します。

一覧のマークアップ例

例として見出し行、および、3行の一覧を表示してみます。
list.jspに以下の記述を追加します。
 <div data-role="content">
   <ul data-role="listview">
     <li data-role="list-divider">テストの一覧</li>
     <li>一行目です。</li>
     <li>二行目です。</li>
     <li>三行目です。</li>
   </ul>
 </div>

コラム

  • リスト表示する場合、ulタグにdata-role=”listview”属性を付加します。
  • liタグにdata-role=”list-divider”属性を付加することで強調表現になります。
  • マークアップ結果。ulタグに囲まれたliタグが1行づつ表示されました。

    一覧のマークアップ結果

それでは実際にTODO一覧を表示する処理を実装していきます。

検索処理の実装

前項で作成したサービスクラスに検索処理を追加します。
  • jp.co.intra_mart.sample.spring.imsp.service.MfwSampleService.java

    package jp.co.intra_mart.sample.spring.imsp.service;
    
    import java.util.List;
    
    import jp.co.intra_mart.sample.spring.imsp.domain.model.MfwSample;
    
    public interface MfwSampleService {
        public void store(MfwSample entity);
        
        public List<MfwSample> findAll();
    }
    
  • jp.co.intra_mart.sample.spring.imsp.service.MfwSampleServiceImpl.java

    package jp.co.intra_mart.sample.spring.imsp.service;
    
    import java.util.List;
    
    import javax.inject.Inject;
    
    import org.springframework.stereotype.Service;
    
    import jp.co.intra_mart.sample.spring.imsp.domain.model.MfwSample;
    import jp.co.intra_mart.sample.spring.imsp.domain.repository.MfwSampleRepository;
    
    @Service
    public class MfwSampleServiceImpl implements MfwSampleService {
        
        @Inject
        MfwSampleRepository mfwSampleRepository;
        
        @Override
        public void store(MfwSample entity) {
            mfwSampleRepository.save(entity);
        }
    
        @Override
        public List<MfwSample> findAll() {
            return mfwSampleRepository.findAll();
        }
    }
    

ListControllerにサービスクラスをバインドし、検索処理を追加します。

@Inject
MfwSampleService mfwSampleService;

@RequestMapping({"", "/"})
public String index(Model model) {

    List<MfwSample> result = mfwSampleService.findAll();

    model.addAttribute("list", result);

    return "sample/spring/imsp/list/index.jsp";
}

コラム

  • データベースの詳細については データベース を参照してください。
  • list.jspのulタグの内部を修正します。

      <ul data-role="listview">
        <li data-role="list-divider">テストの一覧</li>
        <c:forEach var="record" items="${list}">
        <li><c:out value="${record.title}"/></li>
        </c:forEach>
      </ul>
    
  • マークアップ結果。登録されている全件のTODOのタイトルが表示されました。

    レコード検索結果

コラム

この項目では、下記のポイントを確認しました。

  • 一覧表示するには<ul data-role=”listview”>を使用する
  • 行の表示は<li>タグを使用する

ページング処理を実装する

TODO一覧にページング処理を追加します。

ページ情報の定義

サービスクラスのfindAllメソッドを以下のように修正します。

  • jp.co.intra_mart.sample.spring.imsp.service.MfwSampleService.java

    import org.springframework.data.domain.Pageable;
    
    ...
    
    public List<MfwSample> findAll(Pageable pageable);
    
    ...
    
    public long count();
    
  • jp.co.intra_mart.sample.spring.imsp.service.MfwSampleServiceImpl.java

    import org.springframework.data.domain.Pageable;
    
    ...
    
    public List<MfwSample> findAll(Pageable pageable) {
        return mfwSampleRepository.findAll(pageable).getContent();
    }
    
    ...
    
    public long count() {
        return mfwSampleRepository.count();
    }
    
  • ListControllerクラスを以下のように修正します。

        import org.springframework.data.domain.PageRequest;
        import org.springframework.data.domain.Pageable;
    
        ...
    
        @RequestMapping({"", "/"})
        public String index(Model model, Integer currentPage) {
    
        currentPage = (currentPage == null)? 1 : currentPage;
    
        //ページング情報オブジェクト
        Pageable pageable = new PageRequest(currentPage - 1, 10, Direction.ASC, "limitDate");
    
        List<MfwSample> result = mfwSampleService.findAll(pageable);
    
        model.addAttribute("currentPage", pageable.getPageNumber() + 1);
        model.addAttribute("pageLine", pageable.getPageSize());
        model.addAttribute("maxRecord", mfwSampleService.count());
        model.addAttribute("list", result);
    
        return "sample/spring/imsp/list/index.jsp";
    }
    

ページング用タグの配置

  • list.jspのulタグの内部に<imsp:pagingButton>タグを表示します。 またページ送り用のフォームも設置します。

     <ul data-role="listview">
       <li data-role="list-divider">テストの一覧</li>
       <c:forEach var="record" items="${list}">
       <li><c:out value="${record.title}"/></li>
       </c:forEach>
       <imsp:pagingButton currentPage="${currentPage}" pageLine="${pageLine}" maxRecord="${maxRecord}" />
     </ul>
     <form id="pageForm" method="POST">
       <input type="hidden" name="currentPage" />
     </form>
    
    • 使用するタグについて

      jspタグ名 機能概要 マークアップ例
      pagingButton リストのページを移動するためのボタンを提供します。
      spPagingButton

ページング処理の実装

  • 最後に、list.jspにページ遷移ボタン押下時の処理を追加します。

     <div data-role="page">
       <script>
         function onPageLinkFunc(page) {
           $("input[name=currentPage]").val(page);
           $("#pageForm").submit();
         }
       </script>
    

    コラム

    pagingButtonタグのページ遷移ボタンは未実装関数「onPageLinkFunc」を呼び出しますので
    必要に応じて実装してください。
  • マークアップ結果。一覧下部にページ遷移ボタンが表示され、一覧が5ページづつ表示されます。

    1ページ目
  • ページ遷移ボタン押下時。2ページ目が表示されました。

    2ページ目

コラム

この項目では、下記のポイントを確認しました。

  • ページング処理を実装するには<imsp:spPagingButton>タグを使用する

書式をカスタマイズする

より使いやすいレイアウトにするために、一覧表示の書式を修正します。

  • <ul>タグの内部を以下のように修正します。

     <ul data-role="listview">
       <li data-role="list-divider"><c:out value="${currentPage}" />ページ目</li>
       <c:forEach var="record" items="${list}">
         <li>
           <p class="ui-li-aside"><c:out value="${record.limitDate}"/></p>
           <h3><c:out value="${record.title}"/></h3>
           <p class="ui-li-desc"><c:out value="${record.comment}"/></p>
         </li>
       </c:forEach>
       <imsp:pagingButton currentPage="${currentPage}" pageLine="${pageLine}" maxRecord="${maxRecord}" />
     </ul>
    

    コラム

    <li>タグ内の<h>タグは主題として扱われます。
    <p class=”ui-li-aside”>は右端装飾部として表示されます。
    <p class=”ui-li-desc”>は副題として主題下部に表示されます。複数配置可能です。
  • マークアップ結果。日付とコメントが一覧に表示されるようになりました。

    ../../../../../_images/deco.PNG

最終結果

  • jp.co.intra_mart.sample.spring.imsp.app.list.ListController.java

    package jp.co.intra_mart.sample.spring.imsp.app.list;
    
    import java.util.List;
    
    import javax.inject.Inject;
    
    import jp.co.intra_mart.sample.spring.imsp.domain.model.MfwSample;
    import jp.co.intra_mart.sample.spring.imsp.service.MfwSampleService;
    
    import org.springframework.data.domain.PageRequest;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.domain.Sort.Direction;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping("sample/spring/sp/list")
    public class ListController {
        
        @Inject
        MfwSampleService mfwSampleService;
        
        @RequestMapping({"", "/"})
        public String index(Model model, Integer currentPage) {
            
            currentPage = (currentPage == null)? 1 : currentPage;
            
            //ページング情報オブジェクト
            Pageable pageable = new PageRequest(currentPage - 1, 10, Direction.ASC, "limitDate");
    
            List<MfwSample> result = mfwSampleService.findAll(pageable);
            
            model.addAttribute("currentPage", pageable.getPageNumber() + 1);
            model.addAttribute("pageLine", pageable.getPageSize());
            model.addAttribute("maxRecord", mfwSampleService.count());
            model.addAttribute("list", result);
            
            return "sample/spring/imsp/list/index.jsp";
        }
    }
    
  • %CONTEXT_PATH%/WEB-INF/views/sample/spring/imsp/list/index.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
    <%@ taglib prefix="imsp" uri="http://www.intra-mart.co.jp/taglib/imsp" %>
    <%@ taglib prefix="imui" uri="http://www.intra-mart.co.jp/taglib/imui" %>
    <imui:head>
      <title>TODO一覧</title>
    </imui:head>
    <div data-role="page" id="main" data-theme="a">
      <script>
         function onPageLinkFunc(page) {
           $("input[name=currentPage]").val(page);
           $("#pageForm").submit();
         }
       </script>
      <imsp:headerWithLink headerText="TODO一覧" />
      <div data-role="content">
        <ul data-role="listview">
    	   <li data-role="list-divider"><c:out value="${currentPage}" />ページ目</li>
    	   <c:forEach var="record" items="${list}">
    	     <li>
    	       <p class="ui-li-aside"><c:out value="${record.limitDate}"/></p>
    	       <h3><c:out value="${record.title}"/></h3>
    	       <p class="ui-li-desc"><c:out value="${record.comment}"/></p>
    	     </li>
    	   </c:forEach>
    	   <imsp:pagingButton currentPage="${currentPage}" pageLine="${pageLine}" maxRecord="${maxRecord}" />
    	 </ul>
         <form id="pageForm" method="POST">
           <input type="hidden" name="currentPage" />
         </form>
      </div>
      <imsp:commonFooter dataPosition="fixed"/>
    </div>
    
  • jp.co.intra_mart.sample.spring.imsp.service.MfwSampleService.java

    package jp.co.intra_mart.sample.spring.imsp.service;
    
    import java.util.List;
    
    import org.springframework.data.domain.Pageable;
    
    import jp.co.intra_mart.sample.spring.imsp.domain.model.MfwSample;
    
    public interface MfwSampleService {
        public void store(MfwSample entity);
        
        public List<MfwSample> findAll(Pageable pageable);
        
        public long count();
    }
    
  • jp.co.intra_mart.sample.spring.imsp.service.MfwSampleServiceImpl.java

    package jp.co.intra_mart.sample.spring.imsp.service;
    
    import java.util.List;
    
    import javax.inject.Inject;
    
    import org.springframework.data.domain.Pageable;
    import org.springframework.stereotype.Service;
    
    import jp.co.intra_mart.sample.spring.imsp.domain.model.MfwSample;
    import jp.co.intra_mart.sample.spring.imsp.domain.repository.MfwSampleRepository;
    
    @Service
    public class MfwSampleServiceImpl implements MfwSampleService {
        
        @Inject
        MfwSampleRepository mfwSampleRepository;
        
        @Override
        public void store(MfwSample entity) {
            mfwSampleRepository.save(entity);
        }
    
        @Override
        public List<MfwSample> findAll(Pageable pageable) {
            return mfwSampleRepository.findAll(pageable).getContent();
        }
    
        @Override
        public long count() {
            return mfwSampleRepository.count();
        }
        
    }