easyui的datagrid整合struts2,以及Ajax,实现局部刷新功能,并设置分页的实现---------投票案例

=========================================================================================================

1.登陆功能-

----表单内容-----------------------------------------------------

<pre name="code" class="java"><div class="login">
			<h2>用户登录</h2>
			<form method="post" action="login!login.action">
				<dl id="loginBox">
					<dt>用户名:</dt>
					<dd><input type="text" class="input-text" name="userId"  value="<s:property value='userId'/>"/></dd>
					<dt>密 码:</dt>
					<dd><input type="password" class="input-text" name="password"  value="<s:property value='password'/>"/></dd>
					<dt></dt>
					<dd><input type="submit" class="input-button" value="登录" /> <a href="register.action">新用户注册</a></dd>
				</dl>
			</form>
			<div class="error"><s:actionerror/></div>
		</div>

-----struts.xml----------------------------------------------------

<action name="login"
			class="cn.jbit.vote.web.LoginAction" >
			<result name="success">/login.jsp</result>
			<!-- <result name="loginSuccess" type="redirect">/Subject!list.action</result> -->
			<result name="loginSuccess">/index.jsp</result>
			<result name="loginFailure">/login.jsp</result>
		</action>

----LoginAction-----------------------------------------------------

public class LoginAction extends BaseAction {
	private VoteServiceImpl service;
	private String userId;
	private String password;

	public VoteService getService() {
		if (service == null)
			service = new VoteServiceImpl();
		return service;
	}

	public String execute() {
		return SUCCESS;
	}

	public String login() {
		User user = getService().findUserById(userId);
		/**
		 * 通过id查找到用户对象,如果用户为null,则属于登陆失败,此时添加错误信息,通过this.addActionError()方法,getText("loginUser.notExist")是提取信息文件的内容
		 * 如果用户不为null,通过传入的密码和对象的密码进行比较,验证成功,则建立session存放对象ActionContext.getContext().getSession().put("loginUser", user);
		 * 密码验证失败,this.addActionError(getText("loginUser.wrongPassword")); 添加国际化错误信息
		 * this.hasErrors()判断是否存在fielderror对象进行相应跳转return "loginFailure";
		 * this.addActionError()添加不同的错误信息,来显示不同的错误信息
		 */
		if (user == null) {
			this.addActionError(getText("loginUser.notExist"));
		} else {
			if (user.getPassword().equals(password)) {
				ActionContext.getContext().getSession().put("loginUser", user);//
			} else
				this.addActionError(getText("loginUser.wrongPassword"));
		}
		if (this.hasErrors())
			return "loginFailure";
		return "loginSuccess";
	}

}

-最底层方法实现悲观锁乐观锁,--------------------------------------------------------

//	悲观锁在应用程序中显示地为数据资源加锁.悲观锁假定当前事务操纵数据资源时,肯定还会有其它事务同时访问该数据资源,
//	为了避免当前事务的操作受到干扰,先锁定资源.尽管悲观锁能防止丢失更新和不可重复读这类并发问题,但会影响并发性能.
//	(简单理解,就是每次在操作数据时总是悲观地认为会有别的事务也会来操纵同一数据,从此锁住该笔数据,直到自己操作完成后再解除锁)
//
//  乐观锁:假定当前事务操纵数据资源时,不会有其它事务同时访问该数据资源,因此完全依靠数据库的隔离级别来自动管理锁的工作.
//	应用程序采用版本控制手段来避免可能出现的并发问题.(所谓乐观锁,它通常认为多个事务同时操纵同一数据的情况是很少的,
//	因为根本不做数据库层次上的锁定,只是基于数据的版本标识实现应用程序级别上的锁定机制,既保证了多个事务的并发访问,
//	又有效地防止了第二类丢失更新的出现)

//	多个事务并发运行时的并发问题:
//	第一类丢失更新:撤销一个事务时,把其它事务已提交的更新数据覆盖.
//	第二类丢失更新:不可重复读中的特例,一个事务覆盖另一事务已提交的更新数据.
//	脏读:一个事务读到另一事务未提交的更新数据.
//	幻读:一个事务读到另一事务已提交的新插入的数据.
//	不可重复读:一个事务读到另一个事物已提交的更新数据.
	@SuppressWarnings("unchecked")
	public Object findById(Class entityClass, Serializable id, boolean lock) {
		Object object;
		if (lock)
			object = HibernateSessionFactory.getSession().get(entityClass, id, LockMode.UPGRADE);//悲观锁
		else
			object = HibernateSessionFactory.getSession().get(entityClass, id);//本例设计的都为乐观锁 lock=false
		return object;
	}

