最近项目要用到boostrap,可能会遇到很多问题,所以新开贴总结记录下~~
贴上以前的blog:
boostrap-table插件分页展示表格数据
Bootstrap-3-Typeahead插件
后续更新~
1.默认按钮提交
2017-12-19
问题描述:
在form表单里面有一个button,点击button跳转到一个新的页面,但是却提交了表单.很纳闷.
<button class="btn btn-default" id="pcMappingAddBtn">+ 新增实体与表映射</button>
后来加上type="button"就好了.可能是没有指定type,浏览器默认你是submit,所以去提交表单了.
考虑到兼容性,最好在定义button的时候加上type属性.
2.模态窗口的使用以及form提交集合
2017-12-20
模态窗口:
<form class="form-horizontal" role="form" style="position: relative" method="POST" action="orm/joinTable/saveAdd" onsubmit="return validateForm();">
<input type="text" value="${dataObjectId }" id ="dataObjectId" name="dataObjectId">
<div style="position: relative; left: 30px;">
<div style="position: relative; left: 70%;">
<button type="submit" class="btn btn-primary">保存</button>
<button onclick="window.history.back();" type="button" class="btn btn-default">取消</button>
</div>
<hr style="position: relative;">
</div>
<div class="form-group">
<label for="baseTable" class="col-sm-2 control-label">基础表名</label>
<div class="col-sm-10" style="width: 300px;">
<select id="baseTable" name="baseTable" class="form-control">
<c:if test="${!empty tableNameList }">
<c:forEach items="${tableNameList }" var="tbl">
<option value="${tbl }">${tbl }</option>
</c:forEach>
</c:if>
</select>
</div>
<label for="table" class="col-sm-2 control-label">关联表名</label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="table" name="table">
</div>
</div>
<ul class="nav nav-tabs">
<li role="presentation" class="active"><a href="javascript:void(0)">关联条件</a></li>
</ul>
<div class="tab-list">
<div class="tab-list-detail">
<div style="margin-top: 10px;">
<button class="btn btn-default"type="button" data-toggle="modal" data-target="#myModal">+ 新增关联条件</button>
</div>
<table class="table" style="margin-top: 10px">
<tr>
<td>基础表字段</td>
<td>关联表字段</td>
</tr>
<tbody id="joinConditionTbody">
</tbody>
<tbody id="joinConditionHideTbody" style="display:none;">
</tbody>
</table>
</div>
</div>
<!-- 模态框(Modal) -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
×
</button>
<h4 class="modal-title" id="myModalLabel">新增关联条件</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="baseTableColumn" class="col-sm-2 control-label">基础字段</label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="baseTableColumn" name="baseTableColumn">
</div>
</div>
<div class="form-group">
<label for="joinTableColumn" class="col-sm-2 control-label">关联字段</label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="joinTableColumn" name="joinTableColumn">
</div>
</div>
</div>
<div class="modal-footer">
<button id="closeBtn" type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button id="saveConditionBtn" type="button" class="btn btn-primary">保存</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
</form>
效果图:
点击保存按钮,暂时将数据保存红色框中,等到总提交时再发送后台。
不想用ajax去提交,想直接用form表单提交。解决办法如下:
js:
<script type="text/javascript">
var index = 0;
$(function(){
// 保存关联条件
$("#saveConditionBtn").click(function(){
// 展示列
var str = "<tr><td>"+$("#baseTableColumn").val()+"</td><td>"+$("#joinTableColumn").val()+"</td></tr>";
$("#joinConditionTbody").append(str);
// 隐藏列
var hideStr = "<input type='hidden' name='joinConditions["+index+"].baseTableColumn' value='"+$("#baseTableColumn").val()+"'>";
hideStr += "<input type='hidden' name='joinConditions["+index+"].joinTableColumn' value='"+$("#joinTableColumn").val()+"'>";
$("#joinConditionHideTbody").append(hideStr);
$("#myModal input").val("");
$("#closeBtn").click();
index++;
});
})
</script>
对应实体类字段:
public class JoinTable {
private String table;
private List<JoinCondition> joinConditions;
......
}
3.递归取出数据用插件collapse折叠展示
xml:
<MainTable>t_stu</MainTable>
<JoinTables>
<JoinTable>
<Table>t_class</Table>
<JoinConditions>
<JoinCondition>
<BaseTableColumn>classid</BaseTableColumn>
<JoinTableColumn>classid</JoinTableColumn>
</JoinCondition>
<JoinCondition>
<BaseTableColumn>hhh</BaseTableColumn>
<JoinTableColumn>ttt</JoinTableColumn>
</JoinCondition>
</JoinConditions>
<JoinTables>
<JoinTable>
<Table>t_teacher</Table>
<JoinConditions>
<JoinCondition>
<BaseTableColumn>pid</BaseTableColumn>
<JoinTableColumn>pid</JoinTableColumn>
</JoinCondition>
<JoinCondition>
<BaseTableColumn>11</BaseTableColumn>
<JoinTableColumn>22</JoinTableColumn>
</JoinCondition>
</JoinConditions>
<JoinTables>
<JoinTable>
<Table>yyyyy</Table>
<JoinConditions>
<JoinCondition>
<BaseTableColumn>rr</BaseTableColumn>
<JoinTableColumn>tt</JoinTableColumn>
</JoinCondition>
<JoinCondition>
<BaseTableColumn>77</BaseTableColumn>
<JoinTableColumn>uuu</JoinTableColumn>
</JoinCondition>
</JoinConditions>
</JoinTable>
</JoinTables>
</JoinTable>
</JoinTables>
</JoinTable>
<JoinTable>
<Table>t_school</Table>
<JoinConditions>
<JoinCondition>
<BaseTableColumn>schid</BaseTableColumn>
<JoinTableColumn>schid</JoinTableColumn>
</JoinCondition>
</JoinConditions>
</JoinTable>
</JoinTables>
在xml中数据存储方式是递归的,但是页面上好像用递归方式去展示数据怎么做?所以就采用了平级展示,比如表A和表B,表B和表C,表A和表D这样的形式。首先取出xml中的信息装载到实体DataObjectRelationMapping中,在展示详情的时候再去处理JoinTables这部分。
后台递归处理:
List<RecursionJoinTable> tbls = new ArrayList<>();
getJoinTableList(tbls, mapping.getJoinTables(), mapping.getMainTable());
/**
* 递归取出关联表和条件
*
* @param tbls
* @param joinTables
* @param baseTable
*/
private void getJoinTableList(List<RecursionJoinTable> tbls, List<JoinTable> joinTables, String baseTable) {
if (joinTables != null && joinTables.size() > 0) {
for (JoinTable joinTable : joinTables) {
RecursionJoinTable tbl = new RecursionJoinTable();
tbl.setBaseTable(baseTable);
tbl.setJoinTable(joinTable.getTable());
tbl.setJoinConditions(joinTable.getJoinConditions());
tbls.add(tbl);
if (joinTable.getJoinTables() != null && joinTable.getJoinTables().size() > 0) {
getJoinTableList(tbls, joinTable.getJoinTables(), joinTable.getTable());
}
}
}
}
自定义实体RecursionJoinTable:
public class RecursionJoinTable {
private String baseTable;
private String joinTable;
private List<JoinCondition> joinConditions;
}
页面展示:
<div class="panel-group" id="accordion" style="margin-top: 10px">
<c:forEach var="tbl" items="${joinTableList}" varStatus="vs">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#collapse${vs.count }">
${tbl.baseTable} && ${tbl.joinTable}
</a>
</h4>
</div>
<div id="collapse${vs.count }" class="panel-collapse collapse in">
<div class="panel-body">
<c:forEach var="con" items="${tbl.joinConditions}">
${tbl.baseTable}.${con.baseTableColumn}
= ${tbl.joinTable}.${con.joinTableColumn}
<br/>
</c:forEach>
</div>
</div>
</div>
</c:forEach>
</div>
最终效果图:
让窗口都折叠起来的js:
$('.collapse').collapse("hide");
4.过滤器和监听器
登录过滤器:
package com.sitech.ddoe.base.login.filter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.filter.OncePerRequestFilter;
public class LoginFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 不过滤的URL
List<String> notFilterList = new ArrayList<>(Arrays.asList("/login/", "/static/"));
// 请求路径
String path = request.getRequestURI();
boolean flag = false;
for (String notFilter : notFilterList) {
if (path.contains(notFilter)) {
flag = true;
break;
}
}
if (flag) {
filterChain.doFilter(request, response);
return;
}
HttpSession session = request.getSession(false);
if (session != null) {
String username = (String) session.getAttribute("username");
if (username != null && !"".equals(username)) {
filterChain.doFilter(request, response);
} else {
response.sendRedirect(request.getContextPath() + "/login/login");
}
} else {
response.sendRedirect(request.getContextPath() + "/login/login");
}
}
}
监听到项目启动将不经常变化的内容缓存到内存中:
package com.sitech.ddoe.listener;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import com.sitech.ddoe.common.pt.PropertyTypeManager;
public class InitComboListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
// 属性类型集合
List<String> propTypeList = new ArrayList<String>();
propTypeList.add(PropertyTypeManager.OM_TYPE_BOOLEAN);
propTypeList.add(PropertyTypeManager.OM_TYPE_DATE);
propTypeList.add(PropertyTypeManager.OM_TYPE_DOUBLE);
propTypeList.add(PropertyTypeManager.OM_TYPE_FLOAT);
propTypeList.add(PropertyTypeManager.OM_TYPE_INTEGER);
propTypeList.add(PropertyTypeManager.OM_TYPE_LONG);
propTypeList.add(PropertyTypeManager.OM_TYPE_STRING);
ServletContext servletContext = sce.getServletContext();
servletContext.setAttribute("propTypeList", propTypeList);
}
}
注意:监听器和过滤器需要在web.xml注册,才可以生效.