在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="http://java.sun.com/jsf/core" prefix="f"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<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="http://java.sun.com/jsf/core" prefix="f"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<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" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config xmlns="http://java.sun.com/JSF/Configuration">
<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