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

実装例:登録画面を作る

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

前提条件

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

  • ベースモジュールに TERASOLUNA Server Framework for Java (5.x) for Accel Platform およびIM-Mobile Frameworkモジュールを含めて環境を作成してください。
    実行環境は単体テスト用で作成してください。

下準備 テーブル作成

以下手順を行う前に、以下のテーブルを作成してください。

  • mfw_sample

    列名 データ型 主キー NOT NULL 説明
    todo_id VARCHAR(20) レコードのID
    user_cd VARCHAR(20)   登録ユーザID
    user_nm VARCHAR(20)   登録ユーザ名
    limit_date VARCHAR(20)     TODOの期限
    title VARCHAR(100)     TODOのタイトル
    comment VARCHAR(1000)     コメント
    progress NUMBER(3)     進捗度
    complete VARCHAR(1)     完了/未完了
    priority VARCHAR(1)     重要度
    timestmp VARCHAR(20)     タイムスタンプ
※その他のデータベースの場合は環境に合わせて調整してください。

画面を表示できるようにする

ソースの準備と配置

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

  • jp.co.intra_mart.sample.spring.imsp.app.store.StoreController
package jp.co.intra_mart.sample.spring.imsp.app.store;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("sample/spring/sp/store")
public class StoreController {
    
    @RequestMapping
    public String index(Model model) {
        return "sample/spring/imsp/store/index.jsp";
    }
}
  • %CONTEXT_PATH%/WEB-INF/views/sample/spring/imsp/store/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>
    

コラム

  • スマートフォン向けタグライブラリを使用するには以下のtaglibディレクティブを指定してください。
    <%@ taglib prefix="imsp" uri="http://www.intra-mart.co.jp/taglib/imsp" %>
  • <imsp:headerWithLink> - ヘッダ部左端に、任意のページに遷移のボタンを備えたヘッダを表示します。

  • <imsp:spCommonFooter> - フッタ部にHOMEボタンとログアウトボタンを表示します。

メニューの作成

メニューの設定を行います。

  • PCブラウザからテナント管理者でログインし、「メニュー設定」画面を表示します。

  • グローバルナビ(スマートフォン用)を選択し、新規メニューグループ「テストTODO」を作成します。

    ../../../../../_images/menugroup.PNG

新規メニューアイテムを作成します。

  • メニューアイテム名を「TODO登録」とし、URLを”sample/spring/sp/store”とします。

    ../../../../../_images/menuitem1.PNG

認可の設定

認可を設定します。

  • 「権限設定」ボタンを押下し権限設定(グローバルナビ(スマートフォン用))を表示します。

  • 「権限設定を開始する」ボタンをクリックします。

  • テストTODOの権限の「参照」権限を認証済みユーザに付与します。

    ../../../../../_images/auth.PNG

    コラム

    • 認可の詳細については 認可 を参照してください。

画面を表示する

作成したページをメニューから表示します。

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

  • メニューから「テストTODO」を選択すると、先ほど作成されたメニュー「TODO登録」が表示されます。

    スマホ版グローバルナビを表示
  • TODO登録を選択します。目的の画面を表示できました。

    ../../../../../_images/blank1.PNG

コラム

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

  • スマートフォン用グローバルナビにメニューを表示するには、メニューカテゴリ「グローバルナビ(スマートフォン用)」に設定する

画面に要素を配置する

<div data-role=”content”>内に要素を配置します。
例としてテキストボックスとラベルを配置してみます。
ラベルを配置するには<imsp:fieldContain>タグを使用します。
  • store.jsp

    <imsp:fieldContain label="TODO名" required="true">
      <input type="text" name="title" />
    </imsp:fieldContain>
    
  • マークアップ結果。テーマにより最適化されたテキストボックスが表示されました。

    ../../../../../_images/text.PNG

