3.1 本项目的将按照企业标准开发流程,将程序分成几个层次,同时使用mysql数据库,IDEA开发工具
![]() |
3.2 本程序主要是对新闻数据(编号、标题、发布日期、内容)的一个维护,具体要求:
a. 业务层--增加新闻数据
数据层--新闻表中保存新增的数据
b. 业务层--要列表实现新闻数据,同时还要求分页
数据层--通过数据库查询部分数据
数据层--统计所有新闻数据量
c. 业务层--可以修改新闻数据
数据层--修改标题和内容,不允许修改编号和发布日期
d. 业务层--可以删除指定新闻数据
数据层--通过编号批量删除数据
3.3 本次开发只实现最核心的功能,不涉及数据验证。
3.4 编写数据库脚本
news.sql
-- 删除数据库 DROP DATABASE IF EXISTS ms ; -- 创建数据表 CREATE DATABASE ms CHARACTER SET UTF8 ; -- 使用数据库 USE ms ; -- 删除数据表 DROP TABLE IF EXISTS news ; -- 创建数据表 CREATE TABLE news ( nid INT AUTO_INCREMENT , title VARCHAR(50) , pubdate DATETIME , content TEXT , CONSTRAINT pk_nid PRIMARY KEY (nid) )type=innodb; |
3.5 利用IDEA工具创建一个NewsProject项目,并导入bootstrap开发包和jquery的js文件,然后导入数据库脚本到src目录下
![]() |
3.6 利用mysql数据库工具运行上面的脚本从而建立一个数据表
![]() |
3.7 通过以上步骤完成了一些准备工作,现在为项目继续准备数据库的驱动程序
![]() |
3.8 现在定义一个数据库连接的类,它只负责数据库的打开与关闭
DatabaseConnection.java
public class DatabaseConnection { private static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; private static final String DBURL = "jdbc:mysql://localhost:3306/ms" ; private static final String USER = "root" ; private static final String PWD = "o" ; private Connection conn ; public DatabaseConnection(){ try { Class.forName(DBDRIVER); conn = DriverManager.getConnection(DBURL, USER, PWD); }catch(Exception e){ e.printStackTrace(); } } public Connection getConnection(){ return conn ; } public void close(){ if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } |

News.java
public class News implements Serializable{ private Integer nid ; private String title ; private String content ; private Date pubdate ; public Integer getNid() { return nid; } public void setNid(Integer nid) { this.nid = nid; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Date getPubdate() { return pubdate; } public void setPubdate(Date pubdate) { this.pubdate = pubdate; } } |
3.10 定义数据层的开发,这个层主要通过PreparedStatement类进行操作
![]() |
3.11 首先定义一个dao层的接口
INewsDAO.java
public interface INewsDAO { public boolean doCreate(News vo) throws Exception ; public boolean doUpdate(News vo) throws Exception ; public boolean doRemoveBatch(Set<Integer> nids) throws Exception ; public News findById(Integer nid)throws Exception ; public List<News> findAll(Integer currentPage,Integer lineSize)throws Exception ; public Integer getAllCount()throws Exception ; } |
3.12 然后再定义上面接口的实现子类
NewsDAOImpl.java
public class NewsDAOImpl implements INewsDAO{ private Connection conn ; private PreparedStatement pstmt ; String sql = null ; public NewsDAOImpl(Connection conn){ this.conn = conn ; } public boolean doCreate(News vo) throws Exception { sql = "INSERT INTO news(title,pubdate,content) VALUES(,,)" ; pstmt = conn.prepareStatement(sql) ; pstmt.setString(1,vo.getTitle()); pstmt.setDate(2,new java.sql.Date(vo.getPubdate().getTime())); pstmt.setString(3,vo.getContent()); return pstmt.executeUpdate()>0; } public boolean doUpdate(News vo) throws Exception { sql = "UPDATE news SET title=,content= WHERE nid=" ; pstmt = conn.prepareStatement(sql) ; pstmt.setString(1,vo.getTitle()); pstmt.setString(2,vo.getContent()); pstmt.setInt(1,vo.getNid()); return pstmt.executeUpdate()>0; } public boolean doRemoveBatch(Set<Integer> nids) throws Exception { if(nids.size() == 0) return false ; StringBuffer sql = new StringBuffer("DELETE FROM news WHERE nid IN ("); Iterator<Integer> iter = nids.iterator() ; while(iter.hasNext()){ sql.append(iter.next()+",") ; } sql.delete(sql.length()-1,sql.length()).append(")") ; //删除最后那个逗号 pstmt = conn.prepareStatement(sql.toString()) ; return pstmt.executeUpdate() == nids.size(); //不能用"> 0"这样不能保证所有的都能被删除 } public List<News> findAll(Integer currentPage, Integer lineSize) throws Exception { sql = "SELECT nid,title,content,pubdate FROM news LIMIT , " ; pstmt = conn.prepareStatement(sql) ; pstmt.setInt(1,(currentPage-1)*lineSize); pstmt.setInt(2,lineSize); List<News> list = new ArrayList<News>() ; ResultSet rs = pstmt.executeQuery(); while(rs.next()){ News news = new News(); news.setNid(rs.getInt("nid")); news.setTitle(rs.getString("title")); news.setContent(rs.getString("content")); news.setPubdate(rs.getDate("pubdate")); list.add(news) ; } return list; } public Integer getAllCount() throws Exception { sql = "SELECT COUNT(*) FROM news" ; pstmt = conn.prepareStatement(sql) ; ResultSet rs = pstmt.executeQuery() ; if(rs.next()) return rs.getInt(1); return 0 ; } } |
3.13 在定义了DAO层的实现类和接口以后,那么就需要为这个dao层定义一个工厂类,通过此工厂类就能得到DAO接口的对象
DAOFactory.java
public class DAOFactory { public static INewsDAO getINewsDAOInstance(Connection conn){ return new NewsDAOImpl(conn) ; } } |
日后在业务层就可以通过工厂类来取得DAO的对象。
3.14 现在进行业务层的开发,也是项目中最重要的一项,对数据库的开启关闭也都是在这一层完成的。首先定义业务层的接口
INewsService.java
public interface INewsSerivce { public boolean insert(News vo)throws Exception ; public boolean delete(Set<Integer> nids)throws Exception ; public boolean update(News vo)throws Exception ; public Map<String,Object> list(Integer currentPage,Integer lineSize)throws Exception ; |
public class NewsServiceImpl implements INewsSerivce{
private Connection conn ;
private DatabaseConnection db = new DatabaseConnection() ;
public NewsServiceImpl(){
conn =db.getConnection() ;
}
public boolean insert(News vo) throws Exception {
try {
return DAOFactory.getINewsDAOInstance(conn).doCreate(vo);
}catch(Exception e){
throw e ;
}finally {
db.close();
}
}
public boolean delete(Set<Integer> nids) throws Exception {
try {
return DAOFactory.getINewsDAOInstance(conn).doRemoveBatch(nids) ;
}catch(Exception e){
throw e ;
}finally {
db.close();
}
}
public boolean update(News vo) throws Exception {
try {
return DAOFactory.getINewsDAOInstance(conn).doUpdate(vo) ;
}catch(Exception e){
throw e ;
}finally {
db.close();
}
}
public Map<String, Object> list(Integer currentPage, Integer lineSize) throws Exception {
try {
Map<String,Object> map = new HashMap<String, Object>();
map.put("allCount",
DAOFactory.getINewsDAOInstance(conn).getAllCount());
map.put("selectedNews",
DAOFactory.getINewsDAOInstance(conn).findAll(currentPage,lineSize));
return map ;
}catch(Exception e){
throw e ;
}finally {
db.close();
}
}
}
|
3.16 本次项目的业务层实现不再区分前台或后台业务,现在定义业务层的工厂类
ServiceFactory.java
public class ServiceFactory { public static INewsSerivce getINewsServiceInstance(){ return new NewsServiceImpl(); } } |
3.17 通过以上的步骤就完成了整个业务层的实现。那么现在就剩下控制层的开发,在定义控制层时,由于存在编码的问题,所以需要增加一个编码的过滤器
EncodingFilter.java
@WebFilter(filterName = "EncodingFilter",urlPatterns="/*") public class EncodingFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //来回都设置了编码过滤 req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); chain.doFilter(req, resp); req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); } public void init(FilterConfig config) throws ServletException { } } |
3.18 定义控制层的核心功能
![]() |
NewsServlet.java
@WebServlet(name = "NewsServlet",urlPatterns = "/pages/news/NewsServlet/*") public class NewsServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String methodName = request.getPathInfo().substring(1); //获取输入的方法名称 try{ Method method = this.getClass().getMethod(methodName,HttpServletRequest.class,HttpServletResponse.class) ; method.invoke(this,request,response) ; }catch(Exception e){ e.printStackTrace(); } if(methodName==null||methodName.equals("")){ request.getRequestDispatcher("index") ; }else if(methodName.equalsIgnoreCase("insert")){ }else if(methodName.equalsIgnoreCase("delete")){ }else if(methodName.equalsIgnoreCase("update")){ }else if(methodName.equalsIgnoreCase("list")){ } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); } public void update(HttpServletRequest request,HttpServletResponse response)throws Exception{ News vo = new News() ; vo.setTitle(request.getParameter("title")); vo.setContent(request.getParameter("content")); //采用页面局部刷新更改数据--Ajax response.getWriter().print(ServiceFactory.getINewsServiceInstance().update(vo)); } public void delete(HttpServletRequest request,HttpServletResponse response)throws ServletException{ //删除操作也是采用的异步处理 String nids = request.getParameter("ids") ; try{ if(nids == null){ response.getWriter().print(false); }else{ Set<Integer> ids = new TreeSet<Integer>() ; String idSet[] = nids.split("\\|") ; for(int x=0 ;x<idSet.length ;x++){ ids.add(Integer.parseInt(idSet[x])) ; } response.getWriter().print(ServiceFactory.getINewsServiceInstance().delete(ids)) ; } }catch(Exception e){ e.printStackTrace() ; } } public void list(HttpServletRequest request,HttpServletResponse response)throws ServletException{ int lineSize = 5 ; try { lineSize = Integer.parseInt(request.getParameter("lineSize")) ; }catch(Exception e){} int currentPage = 1 ; try { currentPage = Integer.parseInt(request.getParameter("currentPage")); }catch(Exception e){} Map<String,Object> map = null ; List<News> list = null ; try { map = ServiceFactory.getINewsServiceInstance().list(lineSize,currentPage) ; if(map != null){ //数据是通过json传输的,所以定义json对象来传输数据 JSONObject obj = new JSONObject() ; JSONArray arr = new JSONArray() ; int allCount = (Integer)map.get("allCount") ; list = (List<News>)map.get("selectedNews") ; obj.put("allCount",allCount) ; Iterator<News> iter = list.iterator() ; while(iter.hasNext()){ JSONObject tmp = new JSONObject() ; News vo = iter.next() ; tmp.put("nid",vo.getNid()) ; tmp.put("content",vo.getContent()) ; tmp.put("title",vo.getTitle()) ; tmp.put("pubdate",new SimpleDateFormat("yyyy-MM-dd").format(vo.getPubdate())) ; arr.add(tmp) ; } obj.put("selectedNews",arr) ; response.getWriter().print(obj) ; }else{ response.getWriter().print(false) ; } } catch (Exception e) { e.printStackTrace(); } } public void insert(HttpServletRequest request,HttpServletResponse response)throws Exception{ News vo = new News() ; vo.setNid(Integer.parseInt(request.getParameter("nid"))); vo.setTitle(request.getParameter("title")); vo.setContent(request.getParameter("content")); vo.setPubdate(new Date()); String msg = "新闻数据增加失败!" ; String path = request.getContextPath()+"/pages/news/news_insert.jsp" ; //跳转路径 if(ServiceFactory.getINewsServiceInstance().insert(vo)){ msg = "新闻数据增加成功!" ; } request.setAttribute("msg",msg) ; request.setAttribute("path",path); request.getRequestDispatcher("/pages/forward.jsp").forward(request,response) ; } } |
3.19 项目中使用到了json数据传输,所以需要配置json的jar包
![]() |
![]() |
3.21 根据上图提示,定义一个forward.jsp页面
forward.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <script type="text/javascript" > alert(${msg}) ; window.location="${path}" ; </script> |
3.22 定义新闻增加页面
news_insert.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String path = request.getContextPath() ;
String basePath = request.getScheme()+"://"+request.getServerName()
+":"+request.getServerPort()+"/"+path ;
String insertUrl = basePath+"/pages/news/NewsServlet/insert" ;
%>
<html>
<head>
<base href="<%=basePath%>" />
<title>bootstrap综合应用</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1" >
<script type="text/javascript" src="bootstrap/js/jquery.min.js"></script>
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css">
</head>
<body>
<!--首先定义导航条-->
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="panel panel-success">
<div class="panel-heading">
<strong>增加新闻</strong>
</div>
<div class="panel-body">
<!-- 定义bootstrap样式的form表单 -->
<form action="<%=insertUrl%>" method="post" id="myForm" class="form-horizontal">
<fieldset>
<legend><label>新闻增加</label></legend>
<div class="form-group" id="titleDiv" >
<!-- 用label元素便于鼠标点击实现联动效果同时要设置for="title"才有效果 -->
<label class="col-md-3 control-label" for="title">标题:</label>
<div class="col-md-5">
<input id="title" name="title" type="text" value="test_title" placeholder="请输入标题" class="form-control">
</div>
<div class="col-md-4" id="titleSpan"></div>
</div>
<div class="form-group" id="contentDiv" >
<!-- 用label元素便于鼠标点击实现联动效果同时要设置for="content"才有效果 -->
<label class="col-md-3 control-label" for="content">新闻内容:</label>
<div class="col-md-5">
<textarea id="content" name="content" placeholder="请输入内容" class="form-control">test_content</textarea>
</div>
<div class="col-md-4" id="contentSpan"></div>
</div>
<!-- 定义两个按钮 -->
<div class="form-group">
<div class="col-md-5 col-md-offset-3" >
<button type="submit" class="btn btn-info">发布</button>
<button type="reset" class="btn btn-info">重置</button>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
|
效果图:
![]() |
3.23 通过测试上面的新闻功能ok后,现在实现新闻前端列表显示的功能,而此次列表显示需要分页显示,界面可以利用之前已经做过的分页显示界面。
![]() |
3.24 建立分页显示的公共函数页面
util.js
// 实现分页功能
var jsCommonCp = 1 ; //当前的页码
var jsCommonLs = 5 ; //每页显示数据量
var jsCommonPageSize ; //总页数
function createSplitBar(allRecorders){ //专门用于创建分页操作的
clearBar();
calcPageSize(allRecorders) ;
if(jsCommonPageSize > 1){
previousPage() ;
addBar(1) ;
}
var seed = 3 ; //设置一个显示省略号的临界点--种子数,如果大于它则出现,否则不出现
if(jsCommonCp > seed*2){
addDetailPage() ; //增加省略号按钮
var startPage = jsCommonCp - seed ;
for(var x=startPage ; x<jsCommonCp + seed ; x++){
if(x < jsCommonPageSize){
addBar(x) ;
}
}
if(jsCommonCp+2*seed < jsCommonPageSize){
addDetailPage() ;
}
}else{
for(var x = 2 ; x < jsCommonCp+seed ; x++){
if(x < jsCommonPageSize)
addBar(x) ;
}
if(jsCommonCp+seed < jsCommonPageSize){
addDetailPage() ;
}
}
addBar(jsCommonPageSize) ;
if(jsCommonPageSize > 1){
nextPage() ;
}
}
function clearBar(){ //定义数据的清空操作
$("#pagecontrol li").remove() ;
}
function addBar(index){ //用来生成分页功能的代码,即增加页面页码标签
var liObj = $("<li></li>") ; //定义一个li元素节点对象
var aObj = $("<a style='cursor:pointer;'>"+index+"</a>") ;
if(jsCommonCp == index){
liObj.addClass("active") ; //如果此页码正好为当前页则设置一个样式
}else{
aObj.on("click",function(){
jsCommonCp = index ;
loadData() ;
}) ;
}
liObj.append(aObj) ;
$("#pagecontrol").append(liObj) ;
}
function addDetailPage(){ //添加省略号按钮
var liObj = $("<li><span>...</span></li>") ;
$("#pagecontrol").append(liObj) ;
}
function previousPage(){ //在页面定义上一页按钮
var liObj = $("<li></li>") ; //定义一个li元素节点对象
var aObj = $("<a style='cursor:pointer;'>上一页</a>") ;
if(jsCommonCp == 1){
liObj.addClass("disabled") ; //如果此页码正好为当前页则设置一个样式
}else{
aObj.on("click",function(){
if(jsCommonCp > 1){ //如果还存在有上一页
jsCommonCp -- ;
loadData() ;
}
}) ;
}
liObj.append(aObj) ;
$("#pagecontrol").append(liObj) ;
}
function nextPage(){ //在页面定义下一页按钮
var liObj = $("<li></li>") ; //定义一个li元素节点对象
var aObj = $("<a style='cursor:pointer;'>下一页</a>") ;
if(jsCommonCp == jsCommonPageSize){
liObj.addClass("disabled") ; //如果此页码正好为当前页则设置一个样式
}else{
aObj.on("click",function(){
if(jsCommonCp < jsCommonPageSize){ //如果还存在有下一页
jsCommonCp ++;
loadData() ;
}
}) ;
}
liObj.append(aObj) ;
$("#pagecontrol").append(liObj) ;
}
function calcPageSize(allRecorders){ //计算总页数
//alert("calcPageSize function") ;
if(allRecorders == 0){
jsCommonPageSize = 1 ;
}else{
//js与java不一样此时不会自动转换成整型数据,需要手动设置
jsCommonPageSize = parseInt((allRecorders+jsCommonLs-1)/jsCommonLs) ;
}
}
|
$(function(){ loadData() ; }) ; // 读取JSP页面所返回的数 据 function loadData(){ //数据读取的函数定义 $.post("pages/news/NewsServlet/list",{"cp":jsCommonCp, "ls":jsCommonLs},function(obj){ createSplitBar(obj.allRecorders) ; },"json") ; } |
3.26 定义列表显示页面
news_list.jsp
<!-- 定义表格 --> <!-- bordered:表格带有边框线条、hover:鼠标移动时表格行的颜色改变、striped表格行的颜色隔行变换 --> <table class="table table-bordered tabel-hover table-striped" id="newsTable"> <tr> <td class="text-center"><input type="checkbox" id="selectedAll" name="selectedAll"></td> <td class="text-center"><strong>标题</strong></td> <td class="text-center"><strong>发布日期</strong></td> <td class="text-center"><strong>内容</strong></td> <td class="text-center"><strong>操作</strong></td> </tr> </table> <button class="btn btn-info" id="delBtn"><span class="glyphicon glyphicon-trash"></span> 删除</button> </div> <div id="dividedPage" class="text-right"> <ul class="pagination pagination-sm" id="pagecontrol"> </ul> </div> |
同时定义js功能实现列表功能
news_list.js
$(function(){
loadData() ;
}) ;
// 读取JSP页面所返回的数 据
function loadData(){ //数据读取的函数定义
$.post("pages/news/NewsServlet/list",{"cp":jsCommonCp,
"ls":jsCommonLs},function(obj){
$("#newsTable tr:gt(0)").remove() ;
createSplitBar(obj.allCount) ;
for(var i= 0 ;i<obj.selectedNews.length ;i++){
addRow(obj.selectedNews[i].nid,obj.selectedNews[i].title,obj.selectedNews[i].content,obj.selectedNews[i].pubdate);
}
},"json") ;
}
//增加表格行
function addRow(nid,title,content,pubdate){
var str = "<tr><td class='text-center'><input type='checkbox'"+
"id='nid' name='nid' value='"+nid+"'></td>"+
"<td class='text-center' id='title-'"+nid+">"+title+"</td>"+
"<td class='text-center' id='pubdate-'"+nid+">"+pubdate+"</td>"+
"<td class='text-left' id='content-'"+nid+">"+content+"</td>"+
"<td id='btn-'"+nid+"><btn id='updateBtn-"+nid+"' data-toggle='modal' data-target='#newsInfo' "+
"class='btn btn-info'><span class='glyphicon glyphicon-pencil'>"+
"</span> 修改</btn></td></tr>"
$("#newsTable").append($(str)) ;
$("#updateBtn-"+nid).on("click",function(){
$("#snid").text(nid) ;
$("#title").val(title) ;
$("#content").val(content) ;
}) ;
}
|
然后定义分页显示的页面
util.js
var jsCommonCp = 1 ; //当前的页码
var jsCommonLs = 5 ; //每页显示数据量
var jsCommonPageSize ; //总页数
function createSplitBar(allRecorders){ //专门用于创建分页操作的
clearBar();
calcPageSize(allRecorders) ;
if(jsCommonPageSize > 1){
previousPage() ;
addBar(1) ;
}
var seed = 3 ; //设置一个显示省略号的临界点--种子数,如果大于它则出现,否则不出现
if(jsCommonCp > seed*2){
addDetailPage() ; //增加省略号按钮
var startPage = jsCommonCp - seed ;
for(var x=startPage ; x<jsCommonCp + seed ; x++){
if(x < jsCommonPageSize){
addBar(x) ;
}
}
if(jsCommonCp+2*seed < jsCommonPageSize){
addDetailPage() ;
}
}else{
for(var x = 2 ; x < jsCommonCp+seed ; x++){
if(x < jsCommonPageSize)
addBar(x) ;
}
if(jsCommonCp+seed < jsCommonPageSize){
addDetailPage() ;
}
}
addBar(jsCommonPageSize) ;
if(jsCommonPageSize > 1){
nextPage() ;
}
}
function clearBar(){ //定义数据的清空操作
$("#pagecontrol li").remove() ;
}
function addBar(index){ //用来生成分页功能的代码,即增加页面页码标签
var liObj = $("<li></li>") ; //定义一个li元素节点对象
var aObj = $("<a style='cursor:pointer;'>"+index+"</a>") ;
if(jsCommonCp == index){
liObj.addClass("active") ; //如果此页码正好为当前页则设置一个样式
}else{
aObj.on("click",function(){
jsCommonCp = index ;
loadData() ;
}) ;
}
liObj.append(aObj) ;
$("#pagecontrol").append(liObj) ;
}
function addDetailPage(){ //添加省略号按钮
var liObj = $("<li><span>...</span></li>") ;
$("#pagecontrol").append(liObj) ;
}
function previousPage(){ //在页面定义上一页按钮
var liObj = $("<li></li>") ; //定义一个li元素节点对象
var aObj = $("<a style='cursor:pointer;'>上一页</a>") ;
if(jsCommonCp == 1){
liObj.addClass("disabled") ; //如果此页码正好为当前页则设置一个样式
}else{
aObj.on("click",function(){
if(jsCommonCp > 1){ //如果还存在有上一页
jsCommonCp -- ;
loadData() ;
}
}) ;
}
liObj.append(aObj) ;
$("#pagecontrol").append(liObj) ;
}
function nextPage(){ //在页面定义下一页按钮
var liObj = $("<li></li>") ; //定义一个li元素节点对象
var aObj = $("<a style='cursor:pointer;'>下一页</a>") ;
if(jsCommonCp == jsCommonPageSize){
liObj.addClass("disabled") ; //如果此页码正好为当前页则设置一个样式
}else{
aObj.on("click",function(){
if(jsCommonCp < jsCommonPageSize){ //如果还存在有下一页
jsCommonCp ++;
loadData() ;
}
}) ;
}
liObj.append(aObj) ;
$("#pagecontrol").append(liObj) ;
}
function calcPageSize(allRecorders){ //计算总页数
// alert("calcPageSize function:allRecorders="+allRecorders) ;
if(allRecorders == 0){
jsCommonPageSize = 1 ;
}else{
//js与java不一样此时不会自动转换成整型数据,需要手动设置
jsCommonPageSize = parseInt((allRecorders+jsCommonLs-1)/jsCommonLs) ;
}
}
|
效果图:
![]() |
3.27 定一个bootstrap的模态弹出窗口,此窗口主要用来显示数据更新的
news_list.jsp
<%--定义模态窗口--%> <div class="modal" id="newsInfo"> <div class="modal-dialog" style="width: 600px"> <div class="modal-content"> <div class="modal-header"> <button class="close" data-dismiss="modal">×</button> <h4 class="modal-title">新闻数据编辑</h4> </div> <div class="modal-body"> <form method="post" id="myForm" class="form-horizontal"> <fieldset> <legend><label>新闻编辑</label></legend> <div class="form-group" id="snidDiv" > <label class="col-md-3 control-label" for="title">编号:</label> <div class="col-md-5"> <span id="snid"></span> </div> <div class="col-md-4" id="snidSpan"></div> </div> <div class="form-group" id="titleDiv" > <!-- 用label元素便于鼠标点击实现联动效果同时要设置for="title"才有效果 --> <label class="col-md-3 control-label" for="title">标题:</label> <div class="col-md-5"> <input id="title" name="title" type="text" value="test_title" placeholder="请输入标题" class="form-control"> </div> <div class="col-md-4" id="titleSpan"></div> </div> <div class="form-group" id="contentDiv" > <!-- 用label元素便于鼠标点击实现联动效果同时要设置for="content"才有效果 --> <label class="col-md-3 control-label" for="content">新闻内容:</label> <div class="col-md-5"> <textarea id="content" name="content" placeholder="请输入内容" class="form-control">test_content</textarea> </div> <div class="col-md-4" id="contentSpan"></div> </div> <!-- 定义两个按钮 --> <div class="form-group"> <div class="col-md-5 col-md-offset-3" > <button type="submit" class="btn btn-info" id="updateBtn">修改</button> </div> </div> </fieldset> </form> </div> <div class="modal-footer"> <button class="btn btn-success" data-dismiss="modal">关闭界面</button> </div> </div> </div> </div> |
$("#updateBtn-"+nid).on("click",function(){ $("#snid").text(nid) ; $("#title").val(title) ; $("#content").val(content) ; |
![]() |
3.28 在定义完了修改的模态界面之后,那么现在就可以对修改按钮所触发的事件进行定义了。
![]() |
定义修改数据的函数
news_list.js
function updateNews(){ var nid = $("#snid").text(); var title = $("#title").val() ; var content = $("#content").val() ; $.post("pages/news/NewsServlet/update",{"nid":nid,"title":title,"content":content}, function(obj){ if(obj.trim() == "true"){ $("#alertDiv").attr("class","alert alert-success") ; $("#alertText").text("修改成功!") ; //后台数据修改成功后,那么前台列表页相应的数据肯定要同步更新 $("#title-"+nid).text(title) ; $("#content-"+nid).text(content) ; }else{ //表示修改失败 $("#alertDiv").attr("class","alert alert-danger") ; $("#alertText").text("修改失败!") ; } },"text") ; //更新完毕后需要自动关闭模态窗口 $("#newsInfo").modal("hide") ; //同时更新的状态信息也逐渐消失 $("#alertDiv").fadeIn(1000,function(){ $("#alertDiv").fadeOut(3000) ; }); } |
然后需要在前台页面定义后台数据修改状态的反馈信息
news_list.jsp
<%--用来显示后台数据更新的状态--%> <div class="alert alert-info" style="display: none;" id="alertDiv"> <button class="colse">×</button> <span id="alertText"></span> </div> |
3.29 定义完了新闻增加、修改、列表显示之后现在就只剩下新闻删除的工作了,同样是通过ajax来完成,之前列表页已经存在了删除的按钮,所以就直接定义删除按钮相关的函数
util.js/触发全选的元素 // 被全选的元素 function checkboxSelectedAll(eleA,eleB){ //实现复选框全选操作 eleA.on("click",function(){ eleB.each(function(){ this.checked = eleA.prop("checked") ; //把eleA元素的属性checked赋值给前面 }) ; }) ; } // 删除按钮的选择器 // ajax异步处理的链接 // 所有被选上的复选框 function deleteBtn(ele,cele,url){ ele.on("click",function(){ var selectedItem = "" ; //保存所有要删除的数据 cele.each(function(){ //针对每一个满足选择要求的元素都调用一次定义的函数 if(this.checked){ //如果当前的元素有tmd被选中,那么就要执行下列语句 selectedItem += this.value+"|" ; } }); if(selectedItem == ""){ alert("对不起,你他妈还没有选择任何元素,请先选择?"); }else{ if(window.confirm("你丫真要删除所选择的数据吗?")){ // 如果要删除就通过ajax调用后台实现数据删除的操作 $.post(url,{"ids":selectedItem},function(obj){ if(obj.trim("true")){ $("#alertDiv").attr("class","alert alert-success") ; $("#alertText").text("删除成功") ; loadData() ; //重新刷新列表页 }else{ $("#alertDiv").attr("class","alert alert-danger") ; $("#alertText").text("删除失败") ; } $("#alertDiv").fadeIn(1000,function(){ $("#alertDiv").fadeOut(3000) ; }) },"text") ; } } }); } |
function loadData(){ //数据读取的函数定义 $.post("pages/news/NewsServlet/list",{"cp":jsCommonCp, "ls":jsCommonLs},function(obj){ $("#newsTable tr:gt(0)").remove() ; createSplitBar(obj.allCount) ; for(var i= 0 ;i<obj.selectedNews.length ;i++){ addRow(obj.selectedNews[i].nid,obj.selectedNews[i].title,obj.selectedNews[i].content,obj.selectedNews[i].pubdate); } checkboxSelectedAll($("#selectedAll"),$("input[id='nid']")); deleteBtn($("#delBtn"),$("input[id='nid']"),"pages/news/NewsServlet/delete"); },"json") ; } |
![]() |
- 顶
- 0
- 踩
- 0
下一篇:HTML5知识点总结
-
在VMware虚拟机里安装Linux操作系统
这篇文章介绍了在VMware虚拟机里安装Linux操作系统的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
-
在CentOS7上搭建本地GitLab服务器
本文详细讲解了在CentOS7上面搭建本地GitLab服务器的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
-
分布式架构中关于正向代理反向代理面试提问
这篇文章主要为大家介绍了分布式架构中关于正向代理反向代理的面试提问,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
-
基于nginx反向代理获取用户真实Ip地址详细介绍
我们访问互联网上的服务时,大多数时客户端并不是直接访问到服务端的,而是客户端首先请求到反向代理,反向代理再转发到服务端实现服务访问,这篇文章主要给大家介绍了关于如何基于nginx反向代理获取用户真实I
-
使用Docker镜像构建Go应用的实现办法
本文主要介绍了使用Docker镜像构建Go应用的实现方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
- asp.net 源码
- 导航网站模板
- 网站客服代码
- 图片代码
- asp网站建设
- asp下载
- 个人网站源码
- asp文件
- 即时通讯
- 源码超市
- html5网站
- 网站模版下载
- 源码中国
- 导航条代码
- 网页模板
- 模版
- 学生个人网页制作
- 网页模板下载
- 企业网站源码
- 网站模板免费下载
- 整站模板
- 个人网页制作模板
- 商业源码
- 呼叫中心源码
- 网站源代码下载
- 源码之家
- 免费源码
- 免费网站模板下载
- php代码
- 源代码下载
- 图片识别植物
- 网页制作模板
- php cms
- 网站下载
- 免费个人网站模板
- 网站首页模板
- 手机源码
- 站长下载
- 源码社区
- 网站 模板
- 小区物业管理系统
- 电脑登录界面
- 源码网站
- 导航网站源码
- css模板
- 安卓源码下载
- 免费商业源码
- 中易广告联盟系统
- html源代码
- 在线客服代码