デザインまで依存すれば、前回の投稿AJAXカレンダーのように、Panel の呼び出し側で
負担がかかることはない。しかし、デザインは自由度が制限される
ここで悩んでいた。
突き詰めれば、以下のWebPage記述で済む。
public class CalendarTestPage extends WebPage{
public CalendarTestPage(){
CalenderHelper helper = new CalenderHelper(getRequestCycle());
add(new CalendarPanel("calendar",new Model<CalendarRequest>(
new CalendarRequestImpl(helper.getTargetDate(),FooPage.class,new PageParameters())
)));
}
}
--------------------------------------------
これを実現するためにHTMLとPanel クラスは以下のようになる。
CalendarPanel.html の記述、、、、
<wicket:panel>
<table class="calendar">
<tr><td><a wicket:id="prev" class="calendar"><</a></td>
<td colspan="5"><span wicket:id="year"></span>年 <span wicket:id="month"></span>月</td>
<td><a wicket:id="next" class="calendar">></a></td>
</tr>
<tr class="head"><th class="sun">日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th class="sat">土</th></tr>
<tbody wicket:id="tbody">
<tr wicket:id="calendar_days" class="days">
<td><a wicket:id="sun" class="calendar"><span wicket:id="sun_day" class="calendar">1</span></a></td>
<td><a wicket:id="mon" class="calendar"><span wicket:id="mon_day" class="calendar">1</span></a></td>
<td><a wicket:id="tue" class="calendar"><span wicket:id="tue_day" class="calendar">1</span></a></td>
<td><a wicket:id="wed" class="calendar"><span wicket:id="wed_day" class="calendar">1</span></a></td>
<td><a wicket:id="thu" class="calendar"><span wicket:id="thu_day" class="calendar">1</span></a></td>
<td><a wicket:id="fri" class="calendar"><span wicket:id="fri_day" class="calendar">1</span></a></td>
<td><a wicket:id="sat" class="calendar"><span wicket:id="sat_day" class="calendar">1</span></a></td>
</tr>
</tbody>
</table>
</wicket:panel>
Panel クラスは、、、
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
/**
* 月移動リンク付きカレンダー.
* 前月、翌月リンクは、このPanel内で生成される。
*/
public class CalendarPanel extends Panel{
private IModel<Date> targetDateModel;
private SimpleDateFormat formatYMD
= new SimpleDateFormat(CalendarRequest.CALENDAR_PARAM_FORMAT);
private IModel<CalendarRequest> reqModel;
public CalendarPanel(String id,final IModel<CalendarRequest> model){
super(id,model);
this.reqModel = model;
final CalenderHelper helper = new CalenderHelper(getRequestCycle());
final Calendar cal = Calendar.getInstance();
final CalendarRequest req = model.getObject();
cal.setTime(req.getDate());
cal.set(Calendar.DAY_OF_MONTH,1);
this.targetDateModel = new Model<Date>(cal.getTime());
// table tbody
final WebMarkupContainer tbody = new WebMarkupContainer("tbody");
tbody.setOutputMarkupId(true);
final ListView<String> daylist = createListView(req);
daylist.setOutputMarkupId(true);
tbody.add(daylist);
add(tbody);
// 年の表示
final Label year = new Label("year",new AbstractReadOnlyModel<String>(){
@Override
public String getObject(){
Calendar c = Calendar.getInstance();
c.setTime(getTargetDateModel().getObject());
return Integer.toString(c.get(Calendar.YEAR));
}
});
year.setOutputMarkupId(true);
add(year);
// 月の表示
final Label month = new Label("month",new AbstractReadOnlyModel<String>(){
@Override
public String getObject(){
Calendar c = Calendar.getInstance();
c.setTime(getTargetDateModel().getObject());
return Integer.toString(c.get(Calendar.MONTH)+1);
}
});
month.setOutputMarkupId(true);
add(month);
// 前月&翌月リンク
add(new WebMarkupContainer("prev").add(new AjaxEventBehavior("onclick"){
@Override
protected void onEvent(AjaxRequestTarget target){
setTargetDateModelDate(helper.prevDate(getTargetDateModel()));
CalendarRequest calendarRequest = getReqModel().getObject();
calendarRequest.setDate(getTargetDateModelDate());
tbody.remove("calendar_days");
tbody.add(createListView(calendarRequest));
target.addComponent(tbody);
target.addComponent(year);
target.addComponent(month);
}
}));
add(new WebMarkupContainer("next").add(new AjaxEventBehavior("onclick"){
@Override
protected void onEvent(AjaxRequestTarget target){
setTargetDateModelDate(helper.nextDate(getTargetDateModel()));
CalendarRequest calendarRequest = getReqModel().getObject();
calendarRequest.setDate(getTargetDateModelDate());
tbody.remove("calendar_days");
tbody.add(createListView(calendarRequest));
target.addComponent(tbody);
target.addComponent(year);
target.addComponent(month);
}
}));
}
protected ListView<String> createListView(final CalendarRequest req){
final String wds = {"sun","mon","tue","wed","thu","fri","sat"};
final Calendar cal = Calendar.getInstance();
final Calendar calx = Calendar.getInstance();
cal.setTime(req.getDate());
cal.set(Calendar.DAY_OF_MONTH,1);
this.targetDateModel = new Model<Date>(cal.getTime());
calx.setTime(cal.getTime());
return new ListView<String>("calendar_days"
,calendarList(req.getDate()," ")){
@Override
protected void populateItem(ListItem<String> item){
final String days = item.getModelObject();
for(int i=0; i < 7; i++){
final int index = i;
item.add(
new BookmarkablePageLink<String>(wds[i],req.getLinkClass(),makeParameter(cal.getTime()
,req.getPageParameters(),req.getDateParameterName())){
@Override
public boolean isEnabled(){
if (days[index].equals(" ")) return false;
calx.set(Calendar.DAY_OF_MONTH,Integer.parseInt(days[index]));
return req.enable(calx.getTime());
}
}.add(new Label(wds[i]+"_day",days[i]).setEscapeModelStrings(false)
));
if (!days[i].equals(" ")) cal.add(Calendar.DAY_OF_MONTH,1);
}
}
};
}
private List<String> calendarList(Date date,String blank){
Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(c.get(Calendar.YEAR),c.get(Calendar.MONTH),1);
int firstWeek = c.get(Calendar.DAY_OF_WEEK);
c.add(Calendar.MONTH, 1);
c.set(c.get(Calendar.YEAR),c.get(Calendar.MONTH),1);
c.add(Calendar.DAY_OF_MONTH, - c.get(Calendar.DAY_OF_MONTH));
int endday = c.get(Calendar.DAY_OF_MONTH);
List<String> list = new ArrayList<String>();
int day = 1;
int week = 0;
String s = new String[7];
int o = firstWeek - 1;
for(;week < o;week++){
s[week] = blank;
}
for(int d=day;d <= endday;d++){
if (week==7){
list.add(s);
s = new String[7];
week = 0;
}
s[week] = Integer.toString(d);
week++;
}
for(;week < 7;week++){
s[week] = blank;
}
list.add(s);
return list;
}
// 日付リンクのパラメータ
protected PageParameters makeParameter(Date ndt,PageParameters p,String key){
p.put(key,this.formatYMD.format(ndt));
return p;
}
protected void setTargetDateModelDate(Date dt){
this.targetDateModel.setObject(dt);
}
protected Date getTargetDateModelDate(){
return this.targetDateModel.getObject();
}
protected IModel<Date> getTargetDateModel(){
return this.targetDateModel;
}
protected IModel<CalendarRequest> getReqModel(){
return this.reqModel;
}
protected void setReqModel(IModel<CalendarRequest> reqModel){
this.reqModel = reqModel;
}
}