JSF实现无刷新二级联动

效果:
在添加图书页,有一个图书分类的下拉框,选择某分类后会自动刷新出子分类。
要点:
JSF有一个"bug":如果页面中包含了下拉框,则提交表单时,JSF会在应用请求值阶段就对下拉框选择的值进行验证(事实上应该在转换完毕后进行验证)。如果这个值不是可选的值之一,则会抛出校验失败的异常。所以 BookBean必须设置在SessionScoped上

代码:
addBook.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	  xmlns:h="http://java.sun.com/jsf/html"
	  xmlns:f="http://java.sun.com/jsf/core"
	  xmlns:c="http://java.sun.com/jsp/jstl/core"
	  >
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>add Book</title>
</h:head>
<h:body>
<!-- 设置了表单,因此其中用到托管bean是是设置值 -->
	<h:form id = "addBookForm">
	<h:panelGrid columns="3">

		<h:outputLabel value="图书名称:"></h:outputLabel>
		<h:inputText id="bookName" value="#{bookBean.bookName}" required="true"></h:inputText>
		<h:message for="bookName"></h:message>
		
		<h:outputLabel value="图书书号:"></h:outputLabel>
		<h:inputText id="bookNumber" value="#{bookBean.bookNumber}" required="true">
			<f:validateRegex pattern="ISBN[0-9]{13}"></f:validateRegex>
		</h:inputText>
		<h:message for="bookNumber"></h:message>
		
		<h:outputLabel value="作者:"></h:outputLabel>
		<h:inputText id="author" value="#{bookBean.author}" required="true"
			converter="authorConverter"></h:inputText>
		<h:message for="author"></h:message>
		
		<h:outputLabel value="出版时间:"></h:outputLabel>
		<h:inputText id="publishDate" value="#{bookBean.publishDate}" required="true">
			<f:convertDateTime pattern="yyyy-mm-dd"></f:convertDateTime>
		</h:inputText>
		<h:message for="publishDate"></h:message>
		
		<h:outputLabel value="价格:">
		</h:outputLabel>
		<h:inputText id="price" value="#{bookBean.price}" required="true">
			<f:convertNumber maxFractionDigits="1"
			></f:convertNumber>
		</h:inputText>
		<h:message for="price"></h:message>
		
		<h:outputLabel value="分类:"></h:outputLabel>
		<h:selectOneListbox id="category" value = "#{bookBean.category}" size = "1"
			                    valueChangeListener="#{bookControl.changeCategory}"
			                    οnchange="submit()" 
			                    immediate="true"
			                    >
			<f:selectItem itemValue="0" itemLabel="请选择"></f:selectItem>
			<f:selectItem itemValue="1" itemLabel="计算机"></f:selectItem>
			<f:selectItem itemValue="2" itemLabel="文学"></f:selectItem>
			<f:selectItem itemValue="3" itemLabel="管理"></f:selectItem>
			<f:selectItem itemValue="4" itemLabel="其他"></f:selectItem>	
		</h:selectOneListbox>
		<h:message for="category"></h:message>
		
		<h:outputLabel value="子分类:"></h:outputLabel>
		<h:selectOneListbox id="subCategory" value="#{bookBean.subCategory}"
			size="1">
			<c:forEach var="cat" items="#{bookBean.subCategories}" varStatus="catCount">
				<f:selectItem itemValue="#{catCount.count}" 
					itemLabel="#{cat}"></f:selectItem>
			</c:forEach>
		</h:selectOneListbox>
		<h:message for="subCategory"></h:message>
	
		
		<h:commandButton value="添加" action="#{bookControl.add}" 
		></h:commandButton>
		<h:commandButton value="取消" immediate="true"></h:commandButton>
		</h:panelGrid>
	</h:form>
</h:body>
</html>

BookBean.java
package cn.edu.jlu.pojo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.faces.bean.NoneScoped;   //NoneScoped不行,
									 //因为拿到.xhtml传回的值并设置BookBean后就被删除
import javax.inject.Named;
import javax.faces.bean.ViewScoped;

