spring+springmvc+hibernate整合
参考另一页的相关示例。
https://www.jianshu.com/writer#/notebooks/50759535/notes/91053055
建一个Student模块(专门测试分页与不分页查询再+EasyUI),再把各层相应类代码写完整:
以后写权限控制时,要加User.java类。
model层
Student查询分页显示
1.Student.java 和User.java
public class Student {
private int id;
private String stuname;
private String password;
private Integer state;
private Date regDate;
private double height;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
......................
}
/*public class User {
private int id;
private String username;
private String password;
private Integer state; // 0:禁用,1:正常
@JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date regDate;
private Set roles = new HashSet<>();
public Set getRoles() {
return roles;
}
public void setRoles(Set roles) {
this.roles = roles;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
public Date getRegDate() {
return regDate;
}
public void setRegDate(Date regDate) {
this.regDate = regDate;
}
}*/
2.分页显示对象Pager.java
public class Pager {
/**
* 分页的大小,每页显示数据的条数
*/
private int size;
/**
* 每页的第一条数据的,条数索引
*/
private int offset;
/**
* 查询出来的总的数据条数,rows--easyui分页插件里变量名称一致
*/
private long total;
/**
* 每张每页是具体数据,rows--easyui分页插件里变量名称一致
*/
private List rows;
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
public long getTotal() {
return total;
}
public void setTotal(long total) {
this.total = total;
}
public List getRows() {
return rows;
}
public void setRows(List rows) {
this.rows = rows;
}
@Override
public String toString() {
return "Pager [size=" + size + ", offset=" + offset + ", total=" + total + ", rows=" + rows + "]";
}
}
- SystemContext.java 本地线程变量里的数据,每个线程中创建副本,在多条线程中,给这个变量赋值,
该类专门为分页查询使用。
/**
* ThreadLocal:数据共享,本地线程变量里的数据,每个线程中创建副本,在多条线程中,给这个变量赋值,
* 每条线程使用不会冲突 进行分页信息通信
* 排序信息通信
*
* @author Administrator
*
*/
public class SystemContext {
// 分页大小,每页显示的数据条数
private static ThreadLocal pageSize = new ThreadLocal<>();
// 每页的起始的条数索引
private static ThreadLocal pageOffset = new ThreadLocal<>();
// 排序的字段
private static ThreadLocal sort = new ThreadLocal<>();
// 排序方式
private static ThreadLocal order = new ThreadLocal<>();
public static Integer getPageSize() {
return pageSize.get();
}
public static void setPageSize(Integer _pageSize) {
pageSize.set(_pageSize);
}
public static Integer getPageOffset() {
return pageOffset.get();
}
public static void setPageOffset(Integer _pageOffset) {
pageOffset.set(_pageOffset);
}
public static String getSort() {
return sort.get();
}
public static void setSort(String _sort) {
sort.set(_sort);
}
public static String getOrder() {
return order.get();
}
public static void setOrder(String _order) {
order.set(_order);
}
public static void removePageSize() {
pageSize.remove();
}
public static void removePageOffset() {
pageOffset.remove();
}
public static void removeSort() {
sort.remove();
}
public static void removeOrder() {
order.remove();
}
}
Dao层
BaseDao与接口实现类BaseDaoImpl
public interface BaseDao {
/**
* 添加
*
* @param t
* @return
*/
public T add(T t);
/**
* 删除
*
* @param id
*/
public void delete(int id);
/**
* 修改
*
* @param t
*/
public void update(T t);
/**
* 查询
*
* @param id
* @return
*/
public T load(int id);
}
......................................................................................................................................
public class BaseDaoImpl implements BaseDao {
@Autowired
private SessionFactory sessionFactory; //spring.xml配置了
private Class> clazz;
public Class> getClazz() {
/*
Type type= this.getClass().getGenericSuperclass();
ParameterizedType pt=(ParameterizedType) type;
Type[] types = pt.getActualTypeArguments();
Class> clz = (Class>) types[0];
return clz;
*/
if (clazz == null) {
clazz = ((Class>) ((((ParameterizedType) (this.getClass().getGenericSuperclass()))
.getActualTypeArguments())[0]));
}
return clazz;
}
/**
* 获取数据连接回话的方法
*/
public Session getSession() {
return sessionFactory.getCurrentSession();
}
@Override
public T add(T t) {
getSession().save(t);
return t;
}
@Override
public void delete(int id) {
getSession().delete(load(id));
}
@Override
public void update(T t) {
getSession().update(t);
}
@SuppressWarnings("unchecked")
@Override
public T load(int id) {
return (T) getSession().load(getClazz(), id);
}
/**
* 用hql语句查询多条记录,没有分页,lsit返回,objs,alias两种sql占位符的处理预设,因为spring mvc有两种占位符方法
* @param hql
* @param objs 替换hql语句中?占位符的实参
* @param alias 替换hql语句中:name占位符的实参
* @return
*/
@SuppressWarnings("unchecked")
public List list(String hql, Object[] objs, Map alias) {//Map对象返回具名参数值如:name
hql = initSort(hql);//初始化排序规则
Query query = getSession().createQuery(hql);
setParameter(query,objs);//将hql里?占位符替换
setAliasParameter(query,alias);
return query.list();
}
/**
* 替换hql语句中:name占位符的实参
* @param query
* @param alias
*/
@SuppressWarnings("rawtypes")
private void setAliasParameter(Query query, Map alias) {
if(alias != null) {
Set keys = alias.keySet();
for(String key:keys) {
Object val = alias.get(key);
if(val instanceof Collection) {
query.setParameterList(key, (Collection)val);
}else {
query.setParameter(key, val);
}
}
}
}
/**
* 将hql里?占位符替换
* @param query
* @param objs
*/
private void setParameter(Query query,Object[] objs) {
if(objs != null && objs.length > 0) {
int index = 0;
for(Object obj:objs) {
query.setParameter(index++, obj);
}
}
}
/**
* 给hql语句加排序规则
* @param hql
* @return
*/
private String initSort(String hql) { //初始化排序规则
String sort = SystemContext.getSort(); // 数据我们可以在Controller放
String order = SystemContext.getOrder();
if (sort != null && !"".equals(sort.trim())) {
hql += " order by " + sort;
if (!"desc".equals(order)) {
hql += " asc";
} else {
hql += " desc";
}
}
return hql;
}
/**
* 查询多条数据,支持分页
* @param hql
* @param objs
* @param alias
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public Pager find(String hql, Object[] objs, Map alias){
hql = initSort(hql);//初始化排序规则
Query query = getSession().createQuery(hql);
setParameter(query,objs);//将hql里?占位符替换
setAliasParameter(query,alias);
Pager pager = new Pager<>();
setPager(query,pager);
List datas = query.list();
pager.setRows(datas);
//还需要一个查询的中条数 select count(*) from users where id>10
String countHql = getCountHql(hql);
Query countQuery = getSession().createQuery(countHql);
setParameter(countQuery,objs);//将hql里?占位符替换
setAliasParameter(countQuery,alias);
long total = (long) countQuery.uniqueResult();
pager.setTotal(total);
return pager;
}
private String getCountHql(String hql) {
String hhql = hql.substring(hql.indexOf("from")); // 拿到hql语句的form开始后半部分:from users where id>10
String countHql = "select count(*) " + hhql;
//hql语句,fetch
countHql = countHql.replace("fetch", "");
return countHql;
}
private void setPager(Query query, Pager pager) {
Integer pageSize = SystemContext.getPageSize();
Integer pageOffset = SystemContext.getPageOffset();
if(pageOffset == null || pageOffset < 0) {
pageOffset = 0; // pageOffset的默认值
}
if (pageSize == null || pageSize < 0) {
pageSize = 10; // 没有设置每页大小,默认每页显示10条
}
pager.setOffset(pageOffset);
pager.setSize(pageSize);
// data数据,也就是分页的数据 select id,username,pasword from users where id>10; 一张页面上显示的数据
query.setFirstResult(pageOffset).setMaxResults(pageSize);
}
//使用sql语句查询的方法,list,pager
/**
* 针对一些特殊的查询,返回不受泛型的制约,返回object
* @param hql
* @param objs
* @param alias
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object queryByHql(String hql, Object[] objs, Map alias) {
Query query = getSession().createQuery(hql);
setParameter(query,objs);//将hql里?占位符替换
setAliasParameter(query,alias);
return query.uniqueResult();
}
/**
* 应对某些特殊情况要用hql语句,来做更新
* @param hql
* @param objs
* @param alias
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public void updateByHql(String hql, Object[] objs, Map alias) {
Query query = getSession().createQuery(hql);
setParameter(query,objs);//将hql里?占位符替换
setAliasParameter(query,alias);
query.executeUpdate();
}
}
StudentDao.java接口 StudentDaoImpl.java接口实现类
import java.util.List;
import cn.ybzy.sshweb.model.Pager;
import cn.ybzy.sshweb.model.Student;
//接口继承了,很方便不用重写共同的方法
public interface StudentDao extends BaseDao{
/**
* 获取所有学生信息,不支持分页
*/
public List getAllStus();
/**
* 获取所有学生信息,支持分页
* @return
*/
public Pager getAllPagerStus();
}
---------------------------------------------------------------------------------------------------------------
import java.util.List;
import org.springframework.stereotype.Repository;
import cn.ybzy.sshweb.model.Pager;
import cn.ybzy.sshweb.model.Student;
@Repository("stuDao")
public class StudentDaoImpl extends BaseDaoImpl implements StudentDao{
//下面写的方法都是本类个性化的方法
@Override
public List getAllStus() {
String hql="from Student";
return super.list(hql, null, null);
}
//分页查询
@Override
public Pager getAllPagerStus() {
String hql="from Student";
return super.find(hql, null, null);
}
}
service层
BaseService.java接口 BaseServiceImpl.java接口实现类
package cn.ybzy.sshweb.service;
public interface BaseService {
/**
* 添加
* @param t
* @return
*/
public T add(T t);
/**
* 删除
* @param id
*/
public void delete(int id);
/**
* 修改
* @param t
*/
public void update(T t);
/**
* 查询
* @param id
* @return
*/
public T load(int id);
}
-----------------------------------------------------------------------------------------------------------------
import cn.ybzy.sshweb.dao.BaseDao;
public class BaseServiceIpml implements BaseService {
@Autowired
protected BaseDao baseDao;
@Override
public T add(T t) {
return baseDao.add(t);
}
@Override
public void delete(int id) {
baseDao.delete(id);
}
@Override
public void update(T t) {
baseDao.update(t);
}
@Override
public T load(int id) {
return baseDao.load(id);
}
}
StudentService.java接口 StudentServiceImpl.java接口实现类
package cn.ybzy.sshweb.service;
import java.util.List;
import cn.ybzy.sshweb.model.Pager;
import cn.ybzy.sshweb.model.Student;
public interface StudentService extends BaseService {
/**
* 获取所有学生信息,不支持分页
* @return
*/
public List getAllStus();
/**
* 获取所有学生信息,支持分页
* @return
*/
public Pager getAllPagerStus();
}
-----------------------------------------------------------------------------------------------------------------
@Service("stuService")
public class StudentServiceImpl extends BaseServiceIpml implements StudentService {
@Autowired
private StudentDao stuDao;
@Override
public List getAllStus() {
return stuDao.getAllStus();
}
//分页查询
@Override
public Pager getAllPagerStus() {
return stuDao.getAllPagerStus();
}
}
---------------------------------------------------------------------------------------------------------------
不分页查询与分页查询测试:StuController.java
@Controller
public class StuController {
@Autowired
private StudentService stuService;
@RequestMapping(value= {"","/","/index"})
public String index() {
return "index";
}
//不分页显示的所有学生信息
@RequestMapping(value="/getAllStudents",method=RequestMethod.GET)
public String getAllStudents(Model model) {
List stus = stuService.getAllStus();
model.addAttribute("stus",stus);
return "index";
}
//带分页显示所有学生信息
@RequestMapping(value="/getAllPagerStudents",method=RequestMethod.GET)
public String getAllPagerStudents(Model model) {
SystemContext.setPageSize(2); //每一页两条记录
SystemContext.setPageOffset(0); //从第一条记录开始分
Pager pager = stuService.getAllPagerStus();
SystemContext.removePageOffset();
SystemContext.removePageSize();
model.addAttribute("pager",pager);
return "index";
}
}
WEB-INF/jsp/index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
所有学生stus不带分页:http://localhost:8080/sshwebtest/getAllStudents
${stus}
所有学生page带分页:http://localhost:8080/sshwebtest/getAllPagerStudents
${pager}
测试结果:
所有学生stus不带分页:
Pager [size=2, offset=0, total=11, rows=[
Student [id=1, stuname=xiong, password=xiong, state=1, regDate=2021-08-20 01:44:03.0, height=1.7],
Student [id=2, stuname=xiong1, password=xiong1, state=1, regDate=2021-08-20 01:50:01.0, height=1.65]]]
EasyUI前端应用基础。
- 下载地址:
EasyUI 官方下载地址: http://www.jeasyui.com/download/index.php ,目前最新的版本是: jQuery EasyUI 1.9.x,可以http://www.jeasyui.com/download/list.php下载其它版本如本项目的1.5x版本。
下载完成之后,得到压缩包,解压后,得到一个【 jquery-easyui-1.5.5.4 】文件夹,里面有如下图所示的文件:
image.png
image.png
image.png -
配置javaweb项目中,不是所有文件都放到项目中,具体见下图:
local本地化文件,我只选'中文格式'的js文件。demo项目都不引进来。
插件(easyui-dialog可以把一个元素窗口化)我只选:jquery.easyui.min.js----它是各插件的综合体,我不会把整个plugins导到项目中。
image.png - https://www.jeasyui.net/plugins/是一个中文网站,我们可以参考插件功能介绍。
举例:
例1:把div窗口化,可以移动,关闭功能。网页为index.jsp
确实太简单的情况或一定有必要的时候才会把样式写在标签中。
Hello world
例2:编程方式写上面例1:的效果
1.分别建index.js,index.css两个文件(src/main/webapp/resources/js,src/main/webapp/resources/css)内容如下:
index.js
$(function(){
$("#dd1").dialog({
title:"Easyui-Dialog",//主题
closed:false,//非关闭状态,默认也是false
maximizable:true, //可最大化
minimizable:true //可最小化
});
});
index.css
@charset "UTF-8";
#dd1{
width:500px;
height:400px;
}
index.jsp
Hello world
例3:拖拽实现---不是按住连框的移动,是任意位置都可移动.
实现原理与上例1,2一样,只是class="esayui-tragger",这里把所有代码写在一起。
--------------------------------------------index.jsp-------------------------------------------------------
--------------------------------------------------index.js--------------------------------------------------
//纯拖动
$("#dragger").draggable();
//拖动时,扡的是代理即复制元素,松开鼠标后,不代理。
/*$("#dragger").draggable({ //拖动代理,设置为 'clone' 时,克隆元素将被用作代理,即复制一个。如果指定一个函数,它必须返回一个 jQuery 对象。
proxy:"clone"
})*/
//拖动时变成别的元素,但实际仍是原元素,只是起到一个美观作用不建议这样干。
/*$("#dragger").draggable({
proxy:function(source){
var div = $("");
div.appendTo("body");
return div;
}
})*/
-----------------------------------------------index.css样式----------------------------------------------
#dragger{
border:1px solid #000;
width:500px;
height:400px;
}
例3x:在容器中移动,不会出容器
----------------------------------------------------------index.jsp--------------------------------------------
---------------------------------------------------------index.js-----------------------------------------------
$("#draggerin").draggable({
onDrag:function(e){ //拖动期间触发。返回 false 将不进行实际的拖动。
//通过e对象拿到拖动的html元素节点对象
var div = e.data; //{target: div#draggerin, startPosition: "absolute", startLeft: 519, startTop: 219, left: 150,...}
console.log(div); //通过控制台我们可以查到相关移动的数据,很有用。
if(div.left<0){
div.left = 0;
}
if(div.top<0){
div.top = 0;
}
if((div.left+$(div.target).innerWidth())>($(div.parent).innerWidth())){ //innerWidth自身的宽度,div.target等于e.data.target即产生事件的元素的自身
div.left = ($(div.parent).innerWidth())-$(div.target).innerWidth()-1;
}
if((div.top+$(div.target).innerHeight())>($(div.parent).innerHeight())){
div.top = ($(div.parent).innerHeight())-$(div.target).innerHeight()-1;
}
}
});
------------------------------------------------index.css------------------------------------------------
/*在容器中移动,不会出容器,容器要相对定位 */
#incontenttrag{
width:600px;
height:300px;
border:1px red solid;
margin:30px;
padding:0;
position:relative;
}
#draggerin{
background:blue;
width:80px;
height:80px;
/* position:absolute; */
}
例31:设置元素拖动可变大变小
$("#draggerin").resizable({ //设置元素可变大小,按住连框,拖动,可以改变大小,默认全部,特设:n往上扡动变大与变小,e东,。。。
handles:"n,e"
})
例4:从一个容器拖动子元素放置到另一个容器-draggable()与droppable()综合。
--------------------------------------------index.jsp-------------------------------------------------------
1
2
3
--------------------------------------------------index.js--------------------------------------------------
$(function(){
$(".drag").draggable({
proxy:"clone", //拖动代理,设置为 'clone' 时,克隆元素将被用作代理,即复制一个。如果指定一个函数,它必须返回一个 jQuery 对象。
revert:true //如果设置为 true,拖动结束后没放置到指定容器后元素将返回它的开始位置,若放置结束后会放到容器中,没有该选项则放置会出容器外面。
});
$("#content2").droppable({
accept:"#drag1,#drag3",
onDrop:function(e,source){ //e,source 当可拖动元素被放下时触发。source 参数指被拖动的 DOM 元素。
$(this).append(source);
},
onDragEnter:function(e,source){ //拖动到一个容器中即使没有松开鼠标放置(放置了更不用说)发生的事件
$(source).draggable("options").cursor = "pointer"; //鼠标指针形状 手形。
$(source).draggable("proxy").css("border","1px red solid");//
}
});
});
-----------------------------------------------index.css样式----------------------------------------------
#content{
width:200px;
height:300px;
border:1px red solid;
margin:30px;
padding:0;
float:left;
}
#content2{ /*容器2样式--被放置元素的容器*/
width:300px;
height:300px;
border:1px red solid;
margin:30px;
padding:0;
float:left;
}
.drag{ /*要移动放置的DOM元素样式*/
width:200px;
height:30px;
border:1px blue solid;
}
5搜索框,原理 input文本输入框+div子元素分类
----------------------------------------------------index.jsp----------------------------------------------------------------------
衣服
电脑
----------------------------------------------------index.js----------------------------------------------------------------------
//6.搜索框,用输入文本框来格式化做成。
$("#search").searchbox({
menu:"#cat", //cat是div元素,查看index.jsp就知道了cat下我在此定了两个分类clothes,computer即衣服和电脑
searcher:function(value,name){ //value存储输入框中接收输入的内容,name是分类信息的name
alert(value+" "+name);
}
});
----------------------------------------------------index.css----------------------------------------------------------------------
#search{
width:50%; /*该适配不会自动来的,要刷新一下页面才会显示适配50%*/
}
6.进度条。
首先把一个div化作进度条,再用一个超链接或按钮来设置和获取进度值,用js与jquery混合编程。
----------------------------------------------------index.jsp----------------------------------------------------------------------
进度条:
快进
----------------------------------------------------index.js----------------------------------------------------------------------
//7.进度条
$(function(){
$("#bar").progressbar({
value:2 //进度条2%
});
});
//7.进度条值获取与增加方法,由超链接按钮单击实现,onclick="add()",这里是js与jquery混合编程
function add(){
var value = $("#bar").progressbar("getValue");
console.log(value);
$("#bar").progressbar("setValue",value+3);
}
----------------------------------------------------index.css----------------------------------------------------------------------
#search{
width:50%; /*进度条适配会自动来的*/
}
7.Pagination 分页
----------------------------------------------------index.jsp----------------------------------------------------------------------
----------------------------------------------------index.js----------------------------------------------------------------------
$("#pagination").pagination({
total:222,
pageList:[11,22,33,44,55], //默认分页 10,20 ,30,这里自定义11,22....
layout:["list","first","links","last"], //定义分页工具显示的图案
buttons:[{ //自定义显示样式
iconCls:"icon-add", //+号图标
handler:function(){
alert("cexoi"); //选中某页发生的函数
}
}],
onSelectPage:function(pageNumber,pageSize){
$(this).pagination("loading"); //没有加载数据时,不会显示loading
alert(pageNumber+","+pageSize); //显示第n页,它有几条记录
$(this).pagination("loaded");
}
});
----------------------------------------------------index.css----------------------------------------------------------------------
}
只 $("#pagination").pagination();显示如下。
经过上面的代码处理后:
8.EasyUI Panel 面板
面板(panel)当做其他内容的容器使用。它是创建其他组件(比如:Layout 布局、Tabs标签页/选项卡、Accordion 折叠面板,等等)的基础组件。它也提供内置的可折叠、可关闭、可最大化、可最小化的行为以及其他自定义行为。面板(panel)可以简单地嵌入到网页的任何位置。
----------------------------------------------------index.jsp----------------------------------------------------------------------
这是在讲解panel面板
这是在讲解panel面板
这是在讲解panel面板
----------------------------------------------------index.js----------------------------------------------------------------------
$(function(){
$("#panel").panel({
width:500, //不加px等。
height:400,
title:"面板的测试",
//fit:true, //自动真充父容器,此处填充网页
//content:"熊少文2021年", //自动填充面板,即把下面的全去掉了,这里不需要。
collapsible:true, //收折起面板工具显示
minimizable:true, //最小化按钮,按了不见了
maximizable:true, //最大化铵钮
href:'/sshwebtest/panel', //远程加载覆盖面板内容,即
元素不见了(StuController.java--@RequestMapping(value="/panel"))
onLoad:function(){
alert("远程加载完毕");
},
tools:[ //一些工具
{
iconCls:"icon-add", //工具按钮--添加
handler:function(){
alert("点击了添加工具按钮");
}
},
{
iconCls:"icon-save", //工具按钮--保存
handler:function(){
alert("点击了保存按钮");
}
}
],
footer:"#footer" //设置底部样式
});
$("#open").click(function(){ //单击打开按钮,打开面析
$("#panel").panel("open");
});
$("#close").click(function(){ //单击打开按钮,打开面析
$("#panel").panel("close");
});
$("#open").click(function(){ //单击打开按钮,打开面析
$("#panel").panel("refresh","/sshwebtest/panel");
});
});
9.选项卡tabs(),依赖于面板,一个卡就是一个面板。
----------------------------------------------------index.jsp----------------------------------------------------------------------
tab1的内容
tab2的内容
tab3的内容
----------------------------------------------------index.js----------------------------------------------------------------------
//10.选项卡tabs(),每一个项,有一个面板即依赖panel。
$("#tt").draggable().tabs({
// tabPosition:"left", //让所有选项,向左下排
onSelect:function(title){ //选项被选中事件
$("#tt").tabs("getTab","tab2").panel({ //动态加载远程数据,首先容器要是选项卡,再选项上海面板化,标签中应用-见index.jsp中的tap2(已注释)
href:"/sshwebtest/panel"
});
},
tools:[{
iconCls:"icon-edit", //整个选项框 右上角铅笔图标
handler:function(){
alert("dddd")
}
},
{ //添加选项按按钮,这里实现添加铵钮功能
iconCls:"icon-add",
handler:function(){
$("#tt").tabs("add",{
title:"NewTAB",
content:"newnewnewnewtab",
closable:true, //可关闭选项卡,会有一个关闭按钮
selected:true, //一添加即选中
//href:"/sshwebtest/panel",
cls:"tabx", //新加的选项卡样式,即 jsp页面中定义的class="tab"
tools:[{
iconCls:"icon-mini-refresh", //选项卡里的小刷新按钮,
handler:function(){
alert("刷新有用");
var tap2 = $("#tt").tabs("getSelected");
tap2.panel("refresh","/sshwebtest/panel"); //选项卡的面板中刷新,会显示远程数据
}
}
]
});
}
},
{
iconCls:"icon-remove", //关闭选项卡铵钮,即选中那个卡,再点击‘-’关闭,会关闭那个卡。
handler:function(){
var tab=$("#tt").tabs("getSelected");
var index = $("#tt").tabs("getTabIndex",tab);
$("#tt").tabs("close",index);
}
}
]
});
//按钮标签添加选项卡之单击事件。
$("#add").click(function(){
var title = $("#tabname").val();
// alert(title);
if($("#tt").tabs("exists",title)){
$("#tt").tabs("select",title)
}else{
$("#tt").tabs("add",{
title:title,
content:'Tab Body',
cls:"tabx",
closable:true,
});
}
});
//按钮标签删除选项卡之单击事件。
$("#remove").click(function(){
var title = $("#tabname").val();
if($("#tt").tabs("exists",title)){
$("#tt").tabs("close",title)
}
});
----------------------------------------------------index.css----------------------------------------------------------------------
/* 选项卡tabs,最好把其它样式注释掉,不然会凌乱*/
#tt{
width:400px;
height:300px;
}
.tabx{
height:223px;
padding:20px;
}
10,Accordion 折叠面板(也叫手风琴)
折叠面板(accordion)允许您提供多个面板(panel),同时显示一个或多个面板(panel)。每个面板(panel)都有
展开和折叠的内建支持。点击面板(panel)头部可展开或折叠面板(panel)主体。面板(panel)内容可通过 ajax 指
定 'href' 属性来加载。用户可定义被选中的面板(panel)。如果没指定,则默认选中第一个面板(panel)。
- 用户管理
- 角色管理
- 权限管理
- 用户管理
- 角色管理
- 权限管理
- 用户管理
- 角色管理
- 权限管理
-------------------------------------------------------------index.js-----------------------------------------------
$("#aa").accordion({
width:400,
animate:false //收缩时不要动漫效果
});
11.Layout布局
实际开发中,布局都作后台用,且用body作容器
通过 ajax 加载内容。
布局(layout)是基于面板(panel)创建的。各区域面板提供从 URL 动态加载内容的内建支持。使用动态加载技术,用户可以让他们的布局页面更快地显示。
如:我要拿到第一个布局中的center的panel,并在它里边显示后端传来的数据:
$("#cc").layout("panel","center").panel("refresh","content.jsp");
12 menu菜单
菜单(Menu),是一个右键菜单。它是创建其他菜单组件(比如:menubutton、splitbutton)的基础组件。它也能用于导航和执行命令。
**** 创建菜单(Menu)
通过标记创建菜单(menu)应该添加 'easyui-menu' class 到
(menu item)通过
菜单(Menu)通常用于上下文菜单。它是创建其他菜单组件(比如:menubutton、splitbutton)的基础组件。它也能用于导航和执行命令。
----------------------------------------------------------index.jsp--------------------------------------------------------
-------------------------------------------------------------index.js-----------------------------------------------------------------
$(document).bind("contextmenu",function(e){
//禁用原始右键菜单
e.preventDefault();
//然后显示我们自定义的菜单
$("#mm").menu("show",{
left:e.pageX,
top:e.pageY
});
});
$("#mm").menu({
onClick:function(item){
if(item.name=="new"){
alert("new菜单的具体功能代码")
}
}
});
13 按钮
-
链接按钮(linkbutton)
用于创建一个超链接按钮。它是一个正常的 标记的表示。它可显示图标和文本,或者仅仅显示图标和文本中的一个。按钮宽度可动态收缩/扩展以适应其文本标签。
image.png
链接按钮
---------------------------------------------------------------index.js---------------------------------------------------------------------
$("#btn").linkbutton({
iconCls:'icon-search' //按钮左面有搜索图标
});
$("#btn").on("click",function(){ //绑定点击事件,bind以后会被on取代用于绑定事件
alert("点击链接按钮的相应的代码")
});
- 菜单按钮
Edit
Undo
Redo
Cut
Copy
Paste
Delete
Select All
----------------------------------------------------------index.js-------------------------------------------------------------------------
$("#mb").menubutton({
iconCls:"icon-search",
menu:"#mm"
});
$("#mm").menu({ //单击Undo菜单项的单击事件
onClick:function(item){
alert(item.name)
}
});
3.分隔按钮
14EasyUi表单
- EasyUI Form 表单和文本框,表单(form)提供多种方法来执行带有表单字段的动作,比如 ajax 提交、加载、清除,等等。当提交表单时,调用 'validate' 方法来检查表单是否有效。
例:StuController.java控制层提供远程服务产生json数据,index.jsp表单中获取远程数据json ,index.js用eval()方法获取表单提交成功后返回的数据即远程的。
------------------------------------------------------------------StuController.java-----------------------------------------------------
@ResponseBody
@RequestMapping(value="/panel")
public String panel() { //启动tomcat后,http://localhost:8080/sshwebtest 回车
//return "remote content"; //只返加一个字符串,14讲前用的测试数据,如 url:'/sshwebtest/panel'
return "{'name':'xiongshaowen'}"; //构造一个json数据
}
------------------------------------------------------------------index.jsp------------------------------------------------------------------
------------------------------------------------------------------index.js------------------------------------------------------------------
$("#ff").form({
url:"/sshwebtest/panel", //远程该问服务器,springmvc @RequestMapping(value="/panel")
onSubmit:function(){
//数据的前端的有效性验证
//在额外增加参数,提交到后台
//param.mmm="vvvv";
},
success:function(data){ //提交成功,返回用success接收
//son数据格式{“名”:“值“)
var objdata = eval('(' + data + ')'); //将string转成js的object,注意:+符号前后有空格
alert(objdata);
alert(data);
alert(objdata.name)
}
});
该弹出的对话框中是远程数据。
注:文本框, 一个表单中,最常用的就属文本框了 TextBox
1.灰色的提示文字: prompt属性实现:
2.有效性验证: validType 属性,下节具体讲
3.多行文件框: multiline:true 实现
4.可以给文本框加多个图标: icons : [{iconCls:'',handler:function(){}},
{},{}] 实现
5.easyui 的 textBox ,获取文本框里的值,注意:不能使用普通的 jq 的 val() 了,要用
textbox("getValue"), 赋值用 textbox("setValue","set 进去的值 ") 。
例:
---------------------------------------------------------------------index.jsp-------------------------------------------------
---------------------------------------------------------------------index.js-------------------------------------------------
$("#ff").form({
url:"/sshwebtest/panel", //远程该问服务器,springmvc @RequestMapping(value="/panel")
onSubmit:function(){
var name = $("#name").val(); //获取文本框中输入的数据
//$("#name").val("1111111"); //传统jquery方法设置文本框输入的值,没有效果。
var name1 = $("#name").textbox("getValue"); //获取文本框中输入的数据
$("#name").textbox("setValue","1111111111111"); //easyui设置输入框的值为 111111
alert(name);
alert(name1); //name1与name相同值
//数据的前端的有效性验证
//在额外增加参数,提交到后台
//param.mmm="vvvv";
},
success:function(data){ //提交成功,返回用success接收
//son数据格式{“名”:“值“)
var objdata = eval('(' + data + ')'); //将string转成js的object,注意:+符号前后有空格
alert(objdata);
alert(data);
alert(objdata.name)
}
});
- 验证框(validatebox)重点是validType验证规则讲解。
21.验证框(validatebox)是为了验证表单输入字段而设计的。如果用户输入无效的值,它将改变背景颜色,显示警告图标和提示消息。验证框(validatebox)可与表单(form)插件集成,防止提交无效的字段。
例:,验证框与它集成,保证输入框必须有数据,且符合邮箱规则。如下:
---------------------------------------------------------------------------------xxx.js------------------------------------------
$("#eema").validatebox({
required:true,
validType:"email"
});
22.验证规则与自定义验证规则。
验证规则是通过使用 required 和 validType 属性来定义的,这里是已经实施的规则:
email:匹配 email 正则表达式规则。
url:匹配 URL 正则表达式规则。
length[0,100]:允许从 x 到 y 个字符。
remote['http://.../action.do','paramName']:发送 ajax 请求来验证值,成功时返回 'true' 。
要自定义验证规则,重写 $.fn.validatebox.defaults.rules,来定义一个验证函数。
例:检查密码和重新输入密码是相同的,并且密码不少于6个字符。
required可以单独写上required。表示必填框。
index.js自定义验证规则。
$.extend($.fn.validatebox.defaults.rules,{
equals:{
validator:function(value,param){ //value是文本框中输入的值,param是数组,如匹配多个框param[0]即当前只有一个确认密码框,即本身
return value == $(param[0]).val();
},
message:'Field do not match.前后密码不一致!' //返回结果后的标签
},
minLength:{
},
, minLength:{ //这里只是测试写定义规则的方法,实际开发中标签中用validType:'length[4,6]'规则去验验证字符串的个数。
validator:function(value,param){
return value.length >= param[0]
},
message:'输入的字符串个数不足!'
}
});
15 组合(combo)和Combobox 组合框
- 组合(combo) 是在 html 页面上显示一个可编辑的文本框和下拉面板。它是用于创建其他复杂的组合组件(比如:组合框 combobox、组合树 combotree、组合网格 combogrid,等等)的基础组件。
例:两个div ,第一个作为组合,第二个作为下拉面板,面板中定义几个选项按钮,然后,把面板加到组合中,当我们选中一个项后,隐藏面板
请选择:
java
c#
python
php
jquery
---------------------------------------------------------------------------xxxx.js----------------------------------------
combo组合,首先定义了两个div 分别id=cc,id=mianban,而mianban中定义了几个radio选择器,作为下拉面板
$("#cc").combo({
panelHeight:100 //组合属性的应用
});
$("#mianban").appendTo($("#cc").combo("panel"));
$("#mianban input").click(function(){
var value=$(this).val();
var text = $(this).next("span").text();
//alert(value+":"+text); //测试有无数据
$("#cc").combo("setValue",value).combo("setText",text).combo("hidePanel"); //选中一个项后,隐藏下拉面板
});
- combobox 组合框(常用到级联方式如:江西省--南昌市--青山湖区)
组合框(combobox)依赖组合combo的, 显示一个可编辑的文本框和下拉列表,用户可以从下拉列表中选择一个或多个值。用户可以直接输入文本到列表的顶部,或者从列表中选择一个或多个现成的值。
21.从带有预定义结构的
----------------------------------------------------------------------------jsp-------------------------------------------------------
----------------------------------------------------------------------------js---------------------------------------------------------
//21.从带有预定义结构的
22. 从 标记创建组合框(combobox):
----------------------------------------------------------------------------jsp-------------------------------------------------------
--------------------------------------------------StuCtroller.java--------------------------------------------------------------
@ResponseBody
@RequestMapping(value="/comboboxval")
public String comboboxval() throws JsonProcessingException {
ComboBox[] cbarray = {new ComboBox(1,"jianxisheng"),new ComboBox(2,"hunansheng"),new ComboBox(3,"fujiansheng")};
ObjectMapper obmapper = new ObjectMapper();
String jsonStr = obmapper.writeValueAsString(cbarray);
System.out.println("====="+jsonStr); //结果为json格式数据,{}表示里面是对象[{"id":1,"text":"aa"},{"id":2,"text":"bb"},{"id":3,"text":"cc"}]
return jsonStr;
}
----------------------------------------------------------------------------js--------------------------------------------------------
$("#ccipt").combobox({
url:"/sshwebtest/comboboxval", //获取返回的json格式数据[{},{},{}..]
valueField:"id",
textField:"text",
});
下图中,显示的三个数据是后台返回的数据--由js代码获取。http://localhost:8080/sshwebtest/comboboxval回车可看到控制台显示的后台数据。
23.级联组合框,如:江西省--南昌市---青山湖区
-------------------------------------------------------------------------index.jsp页面-------------------------------------------------
----------------------------------------------------------------------模型层Combobox.java-------------------------------------------
public class ComboBox {
private int id;
private String text;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
@Override
public String toString() {
return "ComboBox [id=" + id + ", text=" + text + "]";
}
public ComboBox() {
super();
}
public ComboBox(int id, String text) {
super();
this.id = id;
this.text = text;
}
}
--------------------------------------------------------------------------控制层StuCtroller.java----------------------------------------
@ResponseBody
@RequestMapping(value="/comboboxval")
public String comboboxval() throws JsonProcessingException {
ComboBox[] cbarray = {new ComboBox(1,"jianxisheng"),new ComboBox(2,"hunansheng"),new ComboBox(3,"fujiansheng")};
ObjectMapper obmapper = new ObjectMapper();
String jsonStr = obmapper.writeValueAsString(cbarray);
System.out.println("====="+jsonStr); //结果为json格式数据,{}表示里面是对象[{"id":1,"text":"aa"},{"id":2,"text":"bb"},{"id":3,"text":"cc"}]
return jsonStr;
}
@ResponseBody
@RequestMapping(value="/comboboxval1")
public String comboboxval1(@RequestParam int id) throws JsonProcessingException {
ComboBox[] cbarray = {new ComboBox(1,"nanchangshi"),new ComboBox(2,"jiujiangshi"),new ComboBox(3,"jianshi")};
ObjectMapper obmapper = new ObjectMapper();
String jsonStr = obmapper.writeValueAsString(cbarray);
System.out.println("====="+jsonStr); //结果为json格式数据,{}表示里面是对象[{"id":1,"text":"aa"},{"id":2,"text":"bb"},{"id":3,"text":"cc"}]
return jsonStr;
}
----------------------------------------------------------------------------js-------------------------------------------------------------
$("#ccipt").combobox({
url:"/sshwebtest/comboboxval", //获取返回的json格式数据[{},{},{}..]
valueField:"id",
textField:"text",
onSelect:function(rs){ //rs事件返回来的参数rs,当然了rs名可自定义,但结果不变。
var url="/sshwebtest/comboboxval1?id="+rs.id
$("#cc2").combobox("reload",url)
}
});
16.数字框和文件上传
- 数字框(numberbox)用于让用户仅能输入数字的值。它可以把输入元素转换为不同类型的输入(比如:数字 numeric、百分比 percentage、货币 currency,等等)。更多的输入类型依赖 'formatter' 和 'parser' 函数来定义。
image.png
用法
$('#nn').numberbox({
min:0,
precision:2
});
名称 类型 描述 默认值
disabled boolean 定义是否禁用该字段。 false
value number 框中默认显示的值。
min number 允许的最小值。 null
max number 允许的最大值。 null
precision number 显示在小数点后面的最大精度。 0
decimalSeparator string 分隔数字的整数部分和小数部分的分隔字符。 .
groupSeparator string 分隔整数组合的字符。如每隔 3 位用,分割
prefix string 前缀字符串。
suffix string 后缀字符串。
filter function(e) 定义如何过滤被按下的键,返回 true 则接受输入
字符。该属性自版本 1.3.3 起可用。
formatter function(value) 用来格式数字框( numberbox )值的函数。返回显示在框中的字符串值。
parser function(s) 用来解析字符串的函数。返回数字框( numberb
例:
------------------------------------------------------------------------------------xxx.js-------------------
$("#nn").numberbox({
min:0, //最小值
precision:2, //小数点后的精度为2
groupSeparator:",", //分隔符,每三个数字用一个分隔符
prefix:"$" //前缀,如$111,222.00
});
- 文件上传用的文件框filebox
和本质一样,只是统一了样式!具体实现文件上传的后端,springmvc课程里有非常详细的讲解,这里就不啰嗦了!
17.日期时间插件。
- 日历(calendar)
显示允许用户选择日期的一个月份日历,并允许移动到上一月和下一页。默认情况下,每星期的第一天设置为星期日。这可以通过设置 'firstDay' 属性的值来改变。
image.png
用法
1.从标记创建日历(calendar)。
2.使用 javascript 创建日历(calendar)
---------------------------------------------------xxx.js---------------------------------------------------
$("#dd").calendar({
onSelect: function(date){
alert(date.getFullYear()+":"+(date.getMonth()+1)+":"+date.getDate());
}
})
3.datebox()创建日期,且格式化,解析选择的日期并显示在框中。
------------------------------------------------------xxx.js------------------------------------------------------
$('#dd').datebox({
required:true,
formatter:function(date){ //框中显示格式化的日期,但只这个函数只显示前日期,当改变时也是这样的显示
return date.getFullYear()+"年"+(date.getMonth()+1)+"月"+date.getDate()+"日"
},
parser:function(str){ //解析日期显示在框中
if(str == ""|| str ==null)
return new Date(); //str不是空,一定是xxx年xxx月xxx日
var y = parseInt(str.substring(0,str.indexOf("年")),10);
var m = parseInt(str.substring((str.indexOf("年")+1),str.indexOf("月")),10);
var d = parseInt(str.substring((str.indexOf("月")+1),str.indexOf("日")),10);
if(!isNaN(y) && !isNaN(m) && !isNaN(d)){
return new Date(y,m-1,d)
}else{
return new Date();
}
}
});
$('#dd').datebox().datebox("calendar").calendar({ //当前日的后面时间选择不了
validator:function(date){
var now = new Date();
return date < now;
}
});
18.窗口与对话框
窗口(window)
是一个浮动的、可拖拽的面板,可以当做应用程序窗口使用。默认情况下,窗口可移动、可调整尺寸、可关闭。它的内容既可以通过静态 html 定义,也可以通过 ajax 动态加载。该属性扩展自面板(panel),下面是为窗口(window)重写和添加的属性。
窗口(window)动作
打开和关闭窗口(window)。
('#win').window('close'); // close a window
通过 ajax 加载窗口内容。
$('#win').window('refresh', 'get_content.php');
一。创建窗口
1、从标记创建窗口(window)modal:true表示窗口以外的元素失效。
Window Content
2、使用 javascript(jquery) 创建窗口(window)
-------------------------------------------------------------------xxx.js----------------------------------------------------------------
$("#win").window({
width:500,
height:400,
modal:true //true表示窗口以外的元素失效
});
3、通过复合布局创建窗口(window)。
The Content.
窗口的一些属性:
对话框(dialog)
是一个特殊类型的窗口,它在顶部有一个工具栏,在底部有一个按钮栏。默认情况下,对话框(dialog)只有一个显示在头部右侧的关闭工具。用户可以配置对话框行为来显示其他工具(比如:可折叠collapsible、可最小化 minimizable、可最大化 maximizable,等等)。
1.通过标记从已有的 DOM 节点创建对话框(dialog)。下面的实例演示了一个带有可调整尺寸特性的模态对话框。
Dialog Content.
2.使用 javascript 创建对话框(dialog)。现在让我们创建一个模态对话框,然后调用 'refresh' 方法来通过 ajax 加载它的内容。
Dialog Content.
-------------------------------------------------------------------------------------XXX.js--------------------------------------------------
$('#dd').dialog({
width:500,
height:400,
modal:true,
toolbar:[{
text:"Edit",
iconCls:"icon-edit",
handler:function(){
alert("工具栏上的编辑按钮被点击了一下")
}
}],
buttons:[{
text:"OK",
iconCls:"icon-ok",
handler:function(){
alert("工具栏上的OK按钮被点击了一下")
}
}]
})
19 树的基本用法
树(tree)
在网页中以树形结构显示分层数据。它向用户提供展开、折叠、拖拽、编辑和异步加载功能。
树(tree)定义在 元素中
。
树的属性
每个节点可以包括下列属性:
id:节点的 id,它对于加载远程数据很重要。
text:要显示的节点文本。
state:节点状态,'open' 或 'closed',默认是 'open'。
checked:指示节点是否被选中。
attributes:给一个节点添加的自定义属性。
children:定义了一些子节点的节点数组。
iconCls:用来显示图标的 css class。
target:目标的 DOM 对象。这个是回调时用的!
用的到的属性
名称 类型 描述 默认值
animate boolean 定义当节点展开折叠时是否显示动画效果。 false
checkbox boolean 定义是否在每个节点前边显示复选框。 false
lines boolean 定义是否显示树线条。 false
dnd boolean 定义是否启用拖放。 false
data array 要加载的节点数据。 null
formatter function(node) 定义如何呈现节点文本。
loadFilter function(data,parent) 返回要显示的过滤数据。返回数据时以标准树格式返回的。该函数有下列参数:
data :要加载的原始数据。
parent : DOM 对象,表示父节点。
url string 获取远程数据的 URL. null
method string 检索数据的 http 方法( method )。 post
事件
事件名 参数 描述
onClick node 当用户点击一个节点时触发。代码实例:
$('#tt').tree({
onClick: function(node){
alert(node.text);
}
});
onAfterEdit node 编辑节点后触发。
方法
名称 参数 描述
beginEdit target 开始编辑节点。
getSelected none 获取选中的节点并返回它,如果没有选中节点,则返回 null 。
例:设计七个树枝,其中树枝4有三个子枝。默认勾选node3枝,单击修改枝名,修改枝名后发生onAfterEdit事件,loadFilter方法过滤出node4,并在树枝4上加保存图标。
---------------------------------------------------------------------xxx.js-----------------------------------------
$("#tt").tree({
data:[
{id:1,text:"node1"},
{id:2,text:"node2"},
{id:3,checked:true,text:"node3"}, //checked依赖于checkbox
{id:4,text:"node4", state:"open",children:[ //state默认也为打开,node4的子节点。
{id:5,text:"node4-1"},
{id:6,text:"node4-2"},
{id:7,text:"node4-3"}
]}
], //树节点数组
//dnd:true, //节点可拖出去
checkbox:true,
lines:true,
formatter:function(node){ //对节点进行格式化
return "<-"+node.text+"->";
},
loadFilter:function(data){ //节点进行过滤,data参数里包含节点数组(此处功能:为菜单4加上一个保存图标。
for(var i=0;i
例:实现右键点击节点,弹出菜单-由div标记组成(添加子节点,添节兄弟节点,删除节点),再实现相关功能,实现选中状态的获取,全选,半选,没选 。
--------------------------------------------------------------------index.jsp-------------------------------------
------------------------------------------------------------------------index.js---------------------------------
$(function(){
$("#tt").tree({
data:[
{id:1,text:"node1"},
{id:2,text:"node2"},
{id:3,checked:true,text:"node3"}, //checked依赖于checkbox
{id:4,text:"node4", state:"open",children:[ //state默认也为打开,node4的子节点。
{id:5,text:"node4-1"},
{id:6,text:"node4-2"},
{id:7,text:"node4-3"}
]}
], //树节点数组
//dnd:true, //节点可拖出去
checkbox:true,
lines:true,
cascadeCheck:true, //true是默认。false时不级联检查,如节点4,有三个子节点,当勾选中父节点,子节点不勾选,相反也是一样。
onlyLeafCheck:true, //有子节点的父节点不显示复选框,即没有勾选之处。
formatter:function(node){ //对节点进行格式化
return "<-"+node.text+"->";
},
loadFilter:function(data){ //节点进行过滤,data参数里包含节点数组(此处功能:为菜单4加上一个保存图标。
for(var i=0;i
例:结合后台数据库添加,删除树节点。
步骤:
1.数据结构与数据库表如下:
[{
"id": 1,
"text": "Node 1",
"state": "closed",
"children": [{
"id": 11,
"text": "Node 11"
},{
"id": 12,
"text": "Node 12"
}]
},
{
"id": 2,
"text": "Node 2",
"state": "closed"
}]
数据库中我们先定义几个节点信息。
2.建数据表的java数据模型,dao,service,controller层的类
package cn.ybzy.sshweb.model;
import java.util.ArrayList;
import java.util.List;
//Easyui tree树节点的java模型类
public class TreeNode {
private int id;
private String text;
private List children = new ArrayList<>();
private Integer parentId; //因为有子节点,插入时要有父节点id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public List getChildren() {
return children;
}
public void setChildren(List children) {
this.children = children;
}
public Integer getParentId() {
return parentId;
}
public void setParentId(Integer parentId) {
this.parentId = parentId;
}
@Override
public String toString() {
return "TreeNode [id=" + id + ", text=" + text + ", children=" + children + ", parentId=" + parentId + "]";
}
}
-------------------------------------------------------------TreeNodeDao.java接口---------------------------------------------------
package cn.ybzy.sshweb.dao;
import java.util.List;
import cn.ybzy.sshweb.model.TreeNode;
public interface TreeNodeDao extends BaseDao {
//获取所有的节点对象
public List getAllNodes();
//获取最新节点的id,最后节点的id,所有节点id的最大值
public int getNewestId();
}
------------------------------------------------------TreeNodeDao.java接口实现类TreeNodeDaoImpl.java-------------
@Repository("treeNodeDao") //把它放进IOC中,写法是首字母小写
public class TreeNodeDaoImpl extends BaseDaoImpl implements TreeNodeDao {
//获取所有的节点对象
@Override
public List getAllNodes() {
String hql = "from TreeNode";
return super.list(hql, null, null);
}
@Override
public int getNewestId() {
String hql = "select max(id) from TreeNode";
//return (int)super.queryByHql(hql, null, null); //注意java类型转换从一个对象转换到整数类型时,会转成long类型,所以我们可以拐个湾确保转成int,如下
return Integer.parseInt(super.queryByHql(hql,null,null).toString());
}
}
----------------------------------------------------TreenNodeService.java接口----------------------------------------------------
public interface TreeNodeService extends BaseService {
//获取所有的节点对象
public List getAllNodes();
//获取最新节点的id,最后节点的id,所有节点id的最大值
public int getNewestId();
}
-------------------------------------------TreeNodeServiceImpl.java----------------------------------------------------------------
@Service("treeNodeService")
public class TreeNodeServiceImpl extends BaseServiceIpml implements TreeNodeService{
@Autowired
private TreeNodeDao treeNodeDao; //自动装备注入Dao层对象
/**
* 实现节点的层次结构,返回一个有层次结构的list
*/
@Override
public List getAllNodes() {
//获取到所有节点
List nodes = treeNodeDao.getAllNodes();
//要做的事情,就是区分出父节点,把对象子节点放入对应的父节点的children属性去
List parents = new ArrayList<>(); //这个集合,我打算放所有没有父节点的根节点在这个集合里(即树的第一层节点)
Map map = new HashMap<>(); //nodes所有的节点对象,都放进map去
for(TreeNode node:nodes) { //这个循环是把树的第一层节点放进parents集合里,且让所有节点(包括第二层结点)放进map集合里,并顺序从小到大
map.put(node.getId(),node);
if(node.getParentId() == null) {
parents.add(node);
}
}
for(TreeNode node:nodes) {
TreeNode parent = map.get(node.getParentId());
if(parent != null) {
parent.getChildren().add(node); //终极实现添加子节点功能
}
}
System.out.println("parents:"+parents);
return parents;
}
//获取最新节点的id,最后节点的id,所有节点id的最大值
@Override
public int getNewestId() {
return treeNodeDao.getNewestId();
}
}
------------------------------------------------------------TreeNodeController.java---------------------------------------------------
@Controller //@Conctroller表控制层功能
public class TreeNodeController {
@Autowired //自动注入IOC中的对象(已在service层中加入了IOC中)
private TreeNodeService treeNodeService;
@ResponseBody //因为是easyui与网页json数据格式直接交互,所以要加上@ResponseBody
@RequestMapping(value="/getAllNodes",method=RequestMethod.POST)
public List getAllNodes(){
List nodes = treeNodeService.getAllNodes();
return nodes;
}
@ResponseBody
@RequestMapping(value="/getNewestId",method=RequestMethod.POST)
public int getNewestId() {
return treeNodeService.getNewestId();
}
@ResponseBody
@RequestMapping(value="/addNode",method=RequestMethod.POST)
public String addNode(TreeNode node) {
treeNodeService.add(node);
return "success";
}
/**
* 删除表中的节点记录信息
* @param id
* @return
*/
@ResponseBody
@RequestMapping(value="/removeNode",method=RequestMethod.POST)
public String removeNode(@RequestParam("id") int id) {
treeNodeService.delete(id);
return "success";
}
}
3.jquery的ajax与控制层交互,修改数据库表数据,使之形成节点数据json格式
jq的ajax之post形式如下:
$.post("/sshwebtest/removeNode",{id:selectedNode.id},function(rs){});三个参数,第一个是连接到后台,第二个是对象即节点对象信息,第三个参数是处理函数,一般不用管只写出来即可
思路大概:
当我们右健单击一个节点时,同时发送ajax(在onContextMenu:function(e,node)绑定弹出菜单中实现)到控制层中获取当前节点的id(数据库中存在的id(添加节点时肯定它的id为最大id值--勿yong置疑).
添加节点后我们写入节点名后回车,会触发onAfterEdit:function(node)事件,在该事件方法中我们把节点信息如id,text放入到数据库中(分:子节点和兄弟节点两种情况)。
----------------------------------------------------------------------index.jsp--------------------------------------------------------------
----------------------------------------------------------------------index.js---------------------------------------------------------------
$(function(){
$("#tt").tree({
animate:true,
url:"/sshwebtest/getAllNodes",
checkbox:true, //节点左侧显示复选框
lines:true, //节点左侧显示竖线,
cascadeCheck:true, //true是默认。false时不级联检查,如节点4,有三个子节点,当勾选中父节点,子节点不勾选,相反也是一样。
onlyLeafCheck:true, //有子节点的父节点不显示复选框,即没有勾选之处。
formatter:function(node){ //对节点进行格式化
return "<-"+node.text+"->";
},
loadFilter:function(data){ //节点进行过滤,data参数里包含节点数组(此处功能:为菜单4加上一个保存图标。
for(var i=0;i
20Datagrid 数据网格基本用法
数据网格(datagrid)以表格格式显示数据,并为选择、排序、分组和编辑数据提供了丰富的支持。数据网格(datagrid)的设计目的是为了减少开发时间,且不要求开发人员具备指定的知识。它是轻量级的,但是功能丰富。它的特性包括单元格合并,多列页眉,冻结列和页脚,等等。
通过一些参数查询数据。
$('#dg').datagrid('load', {
name: 'easyui',
address: 'ho'
});
在服务器改变数据之后,更新前台数据。
$('#dg').datagrid('reload');
load 和 reload 很相似,但也有区别:分页的时候, load 会回到第一页, reload 会保留在当前页!
- 使用 class创建数据网格(datagrid)。
id
username
passwrod
state
regDate
height
id
username
passwrod
state
regDate
height
id
username
passwrod
state
regDate
height
..........
- 使用 javascript 创建数据网格(datagrid)并显示后台mysql t_students表的数据。
------------------------------------------------------xxx.jsp------------------------------------------------------
-------------------------------------------------------xxx.js-------------------------------------------------------
$("#dg").datagrid({
url:"/sshwebtest/getAllStudentsD",
// method:"post", //默认为post可以不写这行代码
columns:[[
{field:"id",title:"id",width:100},
{field:"stuname",title:"stuname",width:100},
{field:"password",title:"password",width:100},
{field:"state",title:"state",width:100},
{field:"regDate",title:"regDate",width:100},
{field:"height",title:"height",width:100}
]], //两个中括号,表示二维表格
});
--------------------------------------------------------------后台StuController.java----------------------------------------
@ResponseBody
@RequestMapping(value="/getAllStudentsD",method=RequestMethod.POST)
public List getAllStudentsD(){
List stus = stuService.getAllStus();
return stus;
}
- 给网格加上工具栏,一个工具(铅笔),再加上网纹,设计工具单击事件(单击后,在浏览器的控制台中显示相关记录,这里我们只以2.的代码中加一些数据。
$("#dg").datagrid({
title:"用户信息表",
url:"/sshwebtest/getAllStudentsD",
// method:"post", //默认为post可以不写这行代码
columns:[[
{field:"ck",checkbox:"true"}, //最左侧有复选框,可供我们选择,
{field:"id",title:"id",width:100},
{field:"stuname",title:"stuname",width:100},
{field:"password",title:"password",width:100},
{field:"state",title:"state",width:100},
{field:"regDate",title:"regDate",width:100},
{field:"height",title:"height",width:100}
]], //两个中括号,表示二维表格
striped:true, //把表格网纹化,即奇偶行不同背影 色
toolbar:[ //网格上有工具栏,有一个工具(铅笔)
{
iconCls:"icon-edit",
handler:function(){
//alert("单击");
var datas = $("#dg").datagrid("getChecked"); //获取选中复选框中记录
if(datas.length > 0 ){
for(var i=0;i
- Datagrid 数据网格工具栏和复选框---即对上面的属性和方法做介绍
toolbar array,selector
数据网格( datagrid )面板的头部工具栏。可能的值:
1 、数组,每个工具选项与链接按钮( linkbutton )一样。
2 、选择器,只是工具栏。
在 标签内定义工具栏:
$('#dg').datagrid({
toolbar: '#tb'
});
通过数组定义工具栏:
$('#dg').datagrid({
toolbar: [{
iconCls: 'icon-edit',
handler: function(){alert('edit')}
},'-',{
iconCls: 'icon-help',
handler: function(){alert('help')}
}]
});
实现批量删除,用复选框:
{field:'ck',checkbox:"true"},
与复选框有关的两个属性和方法:
属性:
1.singleSelect boolean 如果设置 true ,只能选择一条 默认值 false
2.checkOnSelect boolean 如果设置为 true ,当用户点击某一行时,则会选中 / 取消选中复选框。 默认值 true
3.selectOnCheck boolean 如果设置为 true ,点击复选框将会选中该行。 默认值true
方法:
1.getChecked none 返回复选框选中的所有行。返回的是一个集合
2.getSelected none 返回第一个选中的行或者 null 。返回的是该行的数据对象
3.getSelections none 返回所有选中的行,当没有选中的记录时,将返回空数组。
- 数据绑定和分页查询和模糊查询
处理绑定的问题:
1.在Model类里如果有日期时间类型的属性, 要注意处理日期时间的格式(加两个注解),否则会出问题的:
image.png
@JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8"): 设置页面上日期时间显示的
格式,没有这个,会在页面上显示时间戳!
@DateTimeFormat注解将一个字符串转成一个Date对象,在springmvc的controller层接收
数据的时候封装对象用的,没有用对象来接收数据报错!
2.有的数据显示的时候要处理:如state状态, 我们不想直接显示1,显示 ‘正常'
image.png
image.png
分页查询:
1.有关属性:
pagination boolean 设置为 true ,则在数据网格( datagrid )底部显示分页工具栏。
pagePosition string 定义分页栏的位置。可用的值有: 'top' 、 'bottom' 、 'both' 。
pageNumber number 当设置了 pagination 属性时,初始化页码。
pageSize number 当设置了 pagination 属性时,初始化页面尺寸。
pageList array 当设置了 pagination 属性时,初始化页面尺寸的选择列表。
例:
$("#dg").datagrid({
title:"用户信息表",
url:"/sshwebtest/getAllPagerStudents", //后台链接
pagination:true, //分页显示,有修改每页显示多少条功能,不用写代码
pageSize: 5, //初始化每页有几条记录,即默认条数。
pageList:[5,10,25,30,100], //设置分页每页能显示多少条记录选择项,这里是每页有5条,10条,,,多个选项,
// method:"post", //默认为post可以不写这行代码
columns:[[
{field:"ck",checkbox:"true"}, //最左侧有复选框,可供我们选择,
{field:"id",title:"id",width:100},
{field:"stuname",title:"stuname",width:100},
{field:"password",title:"password",width:100},
{field:"state",title:"state",width:100,formatter:function(value,row,index){
if(value == 1){
return "正常";
}else{
return "禁用状态";
}
}},
{field:"regDate",title:"regDate",width:100},
{field:"height",title:"height",width:100}
]], //两个中括号,表示二维表格
striped:true, //把表格网纹化,即奇偶行不同背影 色
});
image.png
加上前面的属性,样子有了,但还没有实现分页的,分页是需要后台支持的:
//带分页显示所有学生信息,不用注入对象,这里我们直接用网页与easyui交互,用到json格式数据,所以用@ResponseBody注解
@ResponseBody
@RequestMapping(value="/getAllPagerStudents",method=RequestMethod.POST)
public Pager getAllPagerStudents(Integer page,Integer rows) { //page,rows值由easyui 网格发送过来
System.out.println("StuController.java中由easyui 网格发送的page,rows "+page+","+rows);
if(page != null && page>0) SystemContext.setPageSize(rows); //每一页两条记录
if(rows !=null && rows>0) SystemContext.setPageOffset((page-1)*rows); //从第一条记录开始分
Pager pager = stuService.getAllPagerStus();
SystemContext.removePageOffset();
SystemContext.removePageSize();
return pager;
}
http://localhost/sshwebtest运行结果:
image.png