メール配信画面
<layout:form action="/sendMail" styleClass="FORM" reqCode="sendMail"> <layout:message key="mail.step1" styleClass="LABELLEFT"/> <layout:row> <layout:swap property="isbn,isbn" formProperty="ids1,ids2" selectedStyleClass="FORMSWAP"> <layout:collection name="list1" styleClass="FORM"> <layout:collectionItem title="book.isbn" property="isbn"/> <layout:collectionItem title="book.name" property="name"/> </layout:collection> <layout:collection name="list2" styleClass="FORM"> <layout:collectionItem title="book.isbn" property="isbn"/> <layout:collectionItem title="book.name" property="name"/> </layout:collection> </layout:swap> </layout:row> <layout:message key="mail.step2" styleClass="LABELLEFT"/> <layout:text key="mail.email" property="email" styleClass="LABEL" isRequired="true" /> <layout:submit><bean:message key="mail.send"/></layout:submit> </layout:form>
public class MailForm extends DefaultForm { private String email; private String[] ids1; private String[] ids2; //(中略) }
この画面は一覧より書籍情報を選択して、入力したメールアドレスへ送信する画面です。一覧で表示される書籍情報から任意の項目を選択し、矢印ボタンを押下することで、選択した項目がテーブル間を移動します。
このように、一覧から複数項目を選択する手段を提供するタグが、次に紹介する<layout:swap>
タグです。
Swapの実装
<layout:swap>
タグは2つのテーブル間で行を交換する(Swap)処理を実装するためのタグです。<layout:swap>
タグで2つの<layout:collection>
タグをネストすることでSwap処理をするテーブルを定義することができます。そして<layout:swap>
タグのproperty
属性に、カンマ区切りで2つコレクションの、<layout:collectionItem>
タグでキーにあたるproperty
属性を指定します。
またformProperty
属性には2つのテーブルに格納されるキー項目が設定されるActionFormのプロパティを指定します。こうすることで、Submit実行時に2つのテーブルのキー項目にあたるisbn
番号が、それぞれActionFormのids1
,ids2
に設定されます。
メール配信する行を選択し、メールアドレスを入力したら[メール送信]ボタンを押下して下さい。メール配信結果画面へ遷移します。
<layout:swap>
タグを実装するためには、「swap.js」ファイルをリンクする必要があります。リソースへのアクセスには<layout:resource>
タグを利用します。
<script language="JavaScript"
src="<layout:resource type="cfg" name="swap.js"/>"/>
BreadCrumbの実装
画面数が多く、階層の深い画面構成を持つシステムを利用するユーザは、自分がいる画面を見失いがちです。そこで便利なのがBreadCrumbです。
本システムでは画面数が少ないためメリットを感じることは少ないかと思いますが、ユーザはメール機能の中で、現在どの操作をしているのかを知ることができます。
<layout:crumbs styleClass="CRUMBS" separator=">"> <layout:crumb key="crumb.mail"/> <layout:crumb key="crumb.sendMail" link="/sendMail.do?reqCode=list"/> </layout:crumbs>
Crumbs
もサーバサイドで動的に作成することが可能です。Crumbs
情報をHttpSessionに格納し、画面遷移をする度にCrumb
を追加、削除すると、より便利に使うことができるでしょう。ユーザ管理画面(データグリッド版)
前回Struts-Layoutの大きな特徴のひとつであるディスプレイモードを紹介しましたが、Struts-LayoutではJSPの実装を簡単にし、かつユーザビリティも向上させる<layout:datagrid>
タグも提供されています。
前回ディスプレイモードで実装したユーザ管理画面を、今回はデータグリッド形式で実装してありますので、メニューより[ユーザ管理]の[データグリッド版]を選択して、画面を見てみましょう。
DataGridの実装
public class UserForm extends DefaultForm { private Datagrid users; public Datagrid getUsers() { return users; } public void setUsers(Datagrid datagrid) { users = datagrid; } //(中略) }
ActionFormではfr.improve.struts.taglib.layout.datagrid.Datagrid
クラスの変数とそのGetter/Setterを実装しています。
public class UserAction extends DispatchAction { /** * 編集画面オープン時の処理を行う */ public ActionForward datagridEdit(ActionMapping mapping, ActionForm actionform, HttpServletRequest request, HttpServletResponse response) throws Exception { UserForm form = (UserForm) actionform; // ユーザ一覧の取得 List users = UserDao.getInstance().findAll(); // DataGridインスタンスの生成 Datagrid datagrid = Datagrid.getInstance(); // DataGridの初期化 datagrid.setData(users); datagrid.setDataClass(User.class); form.setUsers(datagrid); //モードの初期化 FormUtils .setFormDisplayMode(request, actionform, FormUtils.EDIT_MODE); return mapping.findForward("datagrid"); } /** * 編集実行時の処理を行う */ public ActionForward datagridSave(ActionMapping mapping, ActionForm actionform, HttpServletRequest request, HttpServletResponse response) throws Exception { UserForm form = (UserForm) actionform; // ActionFormからDatagridを取得 Datagrid datagrid = form.getUsers(); // 登録処理 Collection added = datagrid.getAddedData(); Iterator it = added.iterator(); while (it.hasNext()) { User newUser = (User) it.next(); //項目に値が入力されていれば永続化する if (newUser.getId()!=null && newUser.getId().length()!=0 && newUser.getPassword() !=null && ewUser.getPassword().length()!=0) { //既に存在しているデータでなければ永続化する if (UserDao.getInstance().getUserByPrimaryKey( newUser.getId())==null) { UserDao.getInstance().addUser(newUser); } } } // 削除処理 Collection removed = datagrid.getDeletedData(); it = removed.iterator(); while (it.hasNext()) { User removedUser = (User) it.next(); UserDao.getInstance().deleteUser(removedUser); } // 更新処理 Collection modified = datagrid.getModifiedData(); it = modified.iterator(); while (it.hasNext()) { User modifiedUser = (User) it.next(); try { UserDao.getInstance().updateUser(modifiedUser); } catch (InvalidParameterException e) { } } // Datagridを初期化 datagrid.setData(UserDao.getInstance().findAll()); return mapping.findForward("datagrid"); } }
データグリッドを利用するには、一覧データがfr.improve.struts.taglib.layout.datagrid.Datagrid
インスタンスに設定されていなくてはなりません。Action
クラスでは、ユーザ管理画面オープン時にUserDao
よりユーザ一覧を取得し、setData
メソッドでユーザ一覧をDataGridに設定しています。またsetDataClass
メソッドでUser
クラスを設定しています。
このようにDataGridは一覧データだけではなく格納されるクラス情報も保持する必要があるため、DataGridを保持する変数のスコープはSessionで設定する必要があります。
<layout:datagrid property="users" styleClass="DATAGRID" model="datagrid"> <layout:datagridColumn title="user.id" property="id"/> <layout:datagridColumn title="user.password" property="password"/> </layout:datagrid> <layout:row> <layout:button onclick="StrutsLayout.addDatagridLine('users')"> <bean:message key="addLine.action"/></layout:button> <layout:button onclick="StrutsLayout.setDatagridLineState( 'users', 'removed')"> <bean:message key="delete.action"/></layout:button> <layout:submit><bean:message key="submit.action"/></layout:submit> </layout:row>
jspでは<layout:datagrid>
タグで表示する一覧を指定し、<datagridColumn>
タグで一覧表示するカラムを指定します。
<layout:datagridSelect>
タグと<layout:datagridCheckbox>
タグに関するアナウンスがあったもののリリースはされていません。今後対応されるでしょう。また、ダウンロードしたままのStruts-LayoutではCSSにDatagridに関する定義が無いため、利用するCSSへ次の定義が必要です。
TABLE.DATAGRID { background-color : #336699; } TH.DATAGRID { color : #FFFFFF; background-color : #336699; font-weight: bold; font-family : verdana; } TABLE.DATAGRID TR TD { font-family : verdana; padding: 2px; } TR.DATAGRID { background-color : #FFFFFF; } TR.DATAGRID2 { background-color : #FFFFFF; } .DATAGRID_SEL { background-color : #336699; } .DATAGRID_DEL { text-decoration: line-through; } TR.DATAGRID_DEL TD INPUT { text-decoration: line-through; } TABLE.DATAGRID TR TD INPUT { width: 100%; }