@Named
@SessionScoped
public class BookBean implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private String bookName;
	private String bookNumber;  //pk
	private List<String> author;//多个作者
	private Date publishDate;
	private double price;
	private int category = 0;
	private int subCategory = 99;
	private List<String> subCategories = new ArrayList<String>();
	public String getBookName() {
		return bookName;
	}
	public void setBookName(String bookName) {
		System.out.println("?????????????");
		this.bookName = bookName;
	}
	public String getBookNumber() {
		return bookNumber;
	}
	public void setBookNumber(String bookNumber) {
		this.bookNumber = bookNumber;
	}
	public List<String> getAuthor() {
		return author;
	}
	public void setAuthor(List<String> author) {
		this.author = author;
	}
	public Date getPublishDate() {
		return publishDate;
	}
	public void setPublishDate(Date publishDate) {
		this.publishDate = publishDate;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public int getCategory() {
		return category;
	}
	public void setCategory(int category) {
		this.category = category;
	}
	public int getSubCategory() {
		return subCategory;
	}
	public void setSubCategory(int subCategory) {
		this.subCategory = subCategory;
	}
	public List<String> getSubCategories() {
		return subCategories;
	}
	public void setSubCategories(List<String> subCategories) {
		this.subCategories = subCategories;
	}
	
	
}



BookControl.java
package cn.edu.jlu.controller;

import java.io.Serializable;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.inject.Inject;
import javax.inject.Named;

import cn.edu.jlu.client.CountBeanClient;
import cn.edu.jlu.client.ListBeanClient;
import cn.edu.jlu.pojo.BookBean;

@Named
@RequestScoped
//SessionScoped的Bean需要支持钝化
public class BookControl implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = -3508615784767089380L;
	@Inject @Named("bookBean")
	private BookBean bookBean;
	private int count ;
	
	@Inject @Named("bookBean")
	BookBean book;
	
	public void changeCategory(ValueChangeEvent e) {
		//获取更改后的值
		Integer category = (Integer)e.getNewValue();
		//System.out.println("选择分类------------"+bookBean.getCategory()+"-->"+category);
		//获取bookBean中的子菜单
		List<String> sub = bookBean.getSubCategories();
		sub.clear();
		if(1 == category) {
			bookBean.setCategory(1);
			sub.add("软件工程");
			sub.add("计算机网络");
			sub.add("编程语言");
			sub.add("其他");
		} else if(2 == category) {
			bookBean.setCategory(2);
			sub.add("小说");
			sub.add("散文");
			sub.add("诗词");
			sub.add("其他");
		} else if(3 == category) {
			bookBean.setCategory(3);
			sub.add("行政管理");
			sub.add("金融管理");
			sub.add("经商管理");
			sub.add("其他");
		} else if(4 == category) {
			bookBean.setCategory(4);
			
		}
		//System.out.println(sub);
	}
	
	public String add() {
		if(bookBean.getPrice() != 0.0)
			return "success";
		return "fail";
	}
	
	public void confirmToAdd() {
		System.out.println("confirmToAdd");
		new ListBeanClient().add(bookBean);
	}
	
	@PostConstruct
	public void sCount() {
		count = new CountBeanClient().getCount();
	}
	
	public void setCount(int count) {
		this.count = count;
	}
	public int getCount() {
		return count;
	}
}

作者属性的转换器,将输入的a,b,c转换成一个List
package cn.edu.jlu.biz;

import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;

@FacesConverter("authorConverter")
public class AuthorConverter implements Converter{

	@Override
	public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
		//将String转为List  arg2是获得的参数
		//去掉空格
		String ipt = arg2.replace(" ", "");
		if(ipt.equals("")) {
			FacesMessage message = new FacesMessage(
					FacesMessage.SEVERITY_ERROR, "输入有误", "不可为空");
			arg0.addMessage("author", message);
			throw new ConverterException(message);
		}
		List<String> result = new ArrayList<String>();
		//
		String[] authors = ipt.split(",");
		if(authors.length == 0) {
			FacesMessage message = new FacesMessage(
					FacesMessage.SEVERITY_ERROR, "输入有误", "多作者请用逗号间隔");
			arg0.addMessage("author", message);
			throw new ConverterException(message);
		} 		
		for (String s : authors) {
			result.add(s);
		}
		return result;
	}

	@Override
	public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
		//将List转为String
		List<String> authors = (ArrayList<String>)arg2;
		StringBuilder sb = new StringBuilder();
		for (String i: authors) {
			sb.append(i + ",");
		}
		//去掉最后一个,
		String result = sb.toString();
		int index = result.lastIndexOf(",");
		result = result.substring(0, index);
		return result;
	}

}



  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值