同様に他の要素も配置していきます。

  • imsp:datePicker–日付文字列を参照入力するためのインタフェースを提供します。

    <imsp:fieldContain label="期限" required="true">
      <imsp:datePicker name="limitDate" />
    </imsp:fieldContain>
    
  • textarea–テキストエリアを提供します。

    <imsp:fieldContain label="コメント">
      <textarea name="comment"></textarea>
    </imsp:fieldContain>
    
  • imsp:controlGroup–フォーム要素をグループ化します。

  • imsp:radioButton–jQuery mobileで最適化されたラジオボタンを提供します。

    <imsp:controlGroup label="重要度">
      <imsp:radioButton name="priority" id="radio1" value="0" label="低" />
      <imsp:radioButton name="priority" id="radio2" value="1" label="中" />
      <imsp:radioButton name="priority" id="radio3" value="2" label="高" />
    </imsp:controlGroup>
    
  • imsp:slider–スライダーを提供します。

    <imsp:fieldContain label="進捗">
      <imsp:slider name="progress" min="<%=0 %>" max="<%=100 %>" />
    </imsp:fieldContain>
    
  • imsp:toggle–トグルスイッチを提供します。

    <imsp:fieldContain label="完了">
      <imsp:toggle name="complete" onLabel="完了" offLabel="未完了" onValue="1" offValue="0" />
    </imsp:fieldContain>
    
  • マークアップ結果。各要素が表示されました。

    画面要素配置結果

その他使用可能な要素についてはAPIリストを参照してください。

コラム

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

  • フォーム要素は<div data-role=”content”>内に配置する
  • ラベルを与える場合は<imsp:fieldContain>タグを使用する

登録処理を実装する

まず、フォームを受け取るためのFormクラスを作成します。

  • jp.co.intra_mart.sample.spring.imsp.app.store.StoreForm
package jp.co.intra_mart.sample.spring.imsp.app.store;

public class StoreForm {
    private String title;
    private String limitDate;
    private String comment;
    private String priority;
    private String progress;
    private String complete;
    
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getLimitDate() {
        return limitDate;
    }
    public void setLimitDate(String limitDate) {
        this.limitDate = limitDate;
    }
    public String getComment() {
        return comment;
    }
    public void setComment(String comment) {
        this.comment = comment;
    }
    public String getPriority() {
        return priority;
    }
    public void setPriority(String priority) {
        this.priority = priority;
    }
    public String getProgress() {
        return progress;
    }
    public void setProgress(String progress) {
        this.progress = progress;
    }
    public String getComplete() {
        return complete;
    }
    public void setComplete(String complete) {
        this.complete = complete;
    }
}

次に登録処理用のエンティティクラスを作成します。

  • jp.co.intra_mart.sample.spring.imsp.domain.model.MfwSample

    package jp.co.intra_mart.sample.spring.imsp.domain.model;
    
    import java.io.Serializable;
    import java.math.BigDecimal;
    
    public class MfwSample implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        private String todoId;
    
        private String comment;
    
        private String complete;
    
        private String limitDate;
    
        private String priority;
    
        private BigDecimal progress;
    
        private String timestmp;
    
        private String title;
    
        private String userCd;
    
        private String userNm;
    
        public MfwSample() {
        }
    
        public String getComment() {
            return comment;
        }
    
        public String getComplete() {
            return complete;
        }
    
        public String getLimitDate() {
            return limitDate;
        }
    
        public String getPriority() {
            return priority;
        }
    
        public BigDecimal getProgress() {
            return progress;
        }
    
        public String getTimestmp() {
            return timestmp;
        }
    
        public String getTitle() {
            return title;
        }
    
        public String getTodoId() {
            return todoId;
        }
    
        public String getUserCd() {
            return userCd;
        }
    
        public String getUserNm() {
            return userNm;
        }
    
        public void setComment(final String comment) {
            this.comment = comment;
        }
    
        public void setComplete(final String complete) {
            this.complete = complete;
        }
    
        public void setLimitDate(final String limitDate) {
            this.limitDate = limitDate;
        }
    
        public void setPriority(final String priority) {
            this.priority = priority;
        }
    
        public void setProgress(final BigDecimal progress) {
            this.progress = progress;
        }
    
        public void setTimestmp(final String timestmp) {
            this.timestmp = timestmp;
        }
    
        public void setTitle(final String title) {
            this.title = title;
        }
    
        public void setTodoId(final String todoId) {
            this.todoId = todoId;
        }
    
        public void setUserCd(final String userCd) {
            this.userCd = userCd;
        }
    
        public void setUserNm(final String userNm) {
            this.userNm = userNm;
        }
    }
    
mybatis-config.xml の typeAliasesにエンティティのパッケージを指定します。
<typeAliases>
    <package name="jp.co.intra_mart.sample.spring.imsp.domain.model" />
