1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

wicket: Ajaxボタンで動的に値を追加するテーブルを作る

Last updated at Posted at 2014-12-19

#はじめに
Ajaxボタンをクリックすることでテーブル内の要素の値が増えるページを作りたい。
ただし、決まった数増えたら一段下に増えるように。

#完成予想図
イメージ図.jpeg

#完成画面 キャプチャ
http://cl.ly/image/3h2u0L3L1O1w

#過程(1) 2014/12/19
モックアップのhtmlと空のjavaを作成

Page.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() {
	}

}
Page.html
<!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に

Page.java
~~

	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);
	}

}
Page.html
~略~
			<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>要素の数がカラム数と合っていない場合、表示がおかしくなるから。
こうしたいのに↓
スクリーンショット 2014-12-19 20.04.37.jpg

こうなる↓
スクリーンショット 2014-12-19 20.04.00.jpg

#過程(2) 2015/01/05
複数列になった場合でも繰り返したいカラム(カラム3〜7)と、
そうでないカラム(カラム1、2、+ボタン)の順番が崩れないようなListViewを作成

Page.java
~~
	
	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);
	}

~~

現在の画面
スクリーンショット 2015-01-05 12.02.59.jpg
wicketのコンポーネントを使って正しい形の表を出力できた。
まだ動的にカラムデータが変化しない。

#最終過程(3) 2015/01/05-2
ボタンを押すことで空のカラムへ値が増えるように。空のカラムがない場合は一行増やす。
動作キャプチャ
http://cl.ly/image/3h2u0L3L1O1w

Page.java
~~
	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);
		}
		
		
	}
~~
Page.html

			<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動画の埋め込みができなくて残念。

コードの行数を表示する方法はあるのかな。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?