#はじめに
Ajaxボタンをクリックすることでテーブル内の要素の値が増えるページを作りたい。
ただし、決まった数増えたら一段下に増えるように。
#完成画面 キャプチャ
http://cl.ly/image/3h2u0L3L1O1w
#過程(1) 2014/12/19
モックアップのhtmlと空のjavaを作成
package page;
import org.apache.wicket.markup.html.WebPage;
/**
* ボタンで動的に要素の値を追加するテーブルを作る
*
* @author IS masaki okabe
*
*/
public class Page extends WebPage {
private static final long serialVersionUID = -2093104879611846359L;
public Page() {
}
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"
lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div style="width: 800px; margin: 100px">
<h2>ajaxボタンで動的に変化するtableを作りたい</h2>
<h2>前</h2>
<table border="1px">
<thead>
<tr>
<th style="width: 130px; text-align: center">カラム1</th>
<th style="width: 130px; text-align: center">カラム2</th>
<th style="width: 130px; text-align: center">カラム3</th>
<th style="width: 130px; text-align: center">カラム4</th>
<th style="width: 130px; text-align: center">カラム5</th>
<th style="width: 130px; text-align: center">カラム6</th>
<th style="width: 130px; text-align: center">カラム7</th>
<th style="width: 50px; text-align: center"></th>
</tr>
</thead>
<tbody>
<tr align="center">
<td rowspan="4">A</td>
<td>B</td>
<td>
<div>
<a href="#">1</a>
</div>
</td>
<td>
<div>
<a href="#">2</a>
</div>
</td>
<td>
<div>
<a href="#">3</a>
</div>
</td>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
<td>
<div>
<a href="#"> <span> + </span>
</a>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
テーブル内の繰り返し部分(カラム3〜7)をListViewに
~略~
public Page() {
//テーブルにデフォルトセットされているデータを用意
List<String> tdDatas = new ArrayList<String>();
tdDatas.add("1番目");
tdDatas.add("2番目");
tdDatas.add("3番目");
tdDatas.add("4番目");
tdDatas.add(""); // ※投稿本文で説明
//tdDatasを保持するModelを用意
IModel<List<String>> tdListViewModel = new ListModel<String>(tdDatas);
//テーブルのカラム3〜7の値を決めるListView
ListView<String> tdListView = new ListView<String>("tdListView",tdListViewModel) {
private static final long serialVersionUID = -5282734444412568671L;
@Override
protected void populateItem(ListItem<String> item) {
Link<Void> data = new Link<Void>("data"){
private static final long serialVersionUID = 1301603993310363062L;
@Override
public void onClick() {
}
};
data.add(new Label("dataLabel", item.getModelObject()));
item.add(data);
}
};
this.add(tdListView);
}
}
~略~
<tbody>
<tr align="center">
<td rowspan="4">A</td>
<td>B</td>
<td wicket:id="tdListView">
<div>
<a href="#" wicket:id="data"><span wicket:id="dataLabel">ここにデータラベルが入る</span></a>
</div>
</td>
<td>
<div>
<a href="#"> <span> + </span></a>
</div>
</td>
</tr>
</tbody>
~略~
※Page.java内で空文字をtdDatasnにaddしているのは、
ListViewで吐き出される<td>要素の数がカラム数と合っていない場合、表示がおかしくなるから。
こうしたいのに↓
#過程(2) 2015/01/05
複数列になった場合でも繰り返したいカラム(カラム3〜7)と、
そうでないカラム(カラム1、2、+ボタン)の順番が崩れないようなListViewを作成
~略~
public Page() {
List<List<String>> datas = new ArrayList<List<String>>();
//テーブルにデフォルトセットされているデータを用意
List<String> tdDatas = new ArrayList<String>();
tdDatas.add("1番目");
tdDatas.add("2番目");
tdDatas.add("3番目");
tdDatas.add("4番目");
tdDatas.add("5番目");
//2列目のデータ
List<String> tdDatas2 = new ArrayList<String>();
tdDatas2.add("2列目1番目");
tdDatas2.add("");
tdDatas2.add("");
tdDatas2.add("");
tdDatas2.add("");
datas.add(tdDatas);
datas.add(tdDatas2);
//列を制御するリストビュー
IModel<List<List<String>>> rowListViewModel = new ListModel<List<String>>(datas);
//テーブルのカラム3〜7の値を決めるListView
ListView<List<String>> rowListView = new ListView<List<String>>("rowListView",rowListViewModel) {
private static final long serialVersionUID = -5282734444412568671L;
@Override
protected void populateItem(ListItem<List<String>> item) {
//カラム1&2のラベル
Label column1 = new Label("column_1","A");
Label column2 = new Label("column_2","B");
//+ボタンのリンク
Link<Void> addDataButton = new Link<Void>("addDataButton"){
private static final long serialVersionUID = 1301603993310363062L;
@Override
public void onClick() {
System.out.println("click");
}
};
//2列目以降は上記コンポーネントを非表示に
if(item.getIndex() > 0){
column1.setVisible(false);
column2.setVisible(false);
addDataButton.setVisible(false);
}
//カラムのデータを保持するModelを用意
IModel<List<String>> columnListViewModel = new ListModel<String>(item.getModelObject());
//カラムを表示するリストビュー
ListView<String> columnListView = new ListView<String>("columnListView",columnListViewModel) {
private static final long serialVersionUID = -5282734444412568671L;
@Override
protected void populateItem(ListItem<String> item) {
Link<Void> data = new Link<Void>("data"){
private static final long serialVersionUID = 1301603993310363062L;
@Override
public void onClick() {
}
};
data.add(new Label("dataLabel", item.getModelObject()));
item.add(data);
}
};
item.add(columnListView);
item.add(column1,column2,addDataButton);
}
};
this.add(rowListView);
}
~略~
現在の画面
wicketのコンポーネントを使って正しい形の表を出力できた。
まだ動的にカラムデータが変化しない。
#最終過程(3) 2015/01/05-2
ボタンを押すことで空のカラムへ値が増えるように。空のカラムがない場合は一行増やす。
動作キャプチャ
http://cl.ly/image/3h2u0L3L1O1w
~略~
public Page() {
//tbody用WMC
final WebMarkupContainer tbodyWMC = new WebMarkupContainer("tbodyWMC"){
private static final long serialVersionUID = -2217415656725425892L;
@Override
protected void onInitialize() {
super.onInitialize();
setOutputMarkupId(true);
}
};
this.add(tbodyWMC);
List<List<String>> datas = new ArrayList<List<String>>();
//テーブルにデフォルトセットされているデータを用意
List<String> tdDatas = Arrays.asList("1番目","2番目","3番目","4番目","5番目");
//2列目のデータ
List<String> tdDatas2 = Arrays.asList("2列目1番目","2列目2番目","","","");
datas.add(tdDatas);
datas.add(tdDatas2);
//列を制御するリストビュー
final IModel<List<List<String>>> rowListViewModel = new ListModel<List<String>>(datas);
//テーブルのカラム3〜7の値を決めるListView
ListView<List<String>> rowListView = new ListView<List<String>>("rowListView",rowListViewModel) {
private static final long serialVersionUID = -5282734444412568671L;
@Override
protected void populateItem(final ListItem<List<String>> item) {
//カラム1&2のラベル
Label column1 = new Label("column_1","A");
Label column2 = new Label("column_2","B");
//+ボタンのリンク
AjaxLink<Void> addDataButton = new AjaxLink<Void>("addDataButton"){
private static final long serialVersionUID = 1301603993310363062L;
//リストの末尾に新しい値を一つ追加し、tbodyを更新する
@Override
public void onClick(AjaxRequestTarget target) {
addNewValue(rowListViewModel.getObject());
target.add(tbodyWMC);
}
};
//2列目以降は上記コンポーネントを非表示に
if(item.getIndex() > 0){
column1.setVisible(false);
column2.setVisible(false);
addDataButton.setVisible(false);
}
//カラムのデータを保持するModelを用意
IModel<List<String>> columnListViewModel = new ListModel<String>(item.getModelObject());
//カラムを表示するリストビュー
ListView<String> columnListView = new ListView<String>("columnListView",columnListViewModel) {
private static final long serialVersionUID = -5282734444412568671L;
@Override
protected void populateItem(ListItem<String> item) {
Link<Void> data = new Link<Void>("data"){
private static final long serialVersionUID = 1301603993310363062L;
@Override
public void onClick() {
}
};
data.add(new Label("dataLabel", item.getModelObject()));
item.add(data);
}
};
item.add(columnListView);
item.add(column1,column2,addDataButton);
}
};
tbodyWMC.add(rowListView);
}
//横幅5個、縦幅不定数の2次元リストの横軸の末尾に新しい値を追加する。
//横幅の端に到達したら縦幅を一段伸ばして、新しい値を追加する。
public void addNewValue(List<List<String>> listList){
boolean setFlag = true;
for(List<String> list : listList){
for(int i = 0; i < list.size(); i++){
if(list.get(i).isEmpty()){
list.set(i, "新しい値");
setFlag = false;
break;
}
}
}
if(setFlag){
List<String> list = Arrays.asList("新しい値","","","","");
listList.add(list);
}
}
~略~
<tbody wicket:id="tbodyWMC">
<wicket:container wicket:id="rowListView">
<tr align="center">
<td rowspan="99" wicket:id="column_1"></td>
<td rowspan="99" wicket:id="column_2"></td>
<td wicket:id="columnListView">
<div>
<a href="#" wicket:id="data"><span wicket:id="dataLabel">ここにデータラベルが入る</span></a>
</div>
</td>
<wicket:enclosure>
<td rowspan="99" wicket:id="addDataButton">
<span> + </span>
</td>
</wicket:enclosure>
</tr>
</wicket:container>
</tbody>
#まとめ
2重リストをListViewで回して値を出力し、
値の追加時に画面更新を行った。
値が動的に変化しないカラム(カラム1、2、+ボタン)は、
2行目以降表示されないように表示フラグをoffに変更。
#終わりに
作業ステップがわかるように書いたことが、いつか身を助けますように。
Qiitaはgif動画の埋め込みができなくて残念。
コードの行数を表示する方法はあるのかな。