</typeAliases>
登録処理用のリポジトリインタフェースを定義します。
package jp.co.intra_mart.sample.spring.imsp.domain.repository;

import jp.co.intra_mart.sample.spring.imsp.domain.model.MfwSample;

public interface MfwSampleRepository {

    void create(MfwSample entity);
}

コラム

MyBatis3については、 データベース を参照してください。
リポジトリのパッケージと同じ構成のディレクトリにMfwSampleRepository.xmlを作成します。
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="jp.co.intra_mart.sample.spring.imsp.domain.repository.MfwSampleRepository">

    <insert id="create" parameterType="MfwSample">
        <![CDATA[
        INSERT INTO iap.mfw_sample (
            todo_id,
            user_cd,
            user_nm,
            title,
            comment,
            timestmp,
            priority, 
            limit_date,
            progress,
            complete)
        VALUES (
            #{todoId},
            #{userCd},
            #{userNm},
            #{title},
            #{comment},
            #{timestmp},
            #{priority},
            #{limitDate},
            #{progress},
            #{complete})
        ]]>
    </insert>
</mapper>
applicationContext-im_tgfw_mybatis3.xml のbase-packageの属性値をリポジトリのパッケージに修正し、定義したリポジトリのパッケージをスキャン対象に設定します。
 <!-- setting 'base-package' which is the package in which mapper interface is. -->
 <mybatis:scan base-package="jp.co.intra_mart.sample.spring.imsp.domain.repository" />
ビジネスロジック処理を実現するため、サービスクラスのインタフェースと実装クラスを定義します。
  • jp.co.intra_mart.sample.spring.imsp.domain.service.MfwSampleService

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

    package jp.co.intra_mart.sample.spring.imsp.service;
    
    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.create(entity);
        }
    }
    
  • StoreControllerクラスを以下のように修正します。

    package jp.co.intra_mart.sample.spring.imsp.app.store;
    
    import java.io.IOException;
    
    import javax.inject.Inject;
    
    import jp.co.intra_mart.foundation.context.Contexts;
    import jp.co.intra_mart.foundation.context.model.AccountContext;
    import jp.co.intra_mart.foundation.i18n.datetime.DateTime;
    import jp.co.intra_mart.foundation.i18n.datetime.format.DateTimeFormatter;
    import jp.co.intra_mart.foundation.service.client.information.Identifier;
    import jp.co.intra_mart.foundation.user_context.model.UserContext;
    import jp.co.intra_mart.sample.spring.imsp.domain.model.MfwSample;
    import jp.co.intra_mart.sample.spring.imsp.service.MfwSampleService;
    
    import net.arnx.jsonic.JSON;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping("sample/spring/sp/store")
    public class StoreController {
        
        // ①
        @Inject
        MfwSampleService mfwSampleService; 
        
        // ②
        @ModelAttribute   
        public StoreForm setupStoreForm() {
            return new StoreForm();
        }
        
        @RequestMapping
        public String index(Model model) {
            return "sample/spring/imsp/store/index.jsp";
        }
        
        // ③
        @RequestMapping("store")
        public String store(Model model, StoreForm storeForm) throws IOException {
          
            //ユーザコンテキストを取得します。
            UserContext userProfile = Contexts.get(UserContext.class);
            //アカウントコンテキストからタイムゾーンを取得します。
            AccountContext accountContext = Contexts.get(AccountContext.class);
            DateTimeFormatter formatter = DateTimeFormatter.withPattern("yyyy/MM/dd HH:mm");
    
            //登録値の設定
            MfwSample insertData = new MfwSample();
            // 略
            // storeFormからinsertDataへコピー
    
            insertData.setTodoId(new Identifier().get());
            insertData.setUserCd(userProfile.getUserProfile().getUserCd());
            insertData.setUserNm(userProfile.getUserProfile().getUserName());
            insertData.setTimestmp(formatter.format(DateTime.now(accountContext.getTimeZone())));
            
            mfwSampleService.store(insertData);
            
            return "redirect:/sample/spring/sp/store";
        }
    }
    
  1. サービスクラスをバインドします。

  2. StoreFormを返却するメソッドを定義します。
    @ModelAttributeにより、jspから変数”storeForm”として
    フォームの値を参照できます。
  3. 登録処理のメソッドです。
    引数にStoreFormを設定します。

