57-005-3 bootstrap实现一个简单的项目案例--新闻操作(基于jsp无刷新异步操作)

图文版页面:http://note.youdao.com/share/?id=fc2d42d8ce97bea6f3272c02e92a2d23&type=note

资源文件下载:https://yunpan.cn/OcRdu34JqpRdtw 访问密码
67af

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();

}

}

}

}

3.9 下面就定义一个vo类的javabean

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 ;

3.15 定义业务层的实现类

NewsServiceImpl.java


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.20 控制层over后,现在就处理显示层,本次显示层利用jsp与bootstrap进行处理。首先处理新闻增加的界面显示


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) ;

}

}

3.25 定义列表显示的页面功能函数页面

news_list.js


$(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">&times;</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>

为了在点击修改按钮后弹出的模态窗口能同时显示修改之前的数据,需要定义相应的js文件

news_list.js


    $("#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">&times;</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") ;

}

}

});

然后再定义调用删除函数的方法

news_list.js


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") ;

}

最终效果图:


时间: 2024-09-29 19:42:57

57-005-3 bootstrap实现一个简单的项目案例--新闻操作(基于jsp无刷新异步操作)的相关文章

c# 自己制作一个简单的项目倒计时器

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace date { public partial class Form1 : Form { public Form1() { InitializeCompo

一个简单的项目流程

一个简单的项目流程 一.需求分析 二.设计 技术选型 数据库设计 三.开发 环境搭建 编码 四.测试 五.部署运维 原文地址:https://www.cnblogs.com/zhuobo/p/10806758.html

Django入门第一步(安装和创建一个简单的项目)

目录 Django入门第一步(安装和创建一个简单的项目) 一. Django项目目录结构 二.注意事项 三.Django安装 3.1.安装命令 3.2.验证django是否安装成功 3.3.使用方法 Django入门第一步(安装和创建一个简单的项目) 在使用Django框架开发web应用程序时,开发阶段同样依赖wsgiref模块来实现Server的功能,我们使用Django框架是为了快速地开发application. 如果使用的是我们自定义的框架来开发web应用,需要事先生成框架包含的一系列基础

[bootstrap] 打造一个简单的系统模板(1) 左侧折叠菜单

1. 前言 最近需要做一个后台管理系统,我打算使用bootstrap弄一个好看的后台模板.网上的好多模板我觉的css和js有点重. 于是就打算完全依靠bootstrap搭建一个属于自己的模板. 首先从左侧的折叠菜单开始.看图. 2. CSS 代码 以下是自定义的css代码,由于系统是内部使用,所以优先考虑chrome,firefox 不考虑IE了. #main-nav { margin-left: 1px; } #main-nav.nav-tabs.nav-stacked > li > a {

一个简单的顺序表基础操作示例

最近学计算机软件基础,学到了线性表.下面就将线性表中最简单的顺序表的一个简单示例贴出,方便大家探讨.(以及后面对函数传参的一个小分析,其实这才是重点) 1 ////需求分析 2 //1.线性表递增有序,删除重复元素 3 //2.线性表逆置 4 //3.寻求最大值 5 6 #include<stdio.h> 7 8 typedef int ElementType; 9 typedef struct _struct 10 { 11 ElementType SequenceList[100]; 12

Servlet以及一个简单的登录案例

1.servlet的概述 就是一个运行在web服务器上的小的java程序,用来接收和响应从客户端发送过来的请求,通常使用http协议 就是sun公司提供的一个动态网页开发技术 作用:用来处理从客户端浏览器发送的请求,并且可以对请求作出响应 编写类实现servlet: public class Demo1 implements Servlet{ @Override /** * 为用户处理请求和响应的方法. */ public void service(ServletRequest req, Ser

用bootstrap写一个简单的静态网页

先说点题外话,如果想直接进入bootstrap正题请从第二段开始.周五面试一个小公司,给了我一个psd图让我用最快的时间还愿出这个静态页面,要求是能保证兼容性以及web响应式各种屏幕正常显示.周五晚上开始着手做到了凌晨,然后周六睡了一天的觉补回来,发现现在精力真不比大学毕业.周天放松了一天,炉石新版本巫妖王的骑士刚开,必须玩一下.TI7newbee输了.中国新歌声这届真的不行.中国有嘻哈到目前为止最喜欢小青龙的才气(可惜声音一般),希望带来更多好听的歌,PGone应该是夺冠热门,现场气氛被带动到

使用Python实现一个简单的项目监控

在公司里做的一个接口系统,主要是对接第三方的系统接口,所以,这个系统里会和很多其他公司的项目交互.随之而来一个很蛋疼的问题,这么多公司的接口,不同公司接口的稳定性差别很大,访问量大的时候,有的不怎么行的接口就各种出错了. 这个接口系统刚刚开发不久,整个系统中,处于比较边缘的位置,不像其他项目,有日志库,还有短信告警,一旦出问题,很多情况下都是用户反馈回来,所以,我的想法是,拿起python,为这个项目写一个监控.如果在调用某个第三方接口的过程中,大量出错了,说明这个接口有有问题了,就可以更快的采

spring security+mybatis+springMVC构建一个简单的项目

1.引用 spring security ,这是一种基于spring AOP和Servlet的过滤安全框架.它提供全面的安全性解决方案,同时在web请求级和方法的调用级处理身份确认和授权.在spring framework基础上,spring security充分利用了依赖注入(DI,Dependency Injection)和AOP技术. 下面就让我们用一个小的晓得项目来出初步了解Spring Security 的强大功能吧. 2.项目实战    1)项目的技术架构:maven+spring