フォームを使いこなす(続き)
複数のチェックボックスをまとめて作る
前回は複数のチェックボックスをまとめて作成するところまで作ったが、クエリ送信でエラーが発生していた。
エラーメッセージでは items must not be null と表示されていることから、${checkItems} が null であると推測できる。
コントローラで値を設定するように修正する。
MyAppController.java
@RequestMapping(value = "/helo", method = RequestMethod.POST)
public String form(@ModelAttribute FormModel formModel, Model model){
String res = "<ul><li>" + formModel.getInput1()
+ "</li><li>" + formModel.getPass1()
+ "</li><li>" + formModel.getArea1()
+ "</li><li>" + formModel.isCheck1()
+ "</li></ul>";
model.addAttribute("title", "sample");
model.addAttribute("message", res);
model.addAttribute("formModel", formModel);
model.addAttribute("checkItems", getList());
return "showMessage";
}
チェックされた要素をメッセージに追加する。
MyAppController.java
@RequestMapping(value = "/helo", method = RequestMethod.POST)
public String form(@ModelAttribute FormModel formModel, Model model){
String res = "<ul><li>" + formModel.getInput1()
+ "</li><li>" + formModel.getPass1()
+ "</li><li>" + formModel.getArea1()
+ "</li><li>" + formModel.isCheck1()
+ "</li></ul>";
String[] selected = formModel.getChecks();
res = res + "<ol>";
for (String sel : selected) {
res += "<li>" + sel + "</li>";
}
res += "</ol>";
model.addAttribute("title", "sample");
model.addAttribute("message", res);
model.addAttribute("formModel", formModel);
model.addAttribute("checkItems", getList());
return "showMessage";
}
ラベルと値を設定する
チェックボックスのラベルと値を設定するために、クラスを追加する。
javaリソースの下の src/main/java にある jp.abc パッケージを右クリックし、[新規]-[クラス]を選択する。
新規クラスのダイアログで名前に ListDataModel と入力し「完了」をクリック。
テキスト p.214 のコードを記述する。
ListDataModel.java
package jp.abc;
public class ListDataModel {
private String label;
private String data;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public ListDataModel(String label, String data) {
this.label = label;
this.data = data;
}
}
JSPの <form:checkboxes> の内部を変更する。
<tr><td>
<form:checkboxes items="${checkItems}" path="checks"
itemLabel="label" itemValue="data" delimiter=" "/>
</td></tr>
MyAppControllerでは、ListDataModel を格納した List を作るように getList() を修正する。
MyAppController.java
package jp.abc;
import java.util.ArrayList;
import java.util.List;
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.RequestMethod;
@Controller
public class MyAppController {
private List<ListDataModel> getList() {
List<ListDataModel> list = new ArrayList<ListDataModel>();
list.add(new ListDataModel("まっく", "Mac OS X"));
list.add(new ListDataModel("うぃんどうず", "Windows"));
list.add(new ListDataModel("りなくす", "Linux"));
return list;
}
@RequestMapping(value = "/helo", method = RequestMethod.GET)
public String helo(Model model) {
model.addAttribute("title", "ModelAndView sample");
model.addAttribute("message", "これはModelAndViewのテストです。");
FormModel fm = new FormModel();
fm.setCheck1(true);
fm.setChecks(new String[]{"Windows"});
model.addAttribute("formModel", fm);
model.addAttribute("checkItems", getList());
return "showMessage";
}
@RequestMapping(value = "/helo", method = RequestMethod.POST)
public String form(@ModelAttribute FormModel formModel, Model model){
String res = "<ul><li>" + formModel.getInput1()
+ "</li><li>" + formModel.getPass1()
+ "</li><li>" + formModel.getArea1()
+ "</li><li>" + formModel.isCheck1()
+ "</li></ul>";
String[] selected = formModel.getChecks();
res = res + "<ol>";
for (String sel : selected) {
res += "<li>" + sel + "</li>";
}
res += "</ol>";
model.addAttribute("title", "sample");
model.addAttribute("message", res);
model.addAttribute("formModel", formModel);
model.addAttribute("checkItems", getList());
return "showMessage";
}
}
ラジオボタンの利用
ラジオボタンは、<form:radiobutton> タグを使用する。
ラジオボタンのために、FormModel に radio1 を追加する。
FormModel.java
package jp.abc;
public class FormModel {
private String input1;
private String pass1;
private String area1;
private boolean check1;
private String[] checks;
private String radio1;
public String getInput1() {
return input1;
}
public void setInput1(String input1) {
this.input1 = input1;
}
public String getPass1() {
return pass1;
}
public void setPass1(String pass1) {
this.pass1 = pass1;
}
public String getArea1() {
return area1;
}
public void setArea1(String area1) {
this.area1 = area1;
}
public boolean isCheck1() {
return check1;
}
public void setCheck1(boolean check1) {
this.check1 = check1;
}
public String[] getChecks() {
return checks;
}
public void setChecks(String[] checks) {
this.checks = checks;
}
public String getRadio1() {
return radio1;
}
public void setRadio1(String radio1) {
this.radio1 = radio1;
}
}
JSP にラジオボタンのタグを追加する。
<form:form modelAttribute="formModel">
<tr><td>input1:<form:input path="input1"/></td></tr>
<tr><td>pass1:<form:password path="pass1" showPassword="on"/></td></tr>
<tr><td>area1:<form:textarea path="area1" cols="40" rows="3"></form:textarea></td></tr>
<tr><td><form:checkbox path="check1" label="checkbox 1"/></td></tr>
<tr><td>
<form:checkboxes items="${checkItems}" path="checks"
itemLabel="label" itemValue="data" delimiter=" "/>
</td></tr>
<tr><td><form:radiobutton path="radio1" name="radio1"
label="男性" value="male"/>
<form:radiobutton path="radio1" name="radio1"
label="女性" value="female"/>
<tr><td><input type="submit" ></td></tr>
</form:form>
GETメソッドを処理する helo() メソッドでは、1行だけ追加する。
MyAppController.java
@RequestMapping(value = "/helo", method = RequestMethod.GET)
public String helo(Model model) {
model.addAttribute("title", "ModelAndView sample");
model.addAttribute("message", "これはModelAndViewのテストです。");
FormModel fm = new FormModel();
fm.setCheck1(true);
fm.setChecks(new String[]{"Windows"});
fm.setRadio1("male");
model.addAttribute("formModel", fm);
model.addAttribute("checkItems", getList());
return "showMessage";
}
POSTメソッドを処理する form() メソッドでも1行だけの追加。
MyAppController.java
@RequestMapping(value = "/helo", method = RequestMethod.POST)
public String form(@ModelAttribute FormModel formModel, Model model){
String res = "<ul><li>" + formModel.getInput1()
+ "</li><li>" + formModel.getPass1()
+ "</li><li>" + formModel.getArea1()
+ "</li><li>" + formModel.isCheck1()
+ "</li></ul>";
String[] selected = formModel.getChecks();
res = res + "<ol>";
for (String sel : selected) {
res += "<li>" + sel + "</li>";
}
res += "</ol>";
res += "selected: " + formModel.getRadio1();
model.addAttribute("title", "sample");
model.addAttribute("message", res);
model.addAttribute("formModel", formModel);
model.addAttribute("checkItems", getList());
return "showMessage";
}
ラジオボタンをまとめて作成する
複数のラジオボタンをまとめて作成するには、 <form:radiobuttons> タグを使用する。
まずは複数のラジオボタン用に、FormModel に radio2 を追加し、getter/setter を用意する。
FormModel.java
package jp.abc;
public class FormModel {
private String input1;
private String pass1;
private String area1;
private boolean check1;
private String[] checks;
private String radio1;
private String radio2;
public String getInput1() {
return input1;
}
public void setInput1(String input1) {
this.input1 = input1;
}
public String getPass1() {
return pass1;
}
public void setPass1(String pass1) {
this.pass1 = pass1;
}
public String getArea1() {
return area1;
}
public void setArea1(String area1) {
this.area1 = area1;
}
public boolean isCheck1() {
return check1;
}
public void setCheck1(boolean check1) {
this.check1 = check1;
}
public String[] getChecks() {
return checks;
}
public void setChecks(String[] checks) {
this.checks = checks;
}
public String getRadio1() {
return radio1;
}
public void setRadio1(String radio1) {
this.radio1 = radio1;
}
public String getRadio2() {
return radio2;
}
public void setRadio2(String radio2) {
this.radio2 = radio2;
}
}
JSP に、複数のラジオボタンを表示するタグを追加する。
showMessage.jsp
<tr><td><form:radiobutton path="radio1" name="radio1"
label="男性" value="male"/>
<form:radiobutton path="radio1" name="radio1"
label="女性" value="female"/>
</td></tr>
<tr><td><form:radiobuttons path="radio2" name="radio2"
items="${radiolist}" itemLabel="label" itemValue="data"
delimiter=" " />
</td></tr>
<tr><td><input type="submit" ></td></tr>
GETメソッドを処理する helo() メソッドでは、FormModel の値を設定し、radiolist の名前で ListDataModel の List を渡してやる。
MyController.java
@RequestMapping(value = "/helo", method = RequestMethod.GET)
public String helo(Model model) {
model.addAttribute("title", "ModelAndView sample");
model.addAttribute("message", "これはModelAndViewのテストです。");
FormModel fm = new FormModel();
fm.setCheck1(true);
fm.setChecks(new String[]{"Windows"});
fm.setRadio1("male");
fm.setRadio2("Linux");
model.addAttribute("formModel", fm);
model.addAttribute("checkItems", getList());
model.addAttribute("radiolist", getList());
return "showMessage";
}
POST メソッドを処理する form() メソッドでは、選択された値を表示する1行の追加と、radiolist の名前で ListDataModel の List を渡してやる1行の追加のみ。
MyAppController.jav
@RequestMapping(value = "/helo", method = RequestMethod.POST)
public String form(@ModelAttribute FormModel formModel, Model model){
String res = "<ul><li>" + formModel.getInput1()
+ "</li><li>" + formModel.getPass1()
+ "</li><li>" + formModel.getArea1()
+ "</li><li>" + formModel.isCheck1()
+ "</li></ul>";
String[] selected = formModel.getChecks();
res = res + "<ol>";
for (String sel : selected) {
res += "<li>" + sel + "</li>";
}
res += "</ol>";
res += "<br />selected: " + formModel.getRadio1();
res += "<br />selected: " + formModel.getRadio2();
model.addAttribute("title", "sample");
model.addAttribute("message", res);
model.addAttribute("formModel", formModel);
model.addAttribute("checkItems", getList());
model.addAttribute("radiolist", getList());
return "showMessage";
}
SELECTによる選択リストの作成
複数項目をリスト表示する <select>タグは、<form:select> タグで作成できる。
まず、FormModel に select 用のメンバーを用意する。
FormModel.java
package jp.abc;
public class FormModel {
private String input1;
private String pass1;
private String area1;
private boolean check1;
private String[] checks;
private String radio1;
private String radio2;
private String select1;
public String getInput1() {
return input1;
}
public void setInput1(String input1) {
this.input1 = input1;
}
public String getPass1() {
return pass1;
}
public void setPass1(String pass1) {
this.pass1 = pass1;
}
public String getArea1() {
return area1;
}
public void setArea1(String area1) {
this.area1 = area1;
}
public boolean isCheck1() {
return check1;
}
public void setCheck1(boolean check1) {
this.check1 = check1;
}
public String[] getChecks() {
return checks;
}
public void setChecks(String[] checks) {
this.checks = checks;
}
public String getRadio1() {
return radio1;
}
public void setRadio1(String radio1) {
this.radio1 = radio1;
}
public String getRadio2() {
return radio2;
}
public void setRadio2(String radio2) {
this.radio2 = radio2;
}
public String getSelect1() {
return select1;
}
public void setSelect1(String select1) {
this.select1 = select1;
}
}
JSP の、radiobuttons と submit の間に SELECT用のタグを追加する。
<tr><td><form:radiobuttons path="radio2" name="radio2"
items="${radiolist}" itemLabel="label" itemValue="data"
delimiter=" " />
</td></tr>
<tr><td><form:select path="select1" name="select1"
items="${optionlist}" itemLabel="label" itemValue="data"
size="5" multiple="false" />
</td></tr>
<tr><td><input type="submit" ></td></tr>
GETメソッドを処理する helo() メソッドでは、FormModel の値を設定し、optionlist の名前で ListDataModel の List を渡してやる。
@RequestMapping(value = "/helo", method = RequestMethod.GET)
public String helo(Model model) {
model.addAttribute("title", "ModelAndView sample");
model.addAttribute("message", "これはModelAndViewのテストです。");
FormModel fm = new FormModel();
fm.setCheck1(true);
fm.setChecks(new String[]{"Windows"});
fm.setRadio1("male");
fm.setRadio2("Linux");
fm.setSelect1("Windows");
model.addAttribute("formModel", fm);
model.addAttribute("checkItems", getList());
model.addAttribute("radiolist", getList());
model.addAttribute("optionlist", getList());
return "showMessage";
}
POST メソッドを処理する form() メソッドでは、選択された値を表示する1行の追加と、optionlist の名前で ListDataModel の List を渡してやる1行の追加のみ。
@RequestMapping(value = "/helo", method = RequestMethod.POST)
public String form(@ModelAttribute FormModel formModel, Model model){
String res = "<ul><li>" + formModel.getInput1()
+ "</li><li>" + formModel.getPass1()
+ "</li><li>" + formModel.getArea1()
+ "</li><li>" + formModel.isCheck1()
+ "</li></ul>";
String[] selected = formModel.getChecks();
res = res + "<ol>";
for (String sel : selected) {
res += "<li>" + sel + "</li>";
}
res += "</ol>";
res += "<br />selected: " + formModel.getRadio1();
res += "<br />selected: " + formModel.getRadio2();
res += "<br />selected: " + formModel.getSelect1();
model.addAttribute("title", "sample");
model.addAttribute("message", res);
model.addAttribute("formModel", formModel);
model.addAttribute("checkItems", getList());
model.addAttribute("radiolist", getList());
model.addAttribute("optionlist", getList());
return "showMessage";
}
リストで複数項目を選択可能にする
<form:select> タグの multiple属性をtrueにすることで、リストの複数項目を選択可能になる。
複数選択したデータを受け取るために、FormModel に select2 を追加し、getter/setterを生成する。
FormModel.java
package jp.abc;
public class FormModel {
private String input1;
private String pass1;
private String area1;
private boolean check1;
private String[] checks;
private String radio1;
private String radio2;
private String select1;
private String[] select2;
public String getInput1() {
return input1;
}
public void setInput1(String input1) {
this.input1 = input1;
}
public String getPass1() {
return pass1;
}
public void setPass1(String pass1) {
this.pass1 = pass1;
}
public String getArea1() {
return area1;
}
public void setArea1(String area1) {
this.area1 = area1;
}
public boolean isCheck1() {
return check1;
}
public void setCheck1(boolean check1) {
this.check1 = check1;
}
public String[] getChecks() {
return checks;
}
public void setChecks(String[] checks) {
this.checks = checks;
}
public String getRadio1() {
return radio1;
}
public void setRadio1(String radio1) {
this.radio1 = radio1;
}
public String getRadio2() {
return radio2;
}
public void setRadio2(String radio2) {
this.radio2 = radio2;
}
public String getSelect1() {
return select1;
}
public void setSelect1(String select1) {
this.select1 = select1;
}
public String[] getSelect2() {
return select2;
}
public void setSelect2(String[] select2) {
this.select2 = select2;
}
}
JSP の <form:select タグの multiple 属性を true にしたものを追加する。
showMessage.jsp
<tr><td><form:select path="select1" name="select1"
items="${optionlist}" itemLabel="label" itemValue="data"
size="5" multiple="false" />
</td></tr>
<tr><td><form:select path="select2" name="select2"
items="${optionlist}" itemLabel="label" itemValue="data"
size="5" multiple="true" />
</td></tr>
<tr><td><input type="submit" ></td></tr>
コントローラで、GETメソッドを処理する helo() メソッドの変更箇所は1行のみ。
MyAppController.java
@RequestMapping(value = "/helo", method = RequestMethod.GET)
public String helo(Model model) {
model.addAttribute("title", "ModelAndView sample");
model.addAttribute("message", "これはModelAndViewのテストです。");
FormModel fm = new FormModel();
fm.setCheck1(true);
fm.setChecks(new String[]{"Windows"});
fm.setRadio1("male");
fm.setRadio2("Linux");
fm.setSelect1("Windows");
fm.setSelect2(new String[]{"Linux"});
model.addAttribute("formModel", fm);
model.addAttribute("checkItems", getList());
model.addAttribute("radiolist", getList());
model.addAttribute("optionlist", getList());
return "showMessage";
}
POSTメソッドを処理する form() メソッドでは、選択された複数の項目を表示するコードを追加する。
MyAppController.java
@RequestMapping(value = "/helo", method = RequestMethod.POST)
public String form(@ModelAttribute FormModel formModel, Model model){
String res = "<ul><li>" + formModel.getInput1()
+ "</li><li>" + formModel.getPass1()
+ "</li><li>" + formModel.getArea1()
+ "</li><li>" + formModel.isCheck1()
+ "</li></ul>";
String[] selected = formModel.getChecks();
res = res + "<ol>";
for (String sel : selected) {
res += "<li>" + sel + "</li>";
}
res += "</ol>";
res += "<br />selected: " + formModel.getRadio1();
res += "<br />selected: " + formModel.getRadio2();
res += "<br />selected: " + formModel.getSelect1();
selected = formModel.getSelect2();
res = res + "<ol>";
for (String sel : selected) {
res += "<li>" + sel + "</li>";
}
res += "</ol>";
model.addAttribute("title", "sample");
model.addAttribute("message", res);
model.addAttribute("formModel", formModel);
model.addAttribute("checkItems", getList());
model.addAttribute("radiolist", getList());
model.addAttribute("optionlist", getList());
return "showMessage";
}