コラム

  • 画面にFormタグと登録ボタンを配置します。 formタグのaction属性は先ほどstoreメソッドに設定したリクエストマッピングに合わせます。

        <form name="storeForm" id="storeForm" method="POST" action="sample/spring/sp/store/store" data-ajax="false">
          <imsp:fieldContain label="TODO名" required="true">
            <input type="text" name="title" />
          </imsp:fieldContain>
          <imsp:fieldContain label="期限" required="true">
            ...
          <imsp:fieldContain label="完了">
            <imsp:toggle name="complete" onLabel="完了" offLabel="未完了" onValue="1" offValue="0" />
          </imsp:fieldContain>
            <a data-role="button" data-theme="b" id="storeButton">登録</a>
        </form>
    

コラム

  • リンクにdata-role=”button”属性を付加するとリンクをボタン表示します。
  • リンクまたはFORM要素にdata-ajax=”false”属性を付加することで 明示的にAjax画面遷移をキャンセルできます。
  • 最後に登録ボタン押下時のイベントを実装します。
    このとき、記述箇所は<div data-role=”page”>内に実装することに
    気を付けてください。
    <div data-role="page" id="main" data-theme="a">
    <script>
      (function($){
        $('#main').bind("pagecreate create", function() {
          $("#storeButton").unbind().tap(function() {
            $("#storeForm").submit();
          });
        });
      })(jQuery);
    </script>
    

注意

jQuery Mobileでは、Ajaxを使って画面遷移をする場合遷移先画面の<div data-role=”page”>要素のみ取得し、表示中画面に挿入します。
そのため、<HEAD>タグ内にスクリプト、およびスタイルシートを宣言すると画面遷移時に読み込まれないため、不正動作をする場合があります。
  • サーバを再起動して画面を再表示します。 登録ボタン押下時、登録処理を経て画面が再表示されます。

コラム

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

  • フォームの入力内容を受け取るにはFormクラスを定義する
  • 任意のアクションに遷移するにはパスにアクション名を指定する

入力チェック処理を実装する(クライアントサイド)

store.jspにバリデーションルールを定義します。
rulesオブジェクトは入力チェックのルール、messagesオブジェクトは各ルールに対応したメッセージを定義します。
  • JSP

    <script>
      var rules = {
        "title": {
          required:true,
          maxlength:20
        },
        "limit_date": {
          required:true,
          date:true
        }
      };
      var messages = {
         "title": {
            required:"タイトルは必須です。",
            maxlength:"タイトルは20文字以内で入力してください"
         },
         "limit_date": {
           required:"期限は必須です。",
           maxlength:"期限は日付形式で入力してください"
         }
      };
    </script>
    

登録ボタン押下時のスクリプト処理を修正します。

  • JSP

    <script>
      (function($){
        $('#main').bind("pagecreate create", function() {
          //登録ボタン押下時のイベント
          $("#storeButton").unbind().tap(function() {
            //入力チェック実行
            if (imspValidate('#storeForm', rules, messages)) {
              //正常時
              imspAlert('入力エラーはありませんでした');
            } else {
              imspAlert('入力エラーが発生しました', 'エラー');
            }
            return false;
          });
        });
      })(jQuery);
    </script>
    
  • マークアップ結果。タイトルと日付未入力の状態で登録ボタンを押下すると、
    エラーダイアログが表示され警告が出力されます。
入力チェックエラー

コラム

エラー仕様の詳細は、別ドキュメント クライアントサイド JavaScript の imspValidate を参照してください。

コラム

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

  • クライアントサイドで入力チェックを実装するにはバリデーションルールオブジェクトを定義する

非同期で登録処理を実行する

登録ボタン押下時のスクリプト処理を修正します。

  • store.jsp

    <script>
     (function($){
       $('#main').bind("pagecreate create", function() {
         // Formのダブルクリック防止
         $('#storeForm').imspDisableOnSubmit();
         $("#storeButton").unbind().tap(function() {
           //入力チェック実行
           if (imspValidate('#storeForm', rules, messages)) {
              //Ajaxでのデータ送信
              imspAjaxSend('#storeForm', 'POST', 'json');
              //バリデーションのリセット
              imspResetForm('#storeForm');
           } else {
              imspAlert('入力エラーが発生しました', 'エラー');
           }
         });
       });
     })(jQuery);
    </script>
    

