- PR -

繰り返し入力フィールドと表示のみのフィールドの混在方法

投稿者投稿内容
マリン
常連さん
会議室デビュー日: 2006/05/28
投稿数: 41
投稿日時: 2007-06-06 16:19
マーサ様、ご回答ありがとうございます。

detail(ListFormのdetailListで保持しているインナークラスオブジェクト)は入力・更新に関わるコード・数量・備考のプロパティだけでpojo(表示のみの情報も含まれる商品明細を表現するクラスのオブジェクト)そのものは格納していません。ただし、Actionクラス内で具体的には以下のようにしてコード・数量・備考をコピーして同じ配列数になるように構築しています。
コード:
// データベースから商品明細のリストを取得&セット
List syohinList = getHibernateTemplate().find(…); //←実際には別のDAOクラスメソッドです
request.setAttribute("list", syohinList);

// フォームにコピー
ListForm listForm = (ListForm)form;
listForm.getDetailList().clear();
Iterator ite = list.iterator();
while (ite.hasNext()) {
    SyohinPojo pojo = (SyohinPojo)ite.next();
    ListForm.Detail detail = listForm.new Detail();
    detail.setCode(pojo.getCode());
    detail.setAmount(pojo.getAmount().toString());
    detail.setNode(pojo.getNote());
    listForm.getDetailList().add(detail);
}

return mapping.findForward("success");



それから以下のようになるというのがよくわかりません。
detail[0]
 pojo[0]
 pojo[1]
 …
detail[1]
 pojo[0]
 pojo[1]
 …
logic:iterateをネストすれば当然こういったイメージになるかと思いますが、私が提示させていただいたjspでその部分は<logic:iterate id="pojo" name="list" offset="${i}"/>というようにしていますので、ループではなくpojoにlistのi番目がセットされるだけになるかと思うのですが…?それでループとしてlogic:iterateを使用しているわけではないことに対する違和感を前回の投稿で申し上げた次第です。

なんとなく私の意図が皆様にうまく伝わっていないような気がするのですが気のせいでしょうか?
冗長になりそうだったので商品明細情報を表現するクラスやActionFormクラスの提示を避けてなるべく文章で説明させていただいたのですが、やはり具体的なソースを提示させていただいた方がよろしいでしょうか?
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-06-06 16:34
引用:

マリンさんの書き込み (2007-06-06 16:19) より:
なんとなく私の意図が皆様にうまく伝わっていないような気がするのですが気のせいでしょうか?
冗長になりそうだったので商品明細情報を表現するクラスやActionFormクラスの提示を避けてなるべく文章で説明させていただいたのですが、やはり具体的なソースを提示させていただいた方がよろしいでしょうか?



状況を伝えるというのは難しいことです。
私もマリン氏が問おうとしてる問題の本質を掴みかねています。
ミニマムな再現環境というか、問題を体現しているコードを提示するのは良い方法論です。
どうも意図が伝わっていないなと思うのであれば、納得いくまで認識のすりあわせを行ってください。

# この問題点の認識あわせの時点で根負けしてしまう質問者も多いです…。
civi
会議室デビュー日: 2003/08/15
投稿数: 2
投稿日時: 2007-06-06 17:31
参考にしたサイトの作者です。(参考にしていただいてありがとうございます)

引用:

ただ、商品名等はHTMLエンコードが必要な文字も含まれる可能性があるのでEL式形式ではなく、ヒントをいただいたbean:writeタグで表示させたいのですが、


EL形式でも、coreタグのoutや、functionsタグのescapeXmlを使えば、エンコードして出力しますが、どうしてもStrutsタグを使う前提なのでしょうか?

Strutsタグはこういった面で不便なので、私はJSTLを使っています。
i番目の要素を取り出すために、1回だけループするようなiterateタグをかかなければならないんですかねぇ。

私だったら、pojoListからpojoの要素を取り出すところは、もうスクリプトレットで書いちゃいますけど。(もしくはpojoListをActionFormから参照できるようにしちゃう。)
マーサ
ベテラン
会議室デビュー日: 2004/11/26
投稿数: 87
投稿日時: 2007-06-06 17:35
引用:

マリンさんの書き込み (2007-06-06 16:19) より:

logic:iterateをネストすれば当然こういったイメージになるかと思いますが、私が提示させていただいたjspでその部分は<logic:iterate id="pojo" name="list" offset="${i}"/>というようにしていますので、ループではなくpojoにlistのi番目がセットされるだけになるかと思うのですが…?それでループとしてlogic:iterateを使用しているわけではないことに対する違和感を前回の投稿で申し上げた次第です。