=========================================================================================================

2.easyui使用tree模式==========JSONArray

----jsp----------------------------------------------------------------------

<div class="tree">
		<ul id="mytree"></ul>
	</div>
<script type="text/javascript">
	$(function() {
		getTree();
		/*加载方法*/
		indexGrid();
		$("#gridSearch").click(function() {
			var name = $('#keywords').val();
			$('#mygrid').datagrid('load', {
				keywords : name
			});
		});
	});
</script>

----外部js文件引入------------------------------------------------------------------------

/*<div class="tree"><ul id="mytree"></ul></div>  animate:true定义节点在展开或折叠的时候是否显示动画效果。
onDblClick:function(node){}在用户双击一个节点的时候触发。
onClick:function(node){}在用户点击一个节点的时候触发。*/
function getTree(){
	$("#mytree").tree({
		url:"getTree.action",
		animate:true,
		onDblClick:function(node){
			$(this).tree("toggle",node.target);
		},
		onClick:function(node){
			alert(11);
			if(node.id==113){
				alert(113);
				act(2);
			}else if(node.id==112){alert(112);
				act(1);
			}else if(node.id==111){alert(111);
				act(0);
			}
		}

	});
}

-------struts.xml  可多个package---------------------------------------------------------------------

<package name="json"  extends="json-default">
		<action name="getTree" class="cn.jbit.vote.web.SubjectAction" method="getSubjectTree">
			<result name="success" type="json">
				<param name="root">treeJSON</param>
				<param name="excludeNullProperties">true</param>
			</result>
		</action>

	 </package>  

----action:获取树形菜单,产生json对象----------------------------------------------------------------

/**
	 * 获取树形菜单
	 *
	 * @return
	 */
	public String getSubjectTree() {
		treeJSON = getService().getTreeJSON();

		return SUCCESS;
	}

----底层方法:产生json对象------调用不同的构造方法,放入不同参数:如id,名称,及其下边的集合:-将根目录放入list中,站华为json数组,

传入action中的JSONArray  treeJSON,指盏对象传入acition-----------------------------------------------------------------

	public JSONArray getTreeJSON() {
		//封装菜单数据
		Set<TreeNode> set = new HashSet<TreeNode>();
		Set<TreeNode> set1 = new HashSet<TreeNode>();
		Set<TreeNode> set2 = new HashSet<TreeNode>();
		set1.add(new TreeNode(111,"所有投票"));
		set1.add(new TreeNode(112,"发布新投票"));
		set1.add(new TreeNode(113,"维护"));
		set2.add(new TreeNode(121,"个人信息"));
		set2.add(new TreeNode(121,"投票记录"));
		set.add(new TreeNode(11,"投票管理",set1));
		set.add(new TreeNode(12,"用户管理",set2));
		set.add(new TreeNode(13,"系统管理","system.txt"));

		List<TreeNode> list  = new ArrayList<TreeNode>();
		list.add(new TreeNode(1,"功能菜单", set));

		//将封装好的目标数据格式化为JSONArray对象
		JSONArray result =  JSONArray.fromObject(list);

		return result;
	}

------treeNode----------------------------------------------------------------------

public class TreeNode {
	private Integer id;
	private String text;
	private Set<TreeNode> children;
	//private Map<String,String> attributes;
	private String iconCls;
	private String state;
	private String url;
	private String checked;<pre name="code" class="java">public TreeNode(Integer id, String text, Set<TreeNode> children) {
		super();
		this.id = id;
		this.text = text;
		this.children = children;
	}
	public TreeNode(Integer id, String text) {
		super();
		this.id = id;
		this.text = text;
	}

=========================================================================================================

3.datagrid活动页的效果:标题内容,链接至#tabs-1             <a href="manage.jsp">

--------------------------------------------------------------------------

<pre name="code" class="java"><div id="index" class="content wrap">