非同期で返却するレスポンスオブジェクトを定義します。

  • jp.co.intra_mart.sample.spring.imsp.app.store.MyAjaxResponse

    package jp.co.intra_mart.sample.spring.imsp.app.store;
    
    public class MyAjaxResponse {
        private String result;
        private boolean error;
        private String errorMessage;
        private String successMessage;
        private String[] detailMessages;
        
        public String getResult() {
            return result;
        }
        public void setResult(String result) {
            this.result = result;
        }
        public boolean isError() {
            return error;
        }
        public void setError(boolean error) {
            this.error = error;
        }
        public String getErrorMessage() {
            return errorMessage;
        }
        public void setErrorMessage(String errorMessage) {
            this.errorMessage = errorMessage;
        }
        public String getSuccessMessage() {
            return successMessage;
        }
        public void setSuccessMessage(String successMessage) {
            this.successMessage = successMessage;
        }
        public String[] getDetailMessages() {
            return detailMessages;
        }
        public void setDetailMessages(String[] detailMessages) {
            this.detailMessages = detailMessages;
        }
        
    
    }
    
  • storeメソッドを以下のように修正します。
    返却値をMyAjaxResponseクラスに設定し@ResponseBodyを付加することでレスポンスをオブジェクトで返却できるようにします。
    @RequestMapping("store")
    public @ResponseBody MyAjaxResponse store(Model model, StoreForm storeForm) throws IOException {
    
        //ユーザコンテキストを取得します。
        UserContext userProfile = Contexts.get(UserContext.class);
        //アカウントコンテキストからタイムゾーンを取得します。
        AccountContext accountContext = Contexts.get(AccountContext.class);
        DateTimeFormatter formatter = DateTimeFormatter.withPattern("yyyy/MM/dd HH:mm");
    
        //登録値の設定
        MfwSample insertData = new MfwSample();
        // 略
        // storeFormからinsertDataへコピー
    
        insertData.setTodoId(new Identifier().get());
        insertData.setUserCd(userProfile.getUserProfile().getUserCd());
        insertData.setUserNm(userProfile.getUserProfile().getUserName());
        insertData.setTimestmp(formatter.format(DateTime.now(accountContext.getTimeZone())));
    
        MyAjaxResponse responseObject = new MyAjaxResponse();
        try {
            //登録処理実行
            mfwSampleService.store(insertData);
    
            //成功時
            responseObject.setResult("success");
            responseObject.setError(false);
            responseObject.setSuccessMessage("登録が完了しました。");
         } catch (Exception e) {
            responseObject.setError(true);
            responseObject.setErrorMessage("データ登録時にエラーが発生しました。");
            responseObject.setDetailMessages(new String[] {"管理者にお問い合わせください。"});
         }
    
        return responseObject;
    }
    
  • マークアップ結果。登録ボタン押下後にダイアログが表示され、登録処理が正常終了したことが確認できるようになりました。
    ../../../../../_images/ajax-success.PNG

コラム

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

  • クライアントから非同期でリクエストを送信するにはimspAjaxSend関数を使う

