肥満診断 - その2
フォームに身長と体重を入力し、Submitボタンを押したら、別のページで診断結果を表示するように、肥満診断を修正する。
HTMLで作成するビューは、前の肥満診断を入力フォームを表示する部分と結果を表示する部分にわけることになる。それぞれの内容は以下の通り。
入力フォーム部分(bmi_form.htm):
<h1>BMIによる肥満度診断</h1> $inputForm
結果表示部分(bmi_result.htm):
<h1>BMIによる肥満度診断 - 結果</h1> #if ($diagnosis == "過体重" || $diagnosis == "肥満") <h2 class="diagnosis">$diagnosis</h2> #end あなたの身長は <span class="cmHeight">$cmHeight</span> cmです。<br/> あなたの体重は <span class="kgWeight">$kgWeight</span> kgです。<br/> <hr/> あなたのBMIは <span class="bmi">$bmi</span> です。<br/> あなたは「 <span class="diagnosis">$diagnosis</span> 」です。<br/> ちなみにあなたの標準体重は <span class="idealWeight">$idealWeight</span> kgです。<br/>
フォームを定義するBmiFormPageクラスは、Submitボタンが押されたら、結果を表示するbmi_result.htmを表示するように修正する必要がある。その際、BMIの計算結果を保持するオブジェクトを受け渡す。
BMIの計算結果の受け渡しは、PageクラスのgetContext()メソッドで得られるContextクラスのオブジェクトを介して行う。オブジェクトを渡す側では、適当な名前をつけて、ContextクラスのsetSessionAttribute()メソッドを呼ぶ。オブジェクトを受ける側では、その名前をキーにして、ContextクラスのgetSessionAttribute()メソッドを呼ぶ。ここでは、受け渡しするオブジェクトはBmiクラスのオブジェクトで行う。
BmiFormPageクラスの内容は以下の通り:
package com.fujitsu.fst.hal; import net.sf.click.control.FieldSet; import net.sf.click.control.Form; import net.sf.click.control.Submit; import net.sf.click.control.TextField; import net.sf.click.util.ClickLogger; public class BmiFormPage extends BorderPage { public String title = "BMIによる肥満度診断"; public Form inputForm = new Form(); public double bmi; public String diagnosis; public double idealWeight; /* cmHeightField, kgWeightFieldは、DoubleFieldにしたいところ * だが、DoubleFieldは、required statusが利かないようだ。 * フィールドをクリアしてsubmitボタンを押してもエラーにならない。 * なので、TextFieldにしておく。 */ private TextField cmHeightField; private TextField kgWeightField; private Submit submitButton; private double cmHeight = 170.0; private double kgWeight = 50.0; private ClickLogger logger = ClickLogger.getInstance(); public BmiFormPage() { logger.debug("Bmiform#<init>(): this = " + this); FieldSet inputFieldSet = new FieldSet("bmi", ""); inputForm.add(inputFieldSet); cmHeightField = new TextField("cmHeight", "身長 (cm)", true); inputFieldSet.add(cmHeightField); kgWeightField = new TextField("kgWeight", "体重 (kg)", true); inputFieldSet.add(kgWeightField); submitButton = new Submit("submit", "submit", this, "onStartDiag"); inputForm.add(submitButton); Bmi bmi = new Bmi(cmHeight, kgWeight); this.bmi = bmi.getBmi(); this.diagnosis = bmi.getDiagnosis(); this.idealWeight = bmi.getIdealWeight(); } /* (一応動くが、こんなのでよいのかわからない!) * submitボタンを押すと、一見そうは見えないが、画面が遷移している。 * (thisポインタの値がsubmitボタンを押す前と押したあとで違う。) * inputFormは、新しい画面のオブジェクトになっているが、フォームの中の * 部品が保持する値などは、オブジェクトに設定してないので、フォームから * 値を取り直す必要がある。 */ public boolean onStartDiag() { logger.debug("Bmiform#onStartDiag(): this = " + this); FieldSet inputFieldSet = (FieldSet)inputForm.getField("bmi"); this.cmHeightField = (TextField)inputFieldSet.getField("cmHeight"); this.kgWeightField = (TextField)inputFieldSet.getField("kgWeight"); logger.debug("cmHeightField = " + cmHeightField); logger.debug("kgWeightField = " + kgWeightField); if (cmHeightField == null || kgWeightField == null) { return false; } try { this.cmHeight = Double.parseDouble(cmHeightField.getValue()); this.kgWeight = Double.parseDouble(kgWeightField.getValue()); } catch (NumberFormatException e) { return false; } Bmi bmi = new Bmi(cmHeight, kgWeight); this.bmi = bmi.getBmi(); this.diagnosis = bmi.getDiagnosis(); this.idealWeight = bmi.getIdealWeight(); this.getContext().setSessionAttribute("bmi", bmi); this.setRedirect("bmi_result.htm"); return true; } public void onInit() { cmHeightField.setValue(Double.toString(cmHeight)); kgWeightField.setValue(Double.toString(kgWeight)); } }
Bmiオブジェクトを受け取るBmiResultPageクラスは以下の通り:
package com.fujitsu.fst.hal; public class BmiResultPage extends BorderPage { public double bmi; public String diagnosis; public double idealWeight; public double cmHeight; public double kgWeight; public void onInit() { if (getContext().hasSessionAttribute("bmi")) { Bmi bmi = (Bmi)getContext().getSessionAttribute("bmi"); this.cmHeight = bmi.getCmHeight(); this.kgWeight = bmi.getKgWeight(); this.bmi = bmi.getBmi(); this.diagnosis = bmi.getDiagnosis(); this.idealWeight = bmi.getIdealWeight(); } } }
データの受信は、結果を表示するページができて、それを表示する前に行うので、onInit()メソッドで行っている。データを受ける前に、目的のデータがあるかどうかをhasSessionAttribute()メソッドでチェックしている。