失礼しました、閉じてましたねm(_ _)m
ところで、一行で閉じたときのスコープってどうなるんでしたっけ・・・?
vlkr
会議室デビュー日: 2005/12/02
投稿数: 6
投稿日時: 2007-06-06 17:36
はじめまして。

syohinListを何らかのBean(例えばPojoListBean)のフィールドとしてセットしてあげれば、
コード:
<bean:define id="pojo" name="PojoListBean" property="shohinList[${i}]" />


などとしてshohinList中の任意のindexにアクセスできるかと思います。
今回の場合、syohinListが直にrequestにセットされているのがネックになっているのかと思いました。

Strutsでは、requestにセットされているListに対して
コード:
<bean:define id="pojo" name="shohinList[${i}]" />



コード:
<bean:define id="pojo" name="shohinList" property="${i}" />


といったアクセスの仕方は出来ないんですよね。

私だったら、shohinListを直にrequestにセットせずに、上記のようにBeanのフィールドとして持たせるようにします。(ListFormに持たせてしまうかも)

また、今回の例のように一覧の中に入力フィールドを設ける画面の場合は、恐らくnested:iterateやnested:textタグを使用するのがよいかと思います。
(コードとして提示する際にあえてそうしていたのなら、余計な突っ込みすいません。。)


あと、マーサさんが指摘しているのは、
コード:
<logic:iterate id="pojo" name="list" offset="${i}"/>


は、length="1"を書かないとまずい。ということかと。(そうしないと最後まで回ってしまう)
コード:
<logic:iterate id="pojo" name="list" offset="${i}" length="1"/>

マーサ
ベテラン
会議室デビュー日: 2004/11/26
投稿数: 87
投稿日時: 2007-06-06 17:56
引用:

civiさんの書き込み (2007-06-06 17:31) より:
i番目の要素を取り出すために、1回だけループするようなiterateタグをかかなければならないんですかねぇ。



引用:

vlkrさんの書き込み (2007-06-06 17:36) より:

コード:
<bean:define id="pojo" name="PojoListBean" property="shohinList[${i}]" />



書きたかったのは、実はこっち(bean:define)だったのかなぁ?

引用:

コード:
<logic:iterate id="pojo" name="list" offset="${i}"/>


は、length="1"を書かないとまずい。ということかと。(そうしないと最後まで回ってしまう)
コード:
<logic:iterate id="pojo" name="list" offset="${i}" length="1"/>



補足有難うございますm(_ _)m


#タグ関連の本は1冊持っていても良いかもしれませんね。
#やりたいことを探していると何気に発見出来ますよ。
#ネットでも検索すれば出てきますけど。
vlkr
会議室デビュー日: 2005/12/02
投稿数: 6
投稿日時: 2007-06-06 17:58
連投すみません。
今確認してみたら、length属性は無くていいんですね。
logic:iterateをボディ無しで閉じる場合の挙動を把握せずに発言してしまいました。
申し訳ありません。

コード:
<logic:iterate id="pojo" name="list" offset="${i}"/>


これの動きは、結果として
「listのi番目のObjectを"pojo"とう名前でpageスコープにセットする」
となるようです。

#念のため追記です
ボディ有りのiterateの場合は、length属性を省略するとoffset以降最後までループします。

[ メッセージ編集済み 編集者: vlkr 編集日時 2007-06-06 18:07 ]
朝日奈ありす
大ベテラン
会議室デビュー日: 2007/05/02
投稿数: 189
お住まい・勤務地: 最北の地
投稿日時: 2007-06-06 19:47
コード:
<table>
    <tr><th>コード</th><th>名称</th><th>価格</th>…<th>数量</th><th>備考</th><tr>
    <logic:iterate id="detail" name="ListForm" property="detailList" indexId="i">
        <%-- listからi番目の要素をpojoに取得 --%>
        <logic:iterate id="pojo" name="list" offset="${i}"/>
        <tr>
            <td>
                <html:hidden name="detail" property="code" indexed="true"/>
                ${detail.code}
            </td>
            <td><bean:write name="pojo" property="name"/></td>
            <td><bean:write name="pojo" property="price"/></td>
            …
            <td><html:text name="detail" property="amount" indexed="true"/></td>
            <td><html:text name="detail" property="note" indexed="true"/></td>
        </tr>
    </logic:iterate>
</table>


とあるけど
コード:
            <td><html:text name="detail" property="amount" indexed="true"/></td>


だと
[code]

<input type="text" name="code[0].amout[0]" />

<input type="text" name="code[1].amout[1]" />

<input type="text" name="code[2].amout[2]" />


2次元配列の斜めにとっていったような気もする。
配列またはListじゃなかったら getter がないとかでたきも

スキルアップ/キャリアアップ(JOB@IT)