jqGrid 學習筆記整理——終極篇(一)
本篇開始實現利用jqGrid框架實現 主從表 的顯示效果及與後臺交互的實例,使用的平臺和上篇博文[jqGrid 學習筆記整理——進階篇(二)](http://blog.csdn.net/dfs4df5/article/details/51108798)一致 也將使用上篇中的數據庫和代碼進行添加和修改,如果未看上篇的請先去看上篇,本篇不再重複貼出上篇出現的源碼。
一、數據庫部分
爲了檢索方便,這裏建立了一個視圖
關聯兩個表,設置爲外鍵
最後如果有什麼不清楚的請參考下面語句
/*
Navicat MySQL Data Transfer
Source Server : localhost_3306
Source Server Version : 50710
Source Host : localhost:3306
Source Database : jqgriddemo
Target Server Type : MYSQL
Target Server Version : 50710
File Encoding : 65001
Date: 2016-04-19 08:57:17
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for t_demo
-- ----------------------------
DROP TABLE IF EXISTS `t_demo`;
CREATE TABLE `t_demo` (
`id` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT,
`name` varchar(25) DEFAULT NULL,
`type` int(11) DEFAULT NULL,
`pay` double(10,2) DEFAULT NULL,
`text` text,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for t_documents
-- ----------------------------
DROP TABLE IF EXISTS `t_documents`;
CREATE TABLE `t_documents` (
`d_id` int(11) NOT NULL AUTO_INCREMENT,
`id` int(10) unsigned zerofill NOT NULL,
`g_id` int(10) unsigned zerofill NOT NULL,
`d_num` int(11) DEFAULT NULL,
PRIMARY KEY (`d_id`),
KEY `id` (`id`),
KEY `g_id` (`g_id`),
CONSTRAINT `t_documents_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t_demo` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `t_documents_ibfk_2` FOREIGN KEY (`g_id`) REFERENCES `t_goods` (`g_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for t_goods
-- ----------------------------
DROP TABLE IF EXISTS `t_goods`;
CREATE TABLE `t_goods` (
`g_id` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT,
`g_name` varchar(25) NOT NULL,
`g_type` int(3) DEFAULT NULL,
PRIMARY KEY (`g_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- ----------------------------
-- View structure for v_list
-- ----------------------------
DROP VIEW IF EXISTS `v_list`;
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_list` AS select `t_documents`.`id` AS `id`,`t_goods`.`g_id` AS `g_id`,`t_goods`.`g_name` AS `g_name`,`t_goods`.`g_type` AS `g_type`,`t_documents`.`d_num` AS `d_num` from (`t_goods` join `t_documents` on((`t_documents`.`g_id` = `t_goods`.`g_id`))) ;
注:本篇主從表主要以檢索爲主,爲方便數據顯示,需手動先添加些數據測試!
測試數據如下:
/*t_demo表數據*/
INSERT INTO `t_demo` (`name`, `type`, `pay`, `text`) VALUES ('測試1', '1', '24', '測試測試');
INSERT INTO `t_demo` (`name`, `type`, `pay`, `text`) VALUES ('測試2', '0', '12.312', '而是測試');
INSERT INTO `t_demo` (`name`, `type`, `pay`, `text`) VALUES ('測試3', '0', '12', ' 額額');
/*t_goods表數據*/
INSERT INTO `t_goods` (`g_name`, `g_type`) VALUES ('物資1', '1');
INSERT INTO `t_goods` (`g_name`, `g_type`) VALUES ('物資2', '1');
INSERT INTO `t_goods` (`g_name`, `g_type`) VALUES ('物資3', '0');
INSERT INTO `t_goods` (`g_name`, `g_type`) VALUES ('物資4', '2');
/*t_documents表數據*/
INSERT INTO `t_documents` (`id`, `g_id`, `d_num`) VALUES ('1', '1', '12');
INSERT INTO `t_documents` (`id`, `g_id`, `d_num`) VALUES ('1', '2', '1');
INSERT INTO `t_documents` (`id`, `g_id`, `d_num`) VALUES ('2', '1', '1');
INSERT INTO `t_documents` (`id`, `g_id`, `d_num`) VALUES ('2', '2', '2');
INSERT INTO `t_documents` (`id`, `g_id`, `d_num`) VALUES ('2', '3', '3');
INSERT INTO `t_documents` (`id`, `g_id`, `d_num`) VALUES ('3', '4', '45');
插入數據後點擊打開視圖顯示如下:
二、程序部分
包結構如下,在"進階篇二"的基礎上增加了GoodList(從表顯示的vo對象)部分
goodlist.java
package com.xeonmic.vo;
public class goodlist {
private int id;
private int g_id;
private String g_name;
private int g_type;
private int d_num;
public goodlist(int id, int g_id, String g_name, int g_type, int d_num) {
super();
this.id = id;
this.g_id = g_id;
this.g_name = g_name;
this.g_type = g_type;
this.d_num = d_num;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getG_id() {
return g_id;
}
public void setG_id(int g_id) {
this.g_id = g_id;
}
public String getG_name() {
return g_name;
}
public void setG_name(String g_name) {
this.g_name = g_name;
}
public int getG_type() {
return g_type;
}
public void setG_type(int g_type) {
this.g_type = g_type;
}
public int getD_num() {
return d_num;
}
public void setD_num(int d_num) {
this.d_num = d_num;
}
@Override
public String toString() {
return "goodlist [id=" + id + ", g_id=" + g_id + ", g_name=" + g_name
+ ", g_type=" + g_type + ", d_num=" + d_num + "]";
}
}
GoodListDAO.java
package com.xeonmic.dao;
import java.util.List;
import com.xeonmic.vo.goodlist;
public interface GoodListDAO {
//查詢方法
public List<goodlist> doSearch(String keys);
}
GoodListDAOImpl.java
package com.xeonmic.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.xeonmic.dao.GoodListDAO;
import com.xeonmic.vo.goodlist;
public class GoodListDAOImpl implements GoodListDAO {
private Connection conn = null;
private PreparedStatement pstmt = null;
public GoodListDAOImpl(Connection conn){
this.conn=conn;
}
@Override
public List<goodlist> doSearch(String keys) {
if (keys==null) {
keys="";
}
String sql = "SELECT id,g_id,g_name,g_type,d_num FROM v_list"+keys;
List<goodlist> all = new ArrayList<goodlist>();
System.out.println(sql);
try {
this.pstmt = this.conn.prepareStatement(sql);
ResultSet rs = this.pstmt.executeQuery();
goodlist good = null;
while(rs.next()){
good = new goodlist(rs.getInt("id"),rs.getInt("g_id"),rs.getString("g_name"),rs.getInt("g_type"),rs.getInt("d_num"));
all.add(good);
}
this.pstmt.close();
} catch (SQLException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
return all;
}
}
GoodListDAOProxy.java
package com.xeonmic.dao.proxy;
import java.util.List;
import com.xeonmic.dao.GoodListDAO;
import com.xeonmic.dao.impl.GoodListDAOImpl;
import com.xeonmic.dbc.DatabaseConnection;
import com.xeonmic.vo.goodlist;
public class GoodListDAOProxy implements GoodListDAO {
private DatabaseConnection dbc = null;
private GoodListDAO ddao = null;
public GoodListDAOProxy(){
this.dbc = new DatabaseConnection();
this.ddao = new GoodListDAOImpl(this.dbc.getConnection());
}
@Override
public List<goodlist> doSearch(String keys) {
List<goodlist> all = null;
all = this.ddao.doSearch(keys);
this.dbc.close();
return all;
}
}
修改Factory.java
package com.xeonmic.factory;
import com.xeonmic.dao.DemoDAO;
import com.xeonmic.dao.GoodListDAO;
import com.xeonmic.dao.proxy.DemoDAOProxy;
import com.xeonmic.dao.proxy.GoodListDAOProxy;
public class Factory {
public static DemoDAO getDemoDAOInstance(){
return new DemoDAOProxy();
}
public static GoodListDAO getGoodListDAOInstance(){
return new GoodListDAOProxy();
}
}
goodlistServlet.java(重要 相比demoServlet加入了固定的id條件查詢,因爲從表的結果是根據主表選擇的id進行顯示的,所以每次檢索都是在加上主表id的基礎上進行的)
package com.xeonmic.action;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import com.xeonmic.factory.Factory;
import com.xeonmic.vo.goodlist;
public class goodlistServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8"); //這裏不設置編碼會有亂碼
response.setContentType("text/html;charset=utf-8");
response.setHeader("Cache-Control", "no-cache");
int rows = Integer.valueOf(request.getParameter("rows")); //每頁中顯示的記錄行數
int page = Integer.valueOf(request.getParameter("page")); //當前的頁碼
String sord = request.getParameter("sord");//排序方式
String sidx = request.getParameter("sidx");//排序列名
Boolean search =(request.getParameter("_search").equals("true"))?true:false;//是否用於查詢請求
List<goodlist> allList = new LinkedList<goodlist>();//返回結果集
if (request.getParameter("id")!=null &&!"".equals(request.getParameter("id"))) {
int id = Integer.valueOf(request.getParameter("id"));
String keys=" WHERE id = "+id+" ";//查詢條件字符串
if(search ){
String filters = request.getParameter("filters");//具體的條件
if (filters!=null&&!"".equals(filters)) {
keys += " AND ( ";//將從表自身的檢索條件用AND(條件1 AND 條件2 OR 條件3...)的形式封裝
System.out.println("filters="+filters);
//傳入數據的格式是類似這樣的:"{"groupOp":"AND","rules":[{"field":"id","op":"eq","data":"1"},{"field":"type","op":"ew","data":"2"}]}"
JSONObject jsonObject = JSONObject.fromObject(filters);
String groupOp = "AND";//每個規則之間的關係(and/or)
if (jsonObject.getString("groupOp")!=null&&!"".equals(jsonObject.getString("groupOp"))) {
if (jsonObject.getString("groupOp").equals("OR")) {
groupOp = "OR";
}
}
JSONArray rulesjson = jsonObject.getJSONArray("rules");
//遍歷每個條件
for (int z=0; z < rulesjson.size(); z++) {
Object t = rulesjson.get(z);
JSONObject rulejson = JSONObject.fromObject(t);
String field = rulejson.getString("field");
String op = rulejson.getString("op");
String data = rulejson.getString("data");
String string = "";//用於存儲單個條件sql語句片段
//開始轉化爲sql語句
switch (op) {
case "eq"://相等
string=" = '"+data+"' ";
break;
case "ne"://不相等
string=" <> '"+data+"' ";
break;
case "li"://小於
string=" < '"+data+"' ";
break;
case"le"://小於等於
string=" <= '"+data+"' ";
break;
case"gt"://大於
string=" > '"+data+"' ";
break;
case "ge"://大於等於
string=" >= '"+data+"' ";
break;
case "bw"://在...之間
{
if (data.split(",").length==2) {
string=" BETWEEN '"+data.split(",")[0]+"' AND '"+data.split(",")[1]+"' ";
}else {
string=" = '"+data+"' ";//數據錯誤時處理
}
}
break;
case"bn"://不在...之間
{
if (data.split(",").length==2) {
string=" NOT BETWEEN '"+data.split(",")[0]+"' AND '"+data.split(",")[1]+"' ";
}else {
string=" <> '"+data+"' ";//數據錯誤時處理
}
}
break;
case"ew"://以...結束
string=" LIKE '%"+data+"' ";
break;
case "en"://不以...結束
string=" NOT LIKE '%"+data+"' ";
break;
case "cn"://包含
string=" LIKE '%"+data+"%' ";
break;
case "nc"://不包含
string=" NOT LIKE '%"+data+"%' ";
break;
case "in"://在
{
string=" IN ( ";
String[] datas = data.split(",");
for (int i = 0; i < datas.length; i++) {
string+= " '"+datas[i]+"' ";
if (i!=datas.length-1) {
string += ",";
}else {
string += " ) ";
}
}
}
break;
case "ni"://不在
{
string=" NOT IN ( ";
String[] datas = data.split(",");
for (int i = 0; i < datas.length; i++) {
string+= " '"+datas[i]+"' ";
if (i!=datas.length-1) {
string += ",";
}else {
string += " ) ";
}
}
}
break;
default:
op=null;
System.out.println("OP符號錯誤");//OP符號錯誤
}
if (op!=null) {
if (z==rulesjson.size()-1) {
keys+=" "+field+" "+string +" ";
}else {
keys+=" "+field+" "+string +" "+groupOp+" ";
}
}
}
keys += " ) ";
}
}
//升降序SQL語句轉換
if (sidx!=null&&!"".equals(sidx)) {
System.out.println(sidx);
keys += " ORDER BY " + sidx;
System.out.println("sord="+sord);
if (!sord.equals("asc")) {
keys += " DESC ";
}
}
allList = Factory.getGoodListDAOInstance().doSearch(keys);
//分頁部分
int total=0;
total=(allList.size()%rows==0)?(allList.size()/rows):((allList.size()/rows)+1);
int j = 0;
int m = (page-1)*rows;
int n = (page-1)*rows+rows;
JSONArray jArray = new JSONArray();
for (j=m; j<allList.size()&&j<n; j++) {
jArray.add(JSONObject.fromObject(allList.get(j)));
}
JSONObject jjson = new JSONObject();
//檢索結果及分頁信息封裝 返回
jjson.accumulate("page", page);
jjson.accumulate("total", total);
jjson.accumulate("records", allList.size());
jjson.accumulate("rows", jArray);
System.out.println(jjson.toString());
response.getWriter().write(jjson.toString());
}else {
response.getWriter().write("{}");
}
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
index1.jsp(重要 複製index.jsp 並作出如下修改)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>DEMO</title>
<link rel="stylesheet" type="text/css" href="css/jquery-ui.min.css" />
<link rel="stylesheet" type="text/css" href="css/jquery-ui.theme.min.css" />
<link rel="stylesheet" type="text/css" href="css/ui.jqgrid-bootstrap-ui.css" />
<link rel="stylesheet" type="text/css" href="css/ui.jqgrid.css" />
</head>
<body>
<div class="main" id="main">
<!--jqGrid 主表所在-->
<table id="grid-table"></table>
<!--jqGrid 主表瀏覽導航欄所在-->
<div id="grid-pager"></div>
<!--jqGrid 從表所在-->
<table id="grid-tableo"></table>
<!--jqGrid 從表瀏覽導航欄所在-->
<div id="grid-pagero"></div>
</div>
<script src="js/jquery-1.11.0.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/i18n/grid.locale-cn.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery.jqGrid.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
//當 datatype 爲"local" 時需填寫
var grid_selector = "#grid-table";
var pager_selector = "#grid-pager";
var grid_selectoro = "#grid-tableo";
var pager_selectoro = "#grid-pagero";
$(document).ready(function() {
$("#grid-table").jqGrid({
//用於檢索的Servlet URL
url:"<%=basePath%>"+"demoServlet",
//用於添加、修改、刪除的Servlet URL
editurl: "<%=basePath%>"+"demochangeServlet",
//data: grid_data, //當 datatype 爲"local" 時需填寫
datatype:"json", //數據來源,本地數據(local,json,jsonp,xml等)
height: 150, //高度,表格高度。可爲數值、百分比或'auto'
mtype:"GET",//提交方式
colNames: ['出庫單號', '出庫類型', '總金額', '申請人(單位)', '備註'],
colModel: [{
name: 'id',
index: 'id', //索引。其和後臺交互的參數爲sidx
key: true, //當從服務器端返回的數據中沒有id時,將此作爲唯一rowid使用只有一個列可以做這項設置。如果設置多於一個,那麼只選取第一個,其他被忽略
width: 100,
editable: false,
editoptions: {
size: "20",
maxlength: "30"
}
}, {
name: 'type',
index: 'type',
width: 200, //寬度
editable: true, //是否可編輯
edittype: "select", //可以編輯的類型。可選值:text, textarea, select, checkbox, password, button, image and file.s
editoptions: {
value: "1:採購入庫;2:退用入庫"
}
}, {
name: 'pay',
index: 'pay',
width: 60,
sorttype: "double",
editable: true
}, {
name: 'name',
index: 'name',
width: 150,
editable: true,
editoptions: {
size: "20",
maxlength: "30"
}
}, {
name: 'text',
index: 'text',
width: 250,
sortable: false,
editable: true,
edittype: "textarea",
editoptions: {
rows: "2",
cols: "10"
}
}, ],
viewrecords: true, //是否在瀏覽導航欄顯示記錄總數
rowNum: 10, //每頁顯示記錄數
rowList: [10, 20, 30], //用於改變顯示行數的下拉列表框的元素數組。
pager: pager_selector, //分頁、按鈕所在的瀏覽導航欄
altRows: true, //設置爲交替行表格,默認爲false
//toppager: true,//是否在上面顯示瀏覽導航欄
multiselect: false, //是否多選
//multikey: "ctrlKey",//是否只能用Ctrl按鍵多選
multiboxonly: true, //是否只能點擊複選框多選
// subGrid : true,
//sortname:'id',//默認的排序列名
//sortorder:'asc',//默認的排序方式(asc升序,desc降序)
caption: "採購退貨單列表", //表名
autowidth: true, //自動寬
onSelectRow : function(ids) {
jQuery(grid_selectoro).jqGrid('setGridParam', {
url :"<%=basePath%>"+"goodlistServlet?flag=true&id=" + ids,
page : 1
});
jQuery(grid_selectoro).jqGrid('setCaption',
"物資詳細類表" +" : " + ids).trigger(
'reloadGrid');
}
});
//瀏覽導航欄添加功能部分代碼
$(grid_selector).navGrid(pager_selector, {
search: true, // 檢索
add: true, //添加 (只有editable爲true時才能顯示屬性)
edit: true, //修改(只有editable爲true時才能顯示屬性)
del: true, //刪除
refresh: true //刷新
}, {}, // edit options
{}, // add options
{}, // delete options
{
multipleSearch: true
} // search options - define multiple search
);
$("#grid-tableo").jqGrid({
//用於檢索的Servlet URL
url:"<%=basePath%>"+"goodlistServlet?flag=false&",
//data: grid_data, //當 datatype 爲"local" 時需填寫
datatype:"json", //數據來源,本地數據(local,json,jsonp,xml等)
height: 150, //高度,表格高度。可爲數值、百分比或'auto'
mtype:"GET",//提交方式
colNames: ['物資編號', '物質類型', '物資名稱', '數量', ],
colModel: [{
name: 'g_id',
index: 'g_id', //索引。其和後臺交互的參數爲sidx
key: true, //當從服務器端返回的數據中沒有id時,將此作爲唯一rowid使用只有一個列可以做這項設置。如果設置多於一個,那麼只選取第一個,其他被忽略
width: 100,
editable: false,
editoptions: {
size: "20",
maxlength: "30"
}
}, {
name: 'g_type',
index: 'g_type',
width: 200, //寬度
editable: true, //是否可編輯
edittype: "select", //可以編輯的類型。可選值:text, textarea, select, checkbox, password, button, image and file.s
editoptions: {
value: "1:試劑;2:日用品;3:其他"
}
}, {
name: 'g_name',
index: 'g_name',
width: 150,
editable: true,
editoptions: {
size: "20",
maxlength: "30"
}
}, {
name: 'd_num',
index: 'd_num',
width: 60,
editable: true
}
],
viewrecords: true, //是否在瀏覽導航欄顯示記錄總數
rowNum: 10, //每頁顯示記錄數
rowList: [10, 20, 30], //用於改變顯示行數的下拉列表框的元素數組。
pager: pager_selectoro, //分頁、按鈕所在的瀏覽導航欄
altRows: true, //設置爲交替行表格,默認爲false
//toppager: true,//是否在上面顯示瀏覽導航欄
multiselect: false, //是否多選
//multikey: "ctrlKey",//是否只能用Ctrl按鍵多選
multiboxonly: true, //是否只能點擊複選框多選
// subGrid : true,
//sortname:'id',//默認的排序列名
//sortorder:'asc',//默認的排序方式(asc升序,desc降序)
caption: "物資詳細列表", //表名
autowidth: true //自動寬
});
//瀏覽導航欄添加功能部分代碼
$(grid_selectoro).navGrid(pager_selectoro, {
search: true, // 檢索
add: false, //添加 (只有editable爲true時才能顯示屬性)
edit: false, //修改(只有editable爲true時才能顯示屬性)
del: false, //刪除
refresh: true //刷新
}, {}, // edit options
{}, // add options
{}, // delete options
{
multipleSearch: true
} // search options - define multiple search
);
});
</script>
</body>
</html>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>jqGrid</display-name>
<servlet>
<servlet-name>demoServlet</servlet-name>
<servlet-class>com.xeonmic.action.demoServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>demochangeServlet</servlet-name>
<servlet-class>com.xeonmic.action.demochangeServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>goodlistServlet</servlet-name>
<servlet-class>com.xeonmic.action.goodlistServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demoServlet</servlet-name>
<url-pattern>/demoServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>demochangeServlet</servlet-name>
<url-pattern>/demochangeServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>goodlistServlet</servlet-name>
<url-pattern>/goodlistServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
顯示效果如下:
首次打開效果(未選中主錶行)
不知道你們有沒有發現這些地方有點不對勁?不知道是不是個例
如果你的顯示效果和我一樣,請打開css目錄下的ui.jqgrid.css的文件中刪除圈出來的兩部分
修改後刷新頁面後效果
點擊主表中的某一行從表的相應數據已經顯示(從表的表頭部分已顯示主表點擊行的id了 )
下面測試下主表的檢索(可以看到從表是不會改變的,因爲未點擊主表的行)
點擊後從表顯示正常
下面是從表檢索測試
這裏特別說明一下,如果你進行了從表檢索,再點擊主表的任何一行時,從表的檢索條件並未重置,需要手動點擊從表的重置
點擊從表的檢索按鈕會發現從表的檢索條件並未重置
點擊從表的重置按鈕後顯示正常
測試下主表的刪除
發現數據庫中關聯表中的數據也都刪除了(說明外鍵約束成功)
最後測試下主表的添加(這裏的添加是不完善的 因爲只添加了一個主表中的數據 未添加任何從表中的數據 ,刪除和添加僅僅是測試功能,真正應用主從表的顯示中可刪除這兩個功能)
添加成功,從表無任何數據
至此,主表表顯示設計實現已經全部結束,下篇將實現從表的添加數據修改數據的功能,即主從表全功能實現。如果你喜歡請關注http://blog.csdn.net/dfs4df5