最終結果

  • jp.co.intra_mart.sample.spring.imsp.app.store.StoreController.java

    package jp.co.intra_mart.sample.spring.imsp.app.store;
    
    import java.io.IOException;
    
    import javax.inject.Inject;
    
    import jp.co.intra_mart.foundation.context.Contexts;
    import jp.co.intra_mart.foundation.context.model.AccountContext;
    import jp.co.intra_mart.foundation.i18n.datetime.DateTime;
    import jp.co.intra_mart.foundation.i18n.datetime.format.DateTimeFormatter;
    import jp.co.intra_mart.foundation.service.client.information.Identifier;
    import jp.co.intra_mart.foundation.user_context.model.UserContext;
    import jp.co.intra_mart.sample.spring.imsp.domain.model.MfwSample;
    import jp.co.intra_mart.sample.spring.imsp.service.MfwSampleService;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    @RequestMapping("sample/spring/sp/store")
    public class StoreController {
        
        @Inject
        MfwSampleService mfwSampleService; 
        
        @ModelAttribute   
        public StoreForm setupStoreForm() {
            return new StoreForm();
        }
        
        @RequestMapping
        public String index(Model model) {
            return "sample/spring/imsp/store/index.jsp";
        }
        
        @RequestMapping("store")
        public @ResponseBody MyAjaxResponse store(Model model, StoreForm storeForm) throws IOException {
          
            //ユーザコンテキストを取得します。
            UserContext userProfile = Contexts.get(UserContext.class);
            //アカウントコンテキストからタイムゾーンを取得します。
            AccountContext accountContext = Contexts.get(AccountContext.class);
            DateTimeFormatter formatter = DateTimeFormatter.withPattern("yyyy/MM/dd HH:mm");
    
            //登録値の設定
            MfwSample insertData = new MfwSample();
            // 略
            // storeFormからinsertDataへコピー
    
            insertData.setTodoId(new Identifier().get());
            insertData.setUserCd(userProfile.getUserProfile().getUserCd());
            insertData.setUserNm(userProfile.getUserProfile().getUserName());
            insertData.setTimestmp(formatter.format(DateTime.now(accountContext.getTimeZone())));
            
            MyAjaxResponse responseObject = new MyAjaxResponse();
            try {
                //登録処理実行
                mfwSampleService.store(insertData);
    
                //成功時
                responseObject.setResult("success");
                responseObject.setError(false);
                responseObject.setSuccessMessage("登録が完了しました。");
             } catch (Exception e) {
                responseObject.setError(true);
                responseObject.setErrorMessage("データ登録時にエラーが発生しました。");
                responseObject.setDetailMessages(new String[] {"管理者にお問い合わせください。"});
             }
            
            return responseObject; 
        }
    }
    
  • %CONTEXT_PATH%/WEB-INF/views/sample/spring/imsp/store/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>
            var rules = {
                "title": {
                    required:true,
                    maxlength:20
                },
                "limit_date": {
                    required:true,
                    date:true
                }
            };
            var messages = {
                "title": {
                    required:"タイトルは必須です。",
                    maxlength:"タイトルは20文字以内で入力してください"
                },
                "limit_date": {
                    required:"期限は必須です。",
                    maxlength:"期限は日付形式で入力してください"
                }
            };
        </script>
        <script>
            (function($){
                $('#main').bind("pagecreate create", function() {
                    // Formのダブルクリック防止
                    $('#storeForm').imspDisableOnSubmit();
                    $("#storeButton").unbind().tap(function() {
                        //入力チェック実行
                        if (imspValidate('#storeForm', rules, messages)) {
                            //Ajaxでのデータ送信
                            imspAjaxSend('#storeForm', 'POST', 'json');
                            //バリデーションのリセット
                            imspResetForm('#storeForm');
                        }
                    });
                });
            })(jQuery);
        </script>
        <imsp:headerWithLink headerText="TODO登録" />
        <div data-role="content">
            <form name="storeForm" id="storeForm" method="POST" action="sample/spring/sp/store/store" data-ajax="false">
                <imsp:fieldContain label="TODO名" required="true">
                <input type="text" name="title" />
                </imsp:fieldContain>
    
                <imsp:fieldContain label="期限" required="true">
                <imsp:datePicker name="limitDate" />
                </imsp:fieldContain>
    
                <imsp:fieldContain label="コメント">
                <textarea name="comment"></textarea>
                </imsp:fieldContain>
    
                <imsp:controlGroup label="重要度">
                <imsp:radioButton name="priority" id="radio1" value="0" label="低" />
                <imsp:radioButton name="priority" id="radio2" value="1" label="中" />
                <imsp:radioButton name="priority" id="radio3" value="2" label="高" />
                </imsp:controlGroup>
    
                <imsp:fieldContain label="進捗">
                <imsp:slider name="progress" min="<%=0 %>" max="<%=100 %>" />
                </imsp:fieldContain>
    
                <imsp:fieldContain label="完了">
                <imsp:toggle name="complete" onLabel="完了" offLabel="未完了" onValue="1" offValue="0" />
                </imsp:fieldContain>
    
                <a data-role="button" data-theme="b" id="storeButton">登録</a>
            </form>
        </div>
        <imsp:commonFooter dataPosition="fixed" />
    </div>
    
  • jp.co.intra_mart.sample.spring.imsp.app.store.StoreForm.java

    package jp.co.intra_mart.sample.spring.imsp.app.store;
    
    public class StoreForm {
        private String title;
        private String limitDate;
        private String comment;
        private String priority;
        private String progress;
        private String complete;
        
        public String getTitle() {
            return title;
        }
        public void setTitle(String title) {
            this.title = title;
        }
        public String getLimitDate() {
            return limitDate;
        }
        public void setLimitDate(String limitDate) {
            this.limitDate = limitDate;
        }
        public String getComment() {
            return comment;
        }
        public void setComment(String comment) {
            this.comment = comment;
        }
        public String getPriority() {
            return priority;
        }
        public void setPriority(String priority) {
            this.priority = priority;
        }
        public String getProgress() {
            return progress;
        }
        public void setProgress(String progress) {
            this.progress = progress;
        }
        public String getComplete() {
            return complete;
        }
        public void setComplete(String complete) {
            this.complete = complete;
        }
    }
    
  • jp.co.intra_mart.sample.spring.imsp.app.store.MyAjaxResponse.java

    package jp.co.intra_mart.sample.spring.imsp.app.store;
    
    public class MyAjaxResponse {
        private String result;
        private boolean error;
        private String errorMessage;
        private String successMessage;
        private String[] detailMessages;
        
        public String getResult() {
            return result;
        }
        public void setResult(String result) {
            this.result = result;
        }
        public boolean isError() {
            return error;
        }
        public void setError(boolean error) {
            this.error = error;
        }
        public String getErrorMessage() {
            return errorMessage;
        }
        public void setErrorMessage(String errorMessage) {
            this.errorMessage = errorMessage;
        }
        public String getSuccessMessage() {
            return successMessage;
        }
        public void setSuccessMessage(String successMessage) {
            this.successMessage = successMessage;
        }
        public String[] getDetailMessages() {
            return detailMessages;
        }
        public void setDetailMessages(String[] detailMessages) {
            this.detailMessages = detailMessages;
        }
        
    
    }
    
  • jp.co.intra_mart.sample.spring.imsp.domain.model.MfwSample.java

    package jp.co.intra_mart.sample.spring.imsp.domain.model;
    
    import java.io.Serializable;
    import java.math.BigDecimal;
    
    public class MfwSample implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        private String todoId;
    
        private String comment;
    
        private String complete;
    
        private String limitDate;
    
        private String priority;
    
        private BigDecimal progress;
    
        private String timestmp;
    
        private String title;
    
        private String userCd;
    
        private String userNm;
    
        public MfwSample() {
        }
    
        public String getComment() {
            return comment;
        }
    
        public String getComplete() {
            return complete;
        }
    
        public String getLimitDate() {
            return limitDate;
        }
    
        public String getPriority() {
            return priority;
        }
    
        public BigDecimal getProgress() {
            return progress;
        }
    
        public String getTimestmp() {
            return timestmp;
        }
    
        public String getTitle() {
            return title;
        }
    
        public String getTodoId() {
            return todoId;
        }
    
        public String getUserCd() {
            return userCd;
        }
    
        public String getUserNm() {
            return userNm;
        }
    
        public void setComment(final String comment) {
            this.comment = comment;
        }
    
        public void setComplete(final String complete) {
            this.complete = complete;
        }
    
        public void setLimitDate(final String limitDate) {
            this.limitDate = limitDate;
        }
    
        public void setPriority(final String priority) {
            this.priority = priority;
        }
    
        public void setProgress(final BigDecimal progress) {
            this.progress = progress;
        }
    
        public void setTimestmp(final String timestmp) {
            this.timestmp = timestmp;
        }
    
        public void setTitle(final String title) {
            this.title = title;
        }
    
        public void setTodoId(final String todoId) {
            this.todoId = todoId;
        }
    
        public void setUserCd(final String userCd) {
            this.userCd = userCd;
        }
    
        public void setUserNm(final String userNm) {
            this.userNm = userNm;
        }
    }
    
  • jp.co.intra_mart.sample.spring.imsp.domain.repository.MfwSampleRepository.java

    package jp.co.intra_mart.sample.spring.imsp.domain.repository;
    
    import jp.co.intra_mart.sample.spring.imsp.domain.model.MfwSample;
    
    public interface MfwSampleRepository {
    
        void create(MfwSample entity);
    }
    
  • jp.co.intra_mart.sample.spring.imsp.domain.service.MfwSampleService.java

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

    package jp.co.intra_mart.sample.spring.imsp.service;
    
    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.create(entity);
        }
    }