先上效果图:
实现的功能主要是点击顶部三个按钮时,左侧导航栏切换到各自按钮下的选项框且默认第一个被选中,与此同时右侧表格显示第一栏选中的学校数据。
首先,顶部的三个选项框是通过后台execute方法直接获取的
public void execute(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//使用request方法,在页面加载前获取本科、高职、独立院校名称
Map map = new HashMap();
List<Map> results = gjbxtjDomain.getButton(map);
request.setAttribute("map", results);
}
其中,execute方法是website前端框架中的一个页面处理类,其功能是页面渲染,在需要渲染界面时,并且存在页面处理类,页面处理类必须定义一个public的execute方法,当请求页面时,会执行该页面处理类的execute方法。execute方法中可以做一些渲染页面所需的查询操作,用于向页面提供数据。页面处理类不是必须的,可以没有。
前台页面通过EL表达式获取数据:
<div class="query_btns">
<ul class="nav nav-tabs">
<c:forEach var="item" items="${map}" varStatus="varStatus">
<c:choose>
<c:when test="${varStatus.index eq 0}">
<li class="active"><a
href="javascript:;" id="${item.BSM}"><c:out
value="${item.MC}"></c:out></a></li>
</c:when>
<c:otherwise>
<li><a href="javascript:;"
id="${item.BSM}"><c:out value="${item.MC}"></c:out></a></li>
</c:otherwise>
</c:choose>
</c:forEach>
</ul>
</div>
js代码如下
$('.query_btns a').click(function() {
$(this).parent().addClass("active").siblings().removeClass("active");
var $t = $(this);
var bsm = $t.attr('id');
gjbxtj.code = bsm;
leftObj.pd_f = true;
getGjbxtj();
});
var leftObj = {
val: ko.observableArray([]),
clickLi : function(data){
$('#left_list li:contains("'+data.mc+'")').addClass("active").siblings().removeClass("active");
leftObj.pd = false;
gjbxtj.code = data.xxbsm;
getGjbxtj();
},
pd:true,
pd_f:true,
};
这里对左侧列表的点击事件加了一个判断,这里需要注意的两个参数pd 和 pd_f,整理一下逻辑是,第一次刷新页面时,只点击了顶部选项,此时默认显示所选按钮的分类以及分类中第一个的数据,所以需要模拟一次点击来让右边的表格加载数据,这就用到了pd_f,一开始初始化为true,第一次点击后加载左侧列表数据以及列表第一个的数据,pd_f布尔值变为false;此后不再使用。
此处定义的leftObj指的是左侧的导航栏目,对于参数pd,一开始为true,在顶部按钮执行clickLi事件时,运行了getGjbxtj()这个函数,根据if判断,左侧导航栏加载数据,同时右侧表格加载导航栏第一栏目的数据,此时pd变为false;这样在点击左侧列表时,列表就不会重新加载数据,而是右侧表格加载数据。
第二部分左侧的导航栏及右侧表格通过knockoutjs实现的数据绑定。
首先编写左侧导航栏的部分,默认对第一个选项加载了bootstrap样式,所以这里有一个index的判断;
<ul id="left_list" class="nav nav-pills nav-stacked" data-bind="foreach: val">
<!--ko if:$index() == 0 -->
<li class="active hover" role="presentation"
data-bind="click:$parent.clickLi,attr:{'data-code':xxbsm}"><a
data-bind="text: mc"></a></li>
<!--/ko-->
<!--ko if:$index() != 0 -->
<li class="hover" role="presentation"
data-bind="click:$parent.clickLi,attr:{'data-code':xxbsm}"><a
data-bind="text: mc"></a></li>
<!--/ko-->
</ul>
这里涉及knockoutjs的click绑定,这里的clickLi即为上部分写的下钻函数;接下来编写右侧表格的部分,基本的DOM结构如下:此处删除了引用的bootstrap样式,使用了knockoutjs的text绑定
<div class="stage_school_sum">
<h3>各学校高等教育办学条件概况</h3>
<div id="gjbxtj">
<table class="table table-bordered">
<thead>
<tr>
<th>名称</th>
<th>生师比</th>
<th>研究生学位教师比例(%)</th>
<th>生均教学行政用房(平方米/生)</th>
<th>生均教学科研仪器设置值(元/生)</th>
<th>生均图书(册/生)</th>
</tr>
</thead>
<tbody class="table-data" data-bind="foreach: val">
<tr>
<td data-bind="text:mc,click:$parent.drill"></td>
<td data-bind="text:ssb"></td>
<td data-bind="text:yjs_jsbl"></td>
<td data-bind="text:xzyf"></td>
<td data-bind="text:jxkyyqsz"></td>
<td data-bind="text:sjtj"></td>
</tr>
</tbody>
</table>
</div>
</div>
这里使用了knockoutjs的foreach绑定,这里foreach绑定需要绑定一个数组对象,即val,这个参数将在后面的js中定义,如下:
var gjbxtj = {
val: ko.observableArray([]),//获取的jdbs的xml文件中sql查询出的数组
date: ko.observable('2016'),
code:'',
fj_code:'',//父级标识码
};
加载数据的js,采用GET方式的AJAX请求,这里的判断需要结合之前点击事件的判断,如下,
function getGjbxtj(){
$.get(gjbxtjUrl,{date:gjbxtj.date(),code:gjbxtj.code},function (data) {
if(data){
if(!leftObj.pd){
leftObj.pd = true;
gjbxtj.val(data);//表格加载数据
}else{
leftObj.val(data);//导航栏加载数据
}
}
//如果是第一次请求。默认加载左侧列表
if(leftObj.pd_f){
gjbxtj.code = $('#left_list li').eq("0").attr("data-code");
leftObj.pd = false;
leftObj.pd_f=false;
getGjbxtj();
}
},'json');
}