eXtremeTable本質上是一個form組件,所以我假定表被包在form里,所有的功能都被認為是對form元素的操作。如果你想在表體中包含一些定制的form元素,
或者想將eXtremeTable嵌入到另外的form中,那么你就要使用表標簽的form屬性用來參照最近的form。
下面列出的是checkbox示例的完整代碼。想要強調的主要事情是表標簽form屬性設置為presForm,它參照被稱為presForm的form元素。
同時請注意表標簽的autoIncludeParameters屬性。進行排序、過濾、分頁時,默認的eXtremeTable將保持所有傳至JSP頁面的參數。
這個特性對于內部其他的form進行排序、過濾、分頁時,用于高效復制form元素同樣有效。可以設置
autoIncludeParameters屬性為false來固定它。
在這個form使用id屬性是因為xhtm標準的要求,同時你也可以使用form的name屬性。
<form id="presForm" action="<c:url value="selectedPresidentsListedController.run"/>" method="post">
Enter your name:
<input
type="text"
name="userName"
style="font-family:verdana,arial,helvetica,sans-serif;font-size:11px;"
value="<c:out value="${param.userName}"/>"
/>
<ec:table
items="presidents"
action="${pageContext.request.contextPath}/selectedPresidentsController.run"
view="compact"
imagePath="${pageContext.request.contextPath}/images/table/compact/*.gif"
rowsDisplayed="8"
autoIncludeParameters="false"
form="presForm"
>
<ec:exportPdf
fileName="output.pdf"
tooltip="Export PDF"
headerColor="black"
headerBackgroundColor="#b6c2da"
headerTitle="Presidents"
/>
<ec:row>
<ec:column
alias="checkbox"
title=" "
width="5px"
filterable="false"
sortable="false"
viewsAllowed="compact"
cell="selectedPresident"
/>
<ec:column property="fullName" title="Name"/>
<ec:column property="nickName" />
<ec:column property="term" />
</ec:row>
</ec:table>
<input
type="button"
name="sel"
class="button"
value="List Selected Presidents"
onclick="document.forms.presForm.submit();"
/>
<script type="text/javascript">
function setPresidentState(chkbx) {
//make sure that always know the state of the checkbox
if (chkbx.checked) {
eval('document.forms.presForm.chkbx_' + chkbx.name).value='SELECTED';
} else {
eval('document.forms.presForm.chkbx_' + chkbx.name).value='UNSELECTED';
}
}
</script>
</form>
表標簽form屬性參照最近的form是你使用這個特性所必須知道的,為了更好的理解這個特性,介紹更多的關于內部實現技術的細節是值得的。
如果您不特意指定form屬性,eXtremeTable自動在表附近包上一個form。所有表的動作例如:排序、過濾、分頁將自動給一些隱藏的input元素賦值,然后提交這個form到表標簽action屬性設置的Aciton。
這非常有效,除非您想要將自己的form元素設置到表體,或者想將這個表放到別的form里。
表標簽form屬性參照最近的form,所有表的動作例如:排序、過濾、分頁將自動給一些隱藏的input元素賦值,但是現在
最近form的action屬性將要改變表標簽的動作。這非常重要,因為:當排序、過濾、分頁時,eXtremeTable能夠從一個controller得到數據集合
,但是提交這個form到別的controller來處理這個form時需要對用戶的輸入進行處理。然而,這些對于你使用表標簽來說都是透明的。
就像你現在做的那樣簡單地設置表標簽的action屬性,然后設置相關的form到你想提交的位置。
示例的第一列是checkbox。因為這列不需要參照bean的屬性,alias屬性用來唯一地標識這列。你可以使用property
屬性,但是alias屬性使這列如何使用更清楚。alias屬性還被用來當同樣的屬性被多列使用時唯一地標識一列。
您也許想知道定制的cell是如何通過名稱selectedPresident被參照的(cell="selectedPresident")。這是一個
對eXtremeTable的preferences特性更強的使用。所有要做的就是在extremecomponents.properties文件中添加一個屬性。
請參考Preferences來了解更多的信息
column.cell.selectedPresident=org.extremesite.cell.SelectedPresidentCell
column.cell.selectedPresident就是你定義的用來參照這個cell的名稱。
當然你也可以使用這個Cell的全名來進行參照。
<ec:column
alias="checkbox"
title=" "
width="5px"
filterable="false"
sortable="false"
viewsAllowed="compact"
cell="org.extremesite.cell.SelectedPresidentCell"
/>
在屬性文件中定義參照更方便,它可以被任何JSP文件引用。如果類名或包名改變的話你只需要對一個地方進行修改。
JavaScript的setPresidentState()方法被定制cell用來設置每個checkbox元素的是否被選中。
設置一個隱藏元素的原因是為了獲得瀏覽器的動作而不提交沒有選中的checkbox。通過這個Controller將一直知道一個元素是否別選中。
定制的cell被用來生成checkbox,另外它也創建一個隱藏元素用來表示這個checkbox元素是否被選中。
當用戶進行排序、過濾、分頁時,被選中的數據集合將被放到session里。
getExportDisplay()方法沒有返回值,因為治理只需要Html顯示。
public class SelectedPresidentCell implements Cell {
public String getExportDisplay(TableModel model, Column column) {
return null;
}
public String getHtmlDisplay(TableModel model, Column column) {
HtmlBuilder html = new HtmlBuilder();
CellBuilder.tdStart(html, column);
try {
Object bean = model.getCurrentRowBean();
String presidentId = BeanUtils.getProperty(bean, "presidentId");
Collection selectedPresidentsIds = (Collection)model.getContext().getSessionAttribute(SelectedPresidentsConstants.SELECTED_PRESIDENTS);
if (selectedPresidentsIds != null && selectedPresidentsIds.contains(presidentId)) {
html.input("hidden").name("chkbx_" + presidentId).value(SelectedPresidentsConstants.SELECTED).xclose();
html.input("checkbox").name(BeanUtils.getProperty(bean, "presidentId"));
html.onclick("setPresidentState(this)");
html.checked();
html.xclose();
} else {
html.input("hidden").name("chkbx_" + presidentId).value(SelectedPresidentsConstants.UNSELECTED).xclose();
html.input("checkbox").name(BeanUtils.getProperty(bean, "presidentId"));
html.onclick("setPresidentState(this)");
html.xclose();
}
} catch (Exception e) {}
CellBuilder.tdEnd(html);
return html.toString();
}
}
提示:Spring框架的Controller和Struts框架的Action非常相像。
當在另外的form中使用eXtremeTable時,你可能有1個或2個controllers。當form被提交時,你需要一個controller
來處理用戶的輸入并重新定向到另外的JSP頁面。當排序、過濾、分頁時,你可能有另外的controller來得到表使用的數據集合并重定向會本頁?;蛘吣憧梢栽谕粋€controller中分別處理。
checkbox示例里我使用一個controller來關聯表標簽的action屬性。我也使用另外一個controller來關聯form元素的動作。
這個controller負責調用SelectedPresidentsUtils來保存被選中的presidentIds到session里并回到同一頁。
SelectedPresidentsUtils.saveSelectedPresidentsIDs(request);
Collection presidents = presidentsService.getPresidents();
request.setAttribute("presidents", presidents);
這個controller負責通過presidentIds得到數據集并重定向到下一個Jsp頁面
Collection selectedPresidentsIds = SelectedPresidentsUtils.saveSelectedPresidentsIDs(request);
Collection selectedPresidents = SelectedPresidentsUtils.getSelectedPresidents(presidentsService.getPresidents(), selectedPresidentsIds);
request.setAttribute("selected", selectedPresidents);
request.getSession().removeAttribute(SelectedPresidentsConstants.SELECTED_PRESIDENTS);
我將列出保存presidentIds到session的代碼。我經常被問到如何重新得到eXtremeTable中form元素的值。
它的原理是設置form輸入元素名字屬性值前面加上一些東西來唯一標識元素
本示例中我關心的是以chkbx開頭參數的元素。chkbx后面是唯一的關聯到checkbox的presidentId。它被用來判斷這個checkbox是否別選中。
public static Collection saveSelectedPresidentsIDs(HttpServletRequest request) {
Collection presidents = (Collection) request.getSession().getAttribute(SelectedPresidentsConstants.SELECTED_PRESIDENTS);
if (presidents == null) {
presidents = new ArrayList();
request.getSession().setAttribute(SelectedPresidentsConstants.SELECTED_PRESIDENTS, presidents);
}
Enumeration parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String parameterName = (String) parameterNames.nextElement();
if (parameterName.startsWith("chkbx_")) {
String presidentId = StringUtils.substringAfter(parameterName, "chkbx_");
String parameterValue = request.getParameter(parameterName);
if (parameterValue.equals(SelectedPresidentsConstants.SELECTED)) {
if (!presidents.contains(presidentId)) {
presidents.add(presidentId);
}
} else {
presidents.remove(presidentId);
}
}
}
return presidents;
}