? 在javaserver faces里做彈出對話框并不是一件容易的事情,尤其是在彈出對話框里做修改記錄的操作,感覺還是蠻麻煩的. 這里主要用到了兩個javascript小技巧,window.open("","popup","height=480,width=320,toolbar=no,menubar=no,scrollbars=no");打開一個空白網頁的窗口,然后動態設置修改按鈕提交時的target屬性.另一個小技巧是?setInterval('opener.window.location.href=opener.window.location.href;window.close();',20);在編輯頁面提交表單時做這個
顯示數據的文件show.jsp
<%@page contentType="text/html; charset=GB2312"%>
<%@taglib uri="<%@taglib uri="<html>
<head>
<script language="javascript" type="">
?pressed="fail";
function setPress(newValue){
?? pressed=newValue;
?? }
function confirmSubmit(){
? if(pressed="editor"){
???? popup = window.open("","popup","height=480,width=320,toolbar=no,menubar=no,scrollbars=no");
???? popup.openerFormId=document.forms["fors"].id;
???? popup.focus();
???? document.forms["fors"].target="popup";
? }
}
</script>
<script? language="javascript" type="">
?function SetCheckedStatus()
{
?? ?var oTable=document.all['fors:data'];
?var oChkAll=document.all['fors:selectall']
?if(oTable != null && oChkAll != null)
?{
??for(j=1;j<oTable.rows.length;j++)
??{
???oTable.rows(j).cells(0).children.item(0).checked=oChkAll.checked;
??}
?}
}
</script>
<link href="css/styles3.css" rel="stylesheet" type="text/css"/>
<title>show book</title>
</head>
<body bgcolor="#ffffff">
<f:view>
? <h:form id="fors" onsubmit="return confirmSubmit()">
??? <h:panelGrid id="act" columns="1" cellpadding="0" cellspacing="0" width="100%" border="0" columnClasses="btstyle">
????? <h:panelGroup>
??????? <h:selectBooleanCheckbox id="selectall" onclick="SetCheckedStatus()"/>
??????? <h:outputLabel for="selectall">
????????? <h:outputText value="全選"/>
??????? </h:outputLabel>
??????? <h:commandButton value="編輯" onclick="setPress('editor')" action="editor" actionListener="#{cd.editorTriggered}"/>
??????? <h:commandButton value="刪除" onclick="setPress('del')" actionListener="#{paramsetup.delDirectoryTriggered}"/>
??????? <h:commandButton value="增加" onclick="setPress('add')"/>
??????? <h:commandButton value="保存" onclick="setPress('save')" actionListener="#{paramsetup.saveActionTriggered}"/>
????? </h:panelGroup>
??? </h:panelGrid>
??? <h:dataTable id="data" value="#{cd.model}" var="c" cellpadding="5" cellspacing="10">
????? <h:column>
??????? <f:facet name="header">
????????? <h:outputText id="headerText1" value="選擇"/>
??????? </f:facet>
??????? <h:selectBooleanCheckbox id="selectBooleanCheckbox1" value="#{c.editor}"/>
????? </h:column>
????? <h:column>
??????? <f:facet name="header">
????????? <h:outputText id="headerText2" value="書名"/>
??????? </f:facet>
??????? <h:outputText value="#{c.title}"/>
????? </h:column>
????? <h:column>
??????? <f:facet name="header">
????????? <h:outputText id="headerText3" value="作者"/>
??????? </f:facet>
??????? <h:outputText value="#{c.artist}"/>
????? </h:column>
????? <h:column>
??????? <f:facet name="header">
????????? <h:outputText id="headerText4" value="價格"/>
??????? </f:facet>
??????? <h:outputText value="#{c.price}"/>
????? </h:column>
??? </h:dataTable>
? </h:form>
</f:view>
</body>
</html>
編輯頁面也就彈出對話窗頁面editor.jsp
<%@page contentType="text/html; charset=GBK"%>
<%@taglib uri="<%@taglib uri="<html>
<head>
<title>editor</title>
<script type="">
function confirmSubmit(){
?setInterval('opener.window.location.href=opener.window.location.href;window.close();',20);
}
</script>
</head>
<body bgcolor="#ffffff">
<f:view>
? <h:form id="fors" onsubmit="return confirmSubmit()">
??? <h:dataTable id="data" value="#{cd.editorModel}" var="c" cellpadding="5" cellspacing="10">
????? <h:column>
??????? <f:facet name="header">
????????? <h:outputText id="headerText2" value="書名"/>
??????? </f:facet>
??????? <h:inputText value="#{c.title}"/>
????? </h:column>
????? <h:column>
??????? <f:facet name="header">
????????? <h:outputText id="headerText3" value="作者"/>
??????? </f:facet>
??????? <h:inputText value="#{c.artist}"/>
????? </h:column>
????? <h:column>
??????? <f:facet name="header">
????????? <h:outputText id="headerText4" value="價格"/>
??????? </f:facet>
??????? <h:inputText value="#{c.price}"/>
????? </h:column>
??? </h:dataTable>
??? <h:panelGrid columns="1">
????? <h:commandButton value="保存" action="show" actionListener="#{cd.saveTriggered}">????? </h:commandButton>
????? <h:commandButton value="取消" type="button" onclick="javascript:window.close();">????? </h:commandButton>
??? </h:panelGrid>
? </h:form>
</f:view>
</body>
</html>
backing bean CDBean.java
package test;
import java.util.*;
import javax.faces.model.ListDataModel;
import javax.faces.event.ActionEvent;
public class CDBean {
??? private List CDList = new ArrayList();
??? private ListDataModel model;
??? private ListDataModel editorModel;
??? public CDBean() {
??????? CDList.add(new CD("計算機應用", "長江", 25.00F, ""));
??????? CDList.add(new CD("java模式", "長江", 80.00F, ""));
??????? CDList.add(new CD("j2EE1.4標準教材", "長江", 100.00F, ""));
??? }
??? public ListDataModel getModel() {
??????? if (model == null) {
??????????? model = new ListDataModel(CDList);
??????? }
??????? return model;
??? }
??? public ListDataModel getEditorModel() {
??????? return editorModel;
??? }
??? public void editorTriggered(ActionEvent actionEvent) {
??????? List list = (List) model.getWrappedData();
??????? List editorList = new ArrayList();
??????? for (Iterator it = list.iterator(); it.hasNext(); ) {
??????????? CD cd = (CD) it.next();
??????????? if (cd.getEditor()) {
??????????????? editorList.add(cd);
??????????? }
??????? }
??????? editorModel = new ListDataModel(editorList);
??? }
??? public void saveTriggered(ActionEvent actionEvent) {
??????? List list = (List) editorModel.getWrappedData();
??????? for (Iterator it = list.iterator(); it.hasNext(); ) {
??????????? CD cd = (CD) it.next();
??????????? cd.setEditor(false);
??????? }
??? }
}
輔助類CD.java
package test;
public class CD implements java.io.Serializable {
??? private Long id;
??? private String artist;
??? private String category;
??? private String subCategory;
??? private String title;
??? private float price;
??? private boolean editor;
??? public CD() {
??? }
??? public CD(String aTitle, String aArtist, float aPrice, String aCategory) {
??????? this.title = aTitle;
??????? this.artist = aArtist;
??????? this.price = aPrice;
??????? this.category = aCategory;
??? }
??? public void setArtist(String aArtist) {
??????? this.artist = aArtist;
??? }
??? public String getArtist() {
??????? return artist;
??? }
??? public void setCategory(String aCategory) {
??????? this.category = aCategory;
??? }
??? public String getCategory() {
??????? return category;
??? }
??? public void setId(Long aId) {
??????? this.id = aId;
??? }
??? public Long getId() {
??????? return id;
??? }
??? public void setPrice(float aPrice) {
??????? this.price = aPrice;
??? }
??? public float getPrice() {
??????? return price;
??? }
??? public void setSubCategory(String aSubCategory) {
??????? this.subCategory = aSubCategory;
??? }
??? public String getSubCategory() {
??????? return subCategory;
??? }
??? public void setTitle(String aTitle) {
??????? this.title = aTitle;
??? }
??? public String getTitle() {
??????? return title;
??? }
??? public void setEditor(boolean editor){
??????? this.editor=editor;
??? }
??? public boolean getEditor(){
??????? return this.editor;
??? }
}
配置文件faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "<faces-config xmlns="? <managed-bean>
??? <managed-bean-name>cd</managed-bean-name>
??? <managed-bean-class>test.CDBean</managed-bean-class>
??? <managed-bean-scope>session</managed-bean-scope>
? </managed-bean>
? <navigation-rule>
??? <from-view-id>/show.jsp</from-view-id>
??? <navigation-case>
????? <from-outcome>editor</from-outcome>
????? <to-view-id>/editor.jsp</to-view-id>
??? </navigation-case>
? </navigation-rule>
? <navigation-rule>
??? <from-view-id>/editor.jsp</from-view-id>
??? <navigation-case>
????? <from-outcome>show</from-outcome>
????? <to-view-id>/show.jsp</to-view-id>
??? </navigation-case>
? </navigation-rule>
</faces-config>
最后的總結:在彈出窗口里是沒法用jsf的驗證機制的,原因是setInterval('opener.window.location.href=opener.window.location.href;window.close();',20);有一個javascript的opener對象的引用,當用jsf驗證時如果有非法輸入,彈出窗口頁面就會刷新,這就會丟失對opener的引用,而且還存在另一個問題就是如果驗證正確就應該關閉對話框,失敗就不應該關閉對話框.這個問題也不好解決. 那么是不是就沒辦法解決驗證的問題呢?不是的.可以在彈出頁面里用frame引用兩個頁面,一個保持對opener的引用,另一個就是編輯作用了,具體作法就是在backing bean 里添加一個action動態導航方法里調用FacesContext.getCurrentInstance().getResponseWriter().write(); 在write 方法里打印用于控制關閉對話框的javascript代碼,因為action方法能執行就表示驗證一定通過了.如果驗證不通過的話就會返回自身頁面拋出異常.在write 方法里,最后在write 方法的最后一定不能忘了 FacesContext.getCurrentInstance().responseComplete()以跳過轉向的執行,也就是跳過jsf生命的最后一個階段.還有另一個更好的解決方案,用Ajax實現驗證,具體實現就不再贅述了,因為它不是jsf的一部分:) 歡迎加入QQ群:30406099?
?