这个版本主要是完成市场活动的相关操作。比如给创建市场活动按钮绑定事件、还有最重要的pageList()方法,即:分页操作。
1.为创建按钮绑定事件
这个地方要注意的就是,因为打开的是模态窗口,然后里面有些内容是需要从后台上取数据之后铺上去的。
所以我们就正常发起ajax请求从后台取得数据就行,这里取得user表的name,但是必须是去所有的,返回的就是userList,然后在前端去拼接就行。然后默认选择当前登录用户作为显示的结果:
//默认选中当前登录的用户=====应当是里面有内容之后再选择,一开始我放在上面了
var id = "${user.id}";
$("#create-owner").val(id);
这里需要注意的一个点是:这里的选择默认的值,是在你拼好select标签里面的内容之后才执行的,我做的时候,上面的代码直接放在了前面。
2.为创建市场活动模态窗口的 保存 按钮绑定事件
这个需求也是比较简单的,文本框填好值,前端取到值,后端去接收就行。然后调用dao执行数据库的保存操作就行。
这里里面需要用到日历控件,直接复制添加就行:
$(".time").datetimepicker({
minView: "month",
language: 'zh-CN',
format: 'yyyy-mm-dd',
autoclose: true,
todayBtn: true,
pickerPosition: "bottom-left"
});
这里做的时候,出现乱码了,最后只能把jquery/bootstrap-datetimepicker-master/locale/bootstrap-datetimepicker.zh-CN.js这个文件里面的内容放到js代码中才解决。
然后要用这个日历控件的话,直接在需要用的地方的class属性后面加上time就行
3.最重要的pageList()方法
因为查询条件不一定有,所以我们要使用到mybatis的动态sql。中间的那部分内容有6个地方需要刷他
(1)点击左侧菜单中的"市场活动"超链接,需要刷新市场活动列表,调用pageList方法
(2)添加,修改,删除后,需要刷新市场活动列表,调用pageList方法
(3)点击查询按钮的时候,需要刷新市场活动列表,调用pageList方法
(4)点击分页组件的时候,调用pageList方法
pageList(pageNo,pageSize)是有参数的:
pageNo:页码
pageSize:每页展现的记录数
另外,前端有分页插件,需要总记录条数,所以从后台取得值应该是这样的{“total”:total,[{市场活动1},{市场活动2}…]},发的是ajax请求,取数据就行了
function pageList(pageNo,pageSize){ //第几页,展现几条
//将隐藏域中的内容放到search框里面
$("#search-name").val($.trim($("#hidden-name").val()));
$("#search-owner").val($.trim($("#hidden-owner").val()));
$("#hsearch-startDate").val($.trim($("#hidden-startDate").val()));
$("#search-endDate").val($.trim($("#hidden-endDate").val()));
var name = $.trim($("#search-name").val());
var owner = $.trim($("#search-owner").val());
var startDate = $.trim($("#search-startDate").val());
var endDate = $.trim($("#search-endDate").val());
$.ajax({
url:"workbench/activity/pageList.do",
data:{"pageNoStr":pageNo,
"pageSizeStr":pageSize,
"name":name,
"owner":owner,
"startDate":startDate,
"endDate":endDate
},
type:"GET",
dataType:"json", //预期服务器返回的数据类型
success:function (data){
// {dataList: activityList, total: 总记录条数分页插件要用到}
var html = "";
$.each(data.dataList,function (i,n){
html += '<tr class="active">';
html += '<td><input type="checkbox" name="xuanze" value="'+n.id+'" /></td>';
html += '<td><a style="text-decoration: none; cursor: pointer;" οnclick="window.location.href=\'detail.jsp\';">'+n.name+'</a></td>';
html += '<td>'+n.owner+'</td>';
html += '<td>'+n.startDate+'</td>';
html += '<td>'+n.endDate+'</td>';
html += '</tr>';
})
$("#activityBody").html(html);
//计算出下面需要的总页数
var totalPages = data.total%pageSize==0?data.total/pageSize:parseInt(data.total/pageSize)+1;
//数据处理完毕后,结合分页查询,对前端展现分页信息----下面的代码直接从文档赋值
$("#activityPage").bs_pagination({
currentPage: pageNo, // 页码
rowsPerPage: pageSize, // 每页显示的记录条数
maxRowsPerPage: 20, // 每页最多显示的记录条数
totalPages: totalPages, // 总页数
totalRows: data.total, // 总记录条数
visiblePageLinks: 3, // 显示几个卡片
showGoToPage: true,
showRowsPerPage: true,
showRowsInfo: true,
showRowsDefaultInfo: true,
onChangePage : function(event, data){
pageList(data.currentPage , data.rowsPerPage);
}
});
}
})
}
因为这个分页在很多模块都需要使用,所以在后端往前端返回对象的时候,我们直接封装了一个PaginationVO对象,使用泛型的方式,你给T什么,这个对象里面就是什么。
在controller里面
@ResponseBody
@RequestMapping("/workbench/activity/pageList.do")
public PaginationVO<Activity> pageList(String pageNoStr,String pageSizeStr,
String name,String owner,String startDate,String endDate){
System.out.println("=====市场活动控制器,执行分页方法=========");
Integer pageNo = Integer.valueOf(pageNoStr);
Integer pageSize = Integer.valueOf(pageSizeStr);
//计算出略过的记录数
int skipCount = (pageNo-1)*pageSize;
System.out.println("pageNo,"+pageNo+"pageSize,"+pageSize+"name,"+name+"owner,"+owner+"startDate,"+startDate+"endDate,"+endDate);
PaginationVO<Activity> paginationVO = activityService.pageList(skipCount,pageSize,name,owner,startDate,endDate);
return paginationVO;
}
在service实现类里面
@Override
public PaginationVO<Activity> pageList(int skipCount, Integer pageSize, String name, String owner, String startDate, String endDate) {
PaginationVO<Activity> paginationVO = new PaginationVO<>();
//获取总条数
int count = activityDao.getTotalByCondition(name,owner,startDate,endDate);
//获取市场活动记录
List<Activity> activityList = activityDao.getActivityListByCondition(skipCount,pageSize,name,owner,startDate,endDate);
paginationVO.setTotal(count);
paginationVO.setDataList(activityList);
return paginationVO;
}
注意,在访问数据库的时候,因为需要展现的所有者user的名字,这就涉及到了多表联查,而且查询条件不一定有,就有了动态sql。
<select id="getActivityListByCondition" resultType="Activity">
select
a.id,
u.name as owner,
a.name,
a.startDate,
a.endDate
from tbl_activity a
join tbl_user u
on a.owner=u.id
<where>
<if test="name != null and name != ''">
a.name like '%' #{name} '%'
</if>
<if test="owner != null and owner != ''">
and u.name like '%' #{owner} '%'
</if>
<if test="startDate != null and startDate != ''">
and a.startDate > #{startDate}
</if>
<if test="endDate != null and endDate != ''">
and a.endDate < #{endDate}
</if>
</where>
order by a.createTime desc
limit #{skipCount},#{pageSize}
</select>
在getTotalByCondition()里面也是如此。
上面基本上可以查询出来了。但还存在一些小问题。后面说。
在做这个的时候,我踩到了一个超级大坑。就是在原来的jsp页面的,查询条件的文本框的内容是在form表单里面的,而且这个时候的type属性是submit,必须要把他改成button,不然点的时候,他最后都会提交一张没有任何参数的表单,而且是在你触发了你的按钮的click方法之后才提交的,导致你最后在查询条件里面输入什么都不好使,因为最终查出来的肯定是没有任何条件的数据。坑死我了。。。。。。。。。找了好久,吃完饭回来找到了。发现每次我遇到一个超级大坑,吃完饭回来之后找到原因的可能性最大。
4.前端的分页插件
1.首先引入外部文件,复制文件到jquery里面。
2.在jsp页面引入资源,记得pom文件刷一下。
3.然后把原来的分页组件删掉,成对的删。
4.在pageList.do处理ajax返回值后,加入分页组件(代码直接复制)
$("#activityPage").bs_pagination({
currentPage: pageNo, // 页码
rowsPerPage: pageSize, // 每页显示的记录条数
maxRowsPerPage: 20, // 每页最多显示的记录条数
totalPages: totalPages, // 总页数
totalRows: data.total, // 总记录条数
visiblePageLinks: 3, // 显示几个卡片
showGoToPage: true,
showRowsPerPage: true,
showRowsInfo: true,
showRowsDefaultInfo: true,
onChangePage : function(event, data){
pageList(data.currentPage , data.rowsPerPage);
}
});
这里的 totalPages 要使用后台传回来的total算一下
然后应该就可以了。
5.隐藏域的使用
上面处理完之后,还处在一些问题:
问题1:
在查询框中输入内容,不点击查询按钮
点击分页按钮
结果为查询框中的内容生效了
问题2:
在查询框中输入内容,点击查询按钮
再在查询框中输入内容,不点击查询按钮
点击分页按钮
结果为新的查询框中的内容生效了
解决上面的问题,就需要使用到隐藏域的内容。做法:
将查询条件放到隐藏域当中,每一次翻页的时候,条件都从隐藏域当中取。
什么时候更新隐藏域?
(1)点击查询按钮的时候将查询框中的内容更新(保存内容到)隐藏域。
hidden–>search 将查询的保存到隐藏域中
(2)执行pageList的时候,将隐藏域中的内容更新熬查询框。
search–>hidden 将隐藏域中的内容保存到查询文本框
6.全选框和复选框的操作
1.挑全选,下面的两个自动选择。
----可以拿到全选框的jQuery对象,调用click方法实现需求
$("#qx").click(function () {
$("input[name=xz]").prop("checked",this.checked);
})
2.下面两个选择了,全选也挑上。一个取消选,全选取消。
这里需要注意一个问题,因为下面的两个是动态拼接的。
因为动态生成的元素,是不能够以普通绑定事件的形式来进行操作的。动态生成的元素,我们要以on方法的形式来触发事件
语法:
$(需要绑定元素的有效的外层元素).on(绑定事件的方式,需要绑定的元素的jquery对象,回调函数)
$("#activityBody").on("click",$("input[name=xz]"),function () {
$("#qx").prop("checked",$("input[name=xz]").length==$("input[name=xz]:checked").length);
})
几大我踩的大坑
1.因为这是一个新的模块,所有的包、类、文件什么都是重新建的。一开始的时候,比如:创建controller,我就没有在上面加注解,ServiceImpl也是,在配置文件里面也没有声明这些包的存在,导致跑起来老是出错。所以,撘项目的时候,注解什么的一定要及时加上。
2.在创建activityDao的时候,因为我是用的是自己的模板,里面是有中文提示,哪个地方是写什么的,但是我创建好之后,我就没有理这些东西,也没有把他更新或者注释,最后导致跑起来也是一直出错。所以,就是没用到的文件,里面的内容不要随便乱填,给注释了。
3.就是前面说的超级大坑,type类型是submit,一直在提交空的表单。。。。。。。。。。。。。。。。
今天时间不早了,就更新到这吧。 下一次还是市场活动模态,应该是修改和删除按钮的事件了。