		<div id="tabs">
			<ul>
				<li><a href="#tabs-1">返回列表</a></li>
				<li><a href="#tabs-2">发布新投票</a></li>
				<li><a href="manage.jsp">维护</a></li>
				<li style="float: right; margin: 5px 10px 0 0">您好,<s:property
						value="(#session['loginUser']).userName" /></li>
				<!--datagrid的头部标签,获取session中的对象,通过<a href="#tabs-1">加载tabs的页码内容-->
			</ul>
			<div id="tabs-1">
				<div class="info">
					<div class="search">
						<input id="keywords" class="autoComplete" type="text"
							name="keywords" value="" /> <input id="gridSearch"
							class="gridSearch" type="button" name="search" value="搜索" />
					</div>
				</div>
				<table id="mygrid"></table>
			</div>
			<div id="tabs-2">
				<jsp:include page="add.jsp" />
			</div>
		</div>

=========================================================================================================

4.

-----表单第一部分---------------------------------------------------------------------

<div id="tabs">
			<ul>
				<li><a href="#tabs-1">返回列表</a></li>
				<li><a href="#tabs-2">发布新投票</a></li>
				<li><a href="manage.jsp">维护</a></li>
				<li style="float: right; margin: 5px 10px 0 0">您好,<s:property value="(#session['loginUser']).userName" /></li>
				<!--datagrid的头部标签,获取session中的对象,通过<a href="#tabs-1">加载tabs的页码内容-->
			</ul>
			<div id="tabs-1">
				<div class="info">
					<div class="search">
						<input id="keywords" class="autoComplete" type="text"  name="keywords" value="" />
						<input id="gridSearch" class="gridSearch" type="button" name="search" value="搜索" />
					</div>
				</div>
				<table id="mygrid"></table>
			</div>
			<div id="tabs-2">
				<jsp:include page="add.jsp" />
			</div>
		</div>

-------js加载方法,以及搜索的时候方法---------------------------------------------------------------------

<script type="text/javascript">
	$(function() {
		/*加载Tree  */  getTree();
		/*加载返回列表的方法   id="mygrid"  */  indexGrid();

			$("#gridSearch").click(function() {  /*#gridSearch  点击搜索    */
				var name = $('#keywords').val();   /*  获得#keywords输入框的内容    */
				$('#mygrid').datagrid('load', {    /* table id="mygrid"  表格添加属性    */
					keywords : name
				});
			});
	});
</script>

-------外部js文件---------------------------------------------------------------------

function indexGrid(){
	$('#mygrid').datagrid({
		url:'getDatagrid.action',
		rownumbers:true,
		iconCls: 'icon-search',
		pagination:true,//显示底部分页栏
		pageSize:10,//默认每页记录数,pagination参数为true时才有效
		pageList:[5,10,15], //显示列表记录数的下拉框选项,pagination参数为true时才有效
		fitColumns:true,//自适应宽度,防止水平滚动
		striped:true,//隔行变色
		columns:[[//JSON数组:每列为一个json对象
          	{field:'id',title:'id',hidden:'true'},
			{field:'title',title:'投票标题',width:300},
			{field:'options',title:'选项数',align:'right'},
			{field:'participants',title:'投票人数',align:'right'},
			{field:'opr',title:'操作',align:'center',formatter:function(){
				return "<a herf='#' style='color:red;'>参加投票</a>";
//单元格formatter(格式化器)函数,带3个参数:value:字段值。rowData:行记录数据。rowIndex: 行索引。 
			}}
		]],
		onClickCell:function(index,field,v){//在用户点击一个单元格的时候触发。
			if(field=="opr"){//点击列名为opr时跳转
				var id = $(this).datagrid("getRows")[index].id;
				window.location.href="vote.action?subject.id="+id;
			}
		}
	});
}

----struts.xml------------------------------------------------------------------------

		<action name="getDatagrid" class="cn.jbit.vote.web.SubjectAction" method="getSubjectGrid" >
			<result type="json">
				<param name="root">gridJSON</param>
             	<param name="excludeNullProperties">true</param>
			</result>
		</action>

----action中------------------------------------------------------------------------

private String keywords;//模糊搜索的调价

private Subject subject;

private String rows;// 每页显示记录条数

private String page;// 当前页数

	/**
	 * 获取投票列表
	 * gridJSON对象,放指盏中
	 * @return
	 */
	public String getSubjectGrid() {
		gridJSON = getService().getGridJSON(keywords, page, rows);

		return "success";
	}

-----biz从数据访问层提取,转化为存放帮助类的list,将list放入Map以及总数,-----------------------------------------------------------------------

	public JSONObject getGridJSON(String keywords,String pageNumber,String pageSize) {
		//获取分页参数
		Integer page = null!=pageNumber ? Integer.parseInt(pageNumber) : 0;
		Integer size = null!=pageSize ? Integer.parseInt(pageSize) : 10;

		List<Subject> subjects = subjectDao.getSubjectsByTitle(keywords,page,size);//获取符合条件的分页集合
		Integer count = subjectDao.getSubjectsConutByTitle(keywords);//获取符合条件的所有数据的集合长度
		List<Object[]> subjectVotes = (List<Object[]>)getUserCountPerSubject(null);//查询所有投票记录的投票选项数和参与人数

		Map<Object, Object> votes = new HashMap<Object, Object>();//查询所有投票记录的投票选项数和参与人数
		for (Object[] subjectVote : subjectVotes) {
			votes.put(subjectVote[0],  subjectVote[1]);
		}
		//组装GridNode对象,构建投票列表数据
		List<GridNode> list = null;
		if(null != subjects){
			list  = new ArrayList<GridNode>();
			for(Subject subject :subjects){
				Long id = subject.getId();
				String title = subject.getTitle();
				Integer type = subject.getType();
				Set<Option> otions = subject.getOptions();
				String optionsCount = null!=otions ? otions.size()+"" : "0";
				Object o = votes.get(id);
				String participants = null!= o ? String.valueOf(o) : "0";
				list.add(new GridNode(subject.getId(),title,type,optionsCount,participants));
			}
		}
//		----------List<Subject> subjects底层取出 ------List<GridNode> list集合(GridNode:id,title,options,participants)
//		-----map("total",count)("rows", list)------JSONObject[{"":""},{"":{{"":""},{"":""}}}]

		Map<String,Object> map = new HashMap<String,Object>();
		map.put("total", count);
		map.put("rows", list);
		JSONObject result =  JSONObject.fromObject(map);//将封装好的目标数据格式化为JSONObject对象

		return result;
	}

------criteria实现动态查询功能----------------------------------------------------------------------

@SuppressWarnings("unchecked")
	public List<Subject> getSubjectsByTitle(String title,Integer pageNumber,Integer pageSize) {
		Criteria criteria = HibernateSessionFactory.getSession().createCriteria(Subject.class);
		if(null!=title&&!("".equals(title))){
			criteria.add(Restrictions.like("title", "%"+title+"%"));
		}
		criteria.setFirstResult((pageNumber-1) * pageSize);
		criteria.setMaxResults(pageSize);
		criteria.addOrder(Order.desc("id"));
		return (List<Subject>) criteria.list();
	}

-------criteria实现动态查询且统计总数,排序功能---------------------------------------------------------------------

@SuppressWarnings("rawtypes")
	public Integer getSubjectsConutByTitle(String title) {
		Criteria criteria = HibernateSessionFactory.getSession().createCriteria(Subject.class);
		if(null!=title && !"".equals(title)){
			criteria.add(Restrictions.like("title", "%"+title+"%"));
		}
		criteria.addOrder(Order.desc("id"));
		List list = criteria.list();

		return null!=list?list.size():0;
	}

---------hql语句实现类似的分组后统计总数,且重复时不统计-------------------------------------------------------------------

	/*
	 * (non-Javadoc)
	 *
	 * @see cn.jbit.vote.biz.impl.VoteService#getSubjectVotes()
	 */
	public List<Object[]> getUserCountPerSubject(Long id) {
		return subjectDao.getSubjectVotes(id);
	}
	/**
	 * 根据条件获取投票选项的参与人数
	 */
	@SuppressWarnings("unchecked")
	public List<Object[]> getSubjectVotes(Long id) {
		String hql = "select it.subject.id,count(distinct it.user.id)  from Item it ";
		//String hql = "select it.subject.id,count(it.user.id)  from Item it ";
		if (id != null)
			hql = hql + " where it.subject.id=" + id;
		hql = hql + " group by it.subject.id";
		return super.findByHql(hql);
	}

6.点击链接,发送信息===============================================================

----------------------------------------------------------------------------

function indexGrid(){
	$('#mygrid').datagrid({
		url:'getDatagrid.action',
		columns:[[//JSON数组:每列为一个json对象
          	{field:'id',title:'id',hidden:'true'},
			{field:'title',title:'投票标题',width:300},
			{field:'options',title:'选项数',align:'right'},
			{field:'participants',title:'投票人数',align:'right'},
			{field:'opr',title:'操作',align:'center',formatter:function(){
				return "<a herf='#' style='color:red;'>参加投票</a>";
				//单元格formatter(格式化器)函数,带3个参数:value:字段值。rowData:行记录数据。rowIndex: 行索引。
			}}
		]],
		<pre name="code" class="java"><span style="white-space:pre">		</span>//[{"":""},{"":  {{"":""},{"":""}}  }]
		//$(this)json对象,$(this).datagrid("getRows")JSON对象的第二个元素得知为JSON对象的集合,随后通过下表取得对象
		onClickCell:function(index,field,v){
			if(field=="opr"){//点击列名为opr时跳转
				var id = $(this).datagrid("getRows")[index].id;
				alert($(this));
				window.location.href="vote.action?subject.id="+id;
			}
		}

});}


---action自动选择方法-------------------------------------------------------------------------

		<action name="vote"
			class="cn.jbit.vote.web.VoteAction">
			<result name="success">/vote.jsp</result>
			<result name="saveSuccess">/vote_success.jsp</result>
			<result name="viewSuccess">/view.jsp</result>
		</action>

----------------------------------------------------------------------------

时间: 2024-08-11 01:25:58

easyui的datagrid整合struts2,以及Ajax,实现局部刷新功能,并设置分页的实现---------投票案例的相关文章

easyUI之datagrid 及struts2如何配置

datagrid可以说是easyUI最重要的一个控件.下面我们来看看它有哪些功能,以及如何来实现. $('#firmresult').datagrid({ singleSelect:true,//设置只能选择单选 pagination:true,//显示分页 // fit:true,//自动土适应父容器的大小 fitColumns:true,//列宽的自动适应 rownumbers: true,//显示第几行 pageList:[5,10,15],//每页显示记录条数 pageNumber:1,

struts2结合ajax实现无刷新登录

1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@taglib prefix="s" uri="/struts-tags"%> <!-- 必须加入struts2-dojo-plugin-相应版本.jar 才能使用ajax--> <%@taglib prefix=&qu

Ajax实时局部刷新

//Ajax实现局部刷新      <script type="text/javascript">    var xmlhttp;    function getData()    {      //获取用户填写的名称      var city=document.getElementById("txt").value;      //创建异步调用对象      xmlhttp=new ActiveXObject("Microsoft.XMLH

Ajax 异步局部刷新

Ajax 异步局部刷新 AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新. 传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面. 实现json 字符串与 JavaScrip 对象得相互转换 JSON.parse()和 JSON.stringify() 1.序列化(将JavaScrip 转换为 json)使用 JSON.st

使用php后台给自己做一个页面路由,配合ajax实现局部刷新。

今天就要放假了,把近来囤积的小玩意儿总结整理一下. 在请求一个html页面来嵌入到当前页会有一个问题,就是跟随请求过来的html他的样式表和脚本会失效.是因为文档加载的先后顺序等问题造成的.因此,加载一些纯文本还好. 举个例子,只有这个问题明白了,我们的原理才好理解. b.html有一个点击事件,但是a.html通过ajax拿到b.html后,如果这个b.html的js不是写在页面里面的,你就会发现没有生效.css样式也一样,都需要重新绑定一下. 首先定义两个页面,一个父页面a.html,一个b

ajax实现局部刷新

<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8"> <title>demo</title></head><body><div class="maxBox"> <span class="T-active indexA">首页</span

js(三) ajax异步局部刷新技术底层代码实现

ajax 异步 javaScript and xml 开发五步骤: 1. 创建对象 XMLHttpRequest(chrome,firefox) ie... jquery 2. 找到连接, http的method方法    GET|POST    PUT DELETE 3. 注册监听器  有数据返回之后,就会自动调用该方法(不是一次 3次) 4. 发送请求 POST PUT delete 请求数据 5. 处理请求 1 <%@ page language="java" conten

通过javascript&amp;&amp;ajax实现局部刷新

使用形式如下: function showli_1(){ //通过一个按钮onclick触发函数 var xmlhttp=new XMLHttpRequest(); xmlhttp.open("GET","/ajax_js_war_exploded/EmpServlet?flag=1",true);//定义上传的方式,要传输的Servlet和?后加要传输的数据,数据之间以逗号分隔开,定义是否为异步 xmlhttp.send(); //将请求发送 xmlhttp.on

【SSH网上商城项目实战28】使用Ajax技术局部更新商品数量和总价

昨天把项目部署了一下,玩了玩,今天完善了一下购物车中修改商品数量就能局部更新相应的总价的功能,大家都知道这得用Ajax实现,我之前也没学Ajax,刚好借助这个小功能,去简单学习一下Ajax的知识. 1.问题的分析 先看一下页面中的情况:  功能如上,在没有Ajax之前,一般都是根据用户修改的值去找Action,然后返回新的jsp页面重新加载整个页面,完成数字的更新.但是有了Ajax技术后,我们可以利用Ajax技术局部刷新要改变的地方,而不是重新加载整个页面.首先看一下上图对应的jsp部分的代码: