快两个月了,我快哭了,一直加班~都没有时间写啊!
在经过多天的思考,阅读了大量的Dojo,YUI源码,终于下定决心,正式启动simpleUI项目。
项目宗旨:基于jQuery建立一套完整的UI,弥补jQuery在某些领域的空白,让其更适合企业级应用程序的开发!
项目计划完成时间:2011.07
项目计划完成组件:
1:基础架构搭建 100%
2:动态加载组件 15%
3:对话框,图片展示组件 100%
4:数据表格组件 70%
5:日期组件
6:图形报表组件
7:表单元素组件(input,select,radio,checkbox,button)100%
8:下拉菜单,右键菜单组件 30%
9:拖放,排序组件
10:JSON模板解析,格式化组件
11:布局组件
最先完成的就是simpleDialog组件,其实这个组件在很久前就已经完工了~~一直在完善,目前放出的这个版本是最新的。
支持所有主流浏览器,当然包括万恶的IE6.0
all source
/**
* @author xing
* @date 2011-03-19
* @place guangzhou布谷
@version:1.8
*/
(function($){
var ie6 = typeof document.body.style.maxHeight === "undefined";
$.fn.simpleDialog = $.fn.dialog = function(opts){
//return this.each(function(){
var d = new SimpleDialog(this, opts);
return d;
//});
};
$.close = function(el){
if ($('.xq-dialog').length < 2) {
$('.xq-dialog-overlay').remove();
}
el = el || $('.xq-dialog');
el.remove();
if (ie6) {
$('html,body').removeClass('ie6Fixed');
}
};
$.iframe = $.iframeDialog = function(){
var a = arguments, firstArgs = a[0];
a[1] = a[1] || {};
var o = $.extend({}, {
iframe: true,
iframeUrl: firstArgs
}, a[1]);
return $().simpleDialog(o);
};
/**
* 弹出ajax对话框
* @param {string} url
* @param {Object}
* @param {function} callback
* @return {Object} other
* @return {jQuery Object} dialog
*/
//url,object,callback
$.ajaxDialog = function(){
var a = arguments, firstArgs = a[0], callback = a.length > 1 ? a[1] : function(){
};
a[2] = a[2] || {};
var o = $.extend({
ajax: true,
ajaxUrl: firstArgs,
onLoad: callback
}, a[2]);
return $().simpleDialog(o);
};
/**
* 弹出警告框
* @param {string} html
* @param {function} callback
* @param {Object} other
* <code>
* $.alert('this is a demo');
* </code>
* <code>
* var callback=function(){};
* $.alert('',callback);
* </code>
*/
$.alert = $.alertDialog = function(html, callback, other){
var sure = function(e){
var el = $(this).parents('.xq-dialog');
$.close(el);
if ($.isFunction(callback)) {
callback();
}
};
var o = $.extend({
buttons: {
'确定': sure
},
alert: true,
title: '温馨提示'
}, other);
html = $('<div class="xq-dialog-alert"></div>').append(html);
return html.simpleDialog(o);
};
/**
* 弹出确认框
* @param {string} html
* @param {function} callback
* @param {function} onCancel
* @param {Object} other
*/
$.confirm = $.confirmDialog = function(html, callback, onCancel, other){
var sure = function(){
var el = $(this).parents('.confirm-dialog');
$.close(el);
if ($.isFunction(callback)) {
callback();
}
};
var cancel = function(e){
var el = $(this).parents('.confirm-dialog');
$.close(el);
if ($.isFunction(onCancel)) {
onCancel();
}
};
var o = $.extend({
buttons: {
'确定': sure,
'取消': cancel
},
confirm: true,
title: '系统提示'
}, other);
html = $('<div class="xq-dialog-confirm"></div>').append(html);
return html.simpleDialog(o);
};
var SimpleDialog = Dialog = function(data, opts){
opts = $.extend({}, {
dialogTemplate: '<div class="xq-dialog"><div class="xq-dialog-close"></div><div class="xq-dialog-title"></div>' +
'<table class="xq-dialog-table"><tr class="handle"><td class="tl"></td><td class="tc"></td><td class="tr"></td></tr><tr><td class="cl">' +
'</td><td class="xq-dialog-wapper"><div class="xq-dialog-content"></div></td><td class="cr"></td></tr>' +
'<tr><td class="bl"></td><td class="bc"></td><td class="br"></td></tr></table></div>',
title: 'simpleDialog',
modal: true,
x: null,
y: null,
buttons: null,
id: null,
ajax: false,
ajaxUrl: null,
data: {},
iframe: false,
iframeUrl: null,
width: null,
height: null,
drag: true,
modal: true,
onLoad: function(){
},
onClose: function(){
}
}, opts);
var d = {
container: {},
init: function(){
var s = this, temp;
s.container.temp = temp = $(opts.dialogTemplate).clone();
$(document.body).append(temp);
if (opts.modal) {
s.overlay();
}
if (opts.iframe) {
var iframe = '<iframe src=' +
'"' +
opts.iframeUrl +
'"' +
' style="border:0" id="xq-dialog-iframe" frameborder=0 οnlοad="reinitIframe()"></iframe>';
$('.xq-dialog-content', temp).append(iframe);
}
else
if (opts.ajax) {
var divAjaxLoading = $('<div/>').html('<span>加载中,请等待</span>').addClass('ajaxloading');
var callback = function(){
divAjaxLoading.remove();
//加载完成设置尺寸,防止在加载完成之前执行
s.setPosition(opts.x, opts.y, temp);
opts.onLoad();
};
$('.xq-dialog-content', temp).append(divAjaxLoading).load(opts.ajaxUrl, opts.data, callback);
}
else
if (opts.alert) {
temp.addClass('alert-dialog');
}
else
if (opts.confirm) {
temp.addClass('confirm-dialog');
}
else {
//防止将页面中的元素移除
temp.addClass('normal-dialog');
}
$('.xq-dialog-wapper', temp).append(s.setBtns(opts.buttons));
$('.xq-dialog-content', temp).append(data);
s.setDialogAround(temp);
s.setPosition(opts.x, opts.y, temp);
return temp;
},
setDialogAround: function(el){
var s = this;
if (opts.id != null) {
el.attr('id', opts.id)
}
$('.xq-dialog-title', el).html(opts.title);
if (opts.width != null) {
$('.xq-dialog-content', el).width(opts.width);
}
if (opts.height != null) {
$('.xq-dialog-content', el).height(opts.height);
}
$('.xq-dialog-close', el).click(function(){
s.closeDialog();
});
},
setPosition: function(x, y, el){
//如果给定了top,left值
if (x && y) {
el.css({
top: y,
left: x
});
}
//否则居中显示
else {
var DOC = document.documentElement, DOCHEIGHT = DOC.clientHeight, DOCWIDTH = DOC.clientWidth, DOCSCROLLTOP = DOC.scrollTop;
el.css({
top: (DOCHEIGHT - el.height()) / 2 < 20 ? 20 : (DOCHEIGHT - el.height()) / 2,
left: (DOCWIDTH - el.width()) / 2
});
if (ie6) {
el.css({
top: (DOCSCROLLTOP + (DOCHEIGHT - el.height()) / 2) < 20 ? 20 : (DOCSCROLLTOP + (DOCHEIGHT - el.height()) / 2)
});
}
}
},
setBtns: function(buttons){
var buttonBar = $('<div/>').addClass('xq-dialog-btnBar');
if (typeof buttons !== 'object' || buttons == null) {
return null;
}
$.each(buttons, function(name, event){
event = $.isFunction(event) ? event : function(){
alert('你所传递的参数不是有效的函数!')
};
var button = $('<div>').addClass('btnAction').append('<span class="text">' + name + '</span>').click(event).appendTo(buttonBar);
});
return buttonBar;
},
getPageSize: function(){
var DOC = document.documentElement, DOCHEIGHT = DOC.clientHeight, DOCWIDTH = DOC.clientWidth, DOCSCROLLHEIGHT = DOC.scrollHeight, DOCSCROLLWIDTH = DOC.scrollWidth, MAXHEIGHT = Math.max(DOCHEIGHT, DOCSCROLLHEIGHT), MAXWIDTH = Math.max(DOCWIDTH, DOCSCROLLWIDTH);
return [MAXHEIGHT, MAXWIDTH];
},
overlay: function(){
var s = this;
if ($('.xq-dialog-overlay').length > 0) {
return;
}
s.container.overlay = $('<div/>').addClass('xq-dialog-overlay');
if (ie6) {
$('html,body').addClass('ie6Fixed');
}
$(document.body).append(s.container.overlay);
},
closeDialog: function(){
var s = this;
//判断页面中显示dialog的数量,以免存在多个dialog时将遮罩移除
if ($('.xq-dialog').not(':hidden').length < 2) {
if (s.container.overlay) {
s.container.overlay.remove();
}
$('.xq-dialog-overlay').remove();//防止关闭首先弹出的对话框
}
if (ie6) {
$('html,body').removeClass('ie6Fixed');
}
if (s.container.temp.hasClass('normal-dialog') && !opts.remove) {
s.container.temp.hide();
}
else {
s.container.temp.remove();
}
if (opts && opts.onClose && $.isFunction(opts.onClose)) {
opts.onClose();
}
}
};
return d.init();
}
})(jQuery);
//初始设置iframe的大小
function reinitIframe(){
var iframe = document.getElementById("xq-dialog-iframe");
$(iframe).height(100).width(300);
try {
var bHeight = iframe.contentWindow.document.body.scrollHeight;
var dHeight = iframe.contentWindow.document.documentElement.scrollHeight;
var BW = iframe.contentWindow.document.body.scrollWidth;
var DW = iframe.contentWindow.document.documentElement.scrollWidth;
var height = Math.max(bHeight, dHeight);
var width = Math.max(BW, DW);
$(iframe).height(height).width(width).css('overflow', 'hidden');
var el = $(iframe).parents('.xq-dialog');
$.setPosition(null, null, el);
}
catch (ex) {
}
}
调用实例:
简单调用
var dialog=$(‘#content’).dialog();
效果:
配置选项
dialogTemplate:’’,//调用的的对话框显示的模板,更改此选项可以改变外观
title: 'simpleDialog',//对话框显示的名称
modal: true,//是否显示遮罩层
x: null,//对话框显示的水平位置
y: null,//对话框显示的垂直位置
buttons: null,//对话框的构造按钮
id: null,//对话框的ID,配置此选项可以展示多个对话框
ajax: false,//配置使用ajax的方式
ajaxUrl: null,//配置ajax的URL
data: {},//发送到页面的数据
iframe: false,//配置使用iframe的方式
iframeUrl: null,//配置iframe的URL
width: null,//配置对话框的宽度
height: null,//配置对话框的高度
alert: false,//配置是否显示警告框
confirm: false,//配置是否显示确认框
drag: true,//配置对话框是否可以拖动
modal: true,//配置是否显示遮罩
onLoad: function(){},//页面加载完毕执行的回调
onClose: function(){}//对话框关闭执行的回调
构造按钮方式
var o={
buttons:{
‘确定’:function(){},
‘取消’:function(){}
}
}
var dialog=$(‘#content’).dialog();
效果
远程装载ajax页面
var dialog=$.ajaxDialog('content.html');
效果图
API有时间会放出,如果对jquery插件比较熟悉的话,看配置选项就知道怎么用了。
/*==================================4.8 同步更新simpleGrid-1.4==================================*/
目前支持的功能有
拖拽列,
JSON数据解析,
固定列,
多表头,
数据转换,
checkbox,radio
各种情况下的复杂查询~
单字段服务器端排序
所有源码~~
/**
* @author xing
* @date 2011-03-21
* simpleGrid
* @version 1.4
* add multiple header
* add fixed colmuns
* support convert normal table to simplegrid
* @method simpleGrid---->return grid object;
* @date 2011-03-26
* 修正滚动时表头和内容无法对齐的Bug
* 修正固定高度的列和内容无法对齐的Bug
* 添加三个公共的方法~~
* @method reload:重载表格数据
* @method keepGrid:保持所有的查询条件重载表格数据
* @method setSelectedCell:获取选中的行内数据进行操作
* 修正解析JSON格式错误的问题
* @method groupTable
* //{opts,colIndex,callback}
*@date 03-29
* 增加一个可以让表格饱满的属性
* @method getId,获取选中表格行的ID集合
* @return Array;
*/
(function($){
$.extend($.expr[':'],{
'hasColspan':function(a){
return a.colspan>0;
}
});
$.fn.simpleGrid=$.fn.grid=function(o){
if($(this).data('grid')){
return this;
}else{
var that=$(this);
var grid=new SimpleGrid(that,o);
return this;
}
};
$.fn.changeGrid=function(o){
var that=$(this);
that.next('.simpleGrid').remove();
var grid=new SimpleGrid(that,o);
return this;
};
//public method,重载表格数据
$.fn.reload=function(){
var that=$(this);
if(!that.data('grid')){
return this;
}else{
var grid=that.data('grid');
grid.s={};
grid.form={};
grid.hiddenForm={};
grid.getData();
};
};
$.fn.getId=function(){
var that=$(this),grid=that.data('grid'),id=[];
if(!grid){
return this;
}else{
var selectedCell=grid.getSelectedCell();
$.each(selectedCell,function(i,n){
id.push(n.data('id'));
})
return id;
}
};
//public method,设置选中的行进行操作
$.fn.setSelectedCell=function(type,callback){
var that=$(this),grid=that.data('grid');
if (!grid) {
return this;
}else{
var selectedCell=grid.getSelectedCell();
if(type=="del"){
if(selectedCell.length==0){
alert('至少选择一条数据进行操作!');
return this;
}else{
callback(selectedCell);
return this;
}
}else{
if(selectedCell.length==0||selectedCell.length>1){
alert('只能选择一条数据进行操作!');
return this;
}else{
callback(selectedCell[0]);
return this;
}
}
}
};
//public method,分组进行相关操作
//带修正
$.fn.groupGrid = function(o,colIndex,fun){
var that=$(this);
if(that.data('grid')){
return this;
}
var show=true;
var callbackGroup=function(){
$('.data-table-group-more').unbind('click').click(function(e){
e.stopPropagation();
var id=this.id,
that=this;
if($(this).data('hasLoad')){
if(show){
$('.data-table-body tr').each(function(){
if($(this).attr('rel')==id){
$(this).hide();
}
});
$(that).removeClass('data-table-group-less');
show=false;
}else{
$('.data-table-body tr').each(function(){
if($(this).attr('rel')==id){
$(this).show();
}
});
$(that).addClass('data-table-group-less');
show=true;
}
}else{
if($.isFunction(fun)){
fun(this);
$(this).addClass('data-table-group-less');
}
$(this).data('hasLoad',true);
}
});
};
///var grid=that.data('grid'),
// o=that.data('config'),
var colModel=o.colModel;
$.extend(colModel[colIndex],{
format:function(val){
return '<span class="data-table-group-more">+</span>'+'<label>'+val+'</label>';
}
});
o.callback.push(callbackGroup);
that.grid(o);
return this;
};
//保持相关参数进行表格的刷新
$.fn.keepGrid=function(){
var that=$(this),grid=that.data('grid'),o=that.data('config');
if(!grid){
return this;
}else{
o.currentPage=grid.getCurrentPage();
grid.getData();
}
};
$.fn.getThLength=function(){
var that=$(this),grid=that.data('grid'),o=that.data('config');
if(!grid){
return this;
}else{
return grid.getThLength();
}
};
var Overlay = function(el){
var divLoading;
el = $(el);
var init = function(){
var width = el.width();
var height = el.height();
var offset = el.offset();
divLoading = $('<div/>').css({
'background': '#fff',
'opacity': 0.8,
'width': width,
'height': height,
top: offset.top,
left: offset.left,
'position': 'absolute'
}).addClass('data-table-overlay').appendTo(document.body);
var spanLoading = $('<div>').addClass('data-table-loading').appendTo(divLoading);
var spanWidth = spanLoading.width(), spanHeight = spanLoading.height();
spanLoading.css({
left: (width - spanWidth) / 2,
top: (height - spanHeight) / 2
});
};
return {
init: init,
uninit: function(){
$('.data-table-overlay').remove();
}
};
};
var SimpleGrid=function(data,config){
var t=data;
//t.hide();
var defaults = {
//数据响应的url
url: '',
/**
* 期望返回的数据格式
* html,json,xml
*/
dataType: 'json',
/**
* 请求的页码
*
*/
currentPage: 1,
/**
* 每页请求的数据量
*/
pageSize: 50,
/**
* 发送到服务器的额外的参数
*/
param: {},
pagerShow: 8,
// checkboxEvent: false,
// radioEvent: false,
// pager: '.data-table-footer',
/**
* 构建工具栏上的按钮,数据应该是以下格式
* //string,function,string
* [
* {name:"",event:"",icon:""}
* ]
*/
buttons: {},
// width: [],
/****************************************************************************************
* 如果是多表头的情况,colModel应该是下面的格式
* //string,string,boolean,function,number,number,boolean,number(string)
* [[
* {display:'',name:'',sortable:'',format:'',rowspan:'',colspan:'',checkbox:false,width:""}
* ],
* [
* {display:'',name:'',sortable:'',format:'',rowspan:'',colspan:'',checkbox:false,width:""}
* ]]
* ***************************************************************************************
* 如果是单表头的情况,colModel应该是下面的格式
* [{
* display:'',name:'',sortable:'',format:'',rowspan:'',colspan:'',checkbox:false,width:""
* },{
* display:'',name:'',sortable:'',format:'',rowspan:'',colspan:'',checkbox:false.width:""
* }]
* 判断是多列还是单列,只需判断其子元素是数组还是对象即可
* ****************************************************************************************
* 为了可以转换普通的table到simpleGrid,需要将负责解析的方法与构建表头的方法分离开。
* 而且其中为DOM绑定的事件也应该分离开。
* 为了减少工作量,我们可以将表头构建为带有自定义标记的HTML,然后用负责解析的方法将其转换为simpleGrid
* 为了实现多数据源。需要将getData分离
* 添加一个独立的方法,负责向grid中增加数据
*/
colModel: [],
/**
* 如果配置了固定位置的列,其视图应该分开
* 每一个视图都应该有data-table-header,data-table-body,data-table-footer
* **************************************************************************************
* 我们应该让右侧的视图overflow:auto
* 这样左侧的视图会在右侧视图滚动的时候固定
* 而右侧的视图在上下滚动的时候应该动态改变左侧视图的scrollTop,以便滚动时保持一致
* fixCol的格式与colModel一致
*/
fixedCol:[],
fix:false,
fixParent:false,
//scroll: true,
simpleSearch: true,
simpleSearchKey:[{'name':'name','type':'input'}],
complexSearch: false,
complexSearchForm: '',
hiddenForm: '',
pagination:true,
pagerStyle: 'line',
totalPage: '',
fixHeight: 200,
colDrag: false,
colResize: true,
fixWidth:true,
header:true,
showOrHideCol: true,//待修正
dblclick:function(){
},
callback: function(){
},
onError: function(){
}
};
var classConfig = {
toolsClass: 'data-table-tools',
viewClass:'data-table-views',
headerClass: 'data-table-header',
bodyClass: 'data-table-body',
footerClass: 'data-table-footer',
tdHoverClass: 'td-hover-class',
trClickClass: 'tr-click-class',
oddClass: 'data-table-odd',
evenClass: 'data-table-even',
highlightClass: 'data-table-hightlight',
buttonClass: 'simple-button',
simpleSearchDivClass: 'simpleSearchDiv',
complexSearchDivClass: 'complexSearchDiv',
sortableHoverASCClass: 'sortableHoverASC',
sortableHoverDESCClass: 'sortableHoverDESC'
};
var o = $.extend({}, defaults, classConfig, config);
var grid={
multiple:false,
hiddenForm:{},
g:{
tableHeader:[]
},//grid存储器
s:{},//排序存储器sortManage
d:{
colDrag:false,
proxy: $('<div/>').addClass('proxy'),
resizeProxy:$('<div/>').addClass('resizeProxy')
},//拖放存储器dragManage
//初始化函数
init:function(){
var s=this;
s.buildGridToolBar();
s.buildGridBody();
s.buildGridPager();
s.parseHeader();
var simpleGrid=$('<div/>').addClass('simpleGrid');
simpleGrid.append(s.g.gridTools).append(s.g.gridBody).append(s.g.gridPager);
s.g.simpleGrid=simpleGrid;
t.after(simpleGrid);
t.empty().hide();
t.grid=grid;
t.o=o;
s.getData();
},
getSelectedCell:function(){
var s=this,selectedCell=[];
$(':checkbox',s.g.gridView1).each(function(){
if($(this).attr('checked')){
var tr=$(this).parents('tr');
selectedCell.push(tr);
}
});
return selectedCell;
},
getThLength:function(){
return $('.data-table-body tr').eq(0).find('td').length;
},
fixAll:function(){
var s=this;
var fullPageGrid=function(){
var height=$('table',s.g.gridView2).eq(0).outerHeight();
$('table',s.g.gridView1).eq(0).height(height);
var dataView2Width=$('.data-table-body',s.g.gridView2).width();
$('.data-table-header',s.g.gridView2).width(dataView2Width);
var pageHeight=document.documentElement.clientHeight;
var toolsHeight=0,footerHeight=0;
if(o.header){
toolsHeight=s.g.gridTools.height();
}
if(o.pagination){
footerHeight=s.g.gridPager.height();
}
var headHeight=s.g.tableHeader[0].height();
var parentHeight=s.g.simpleGrid.parent().height();
if(o.fix){
$('.data-table-body',s.g.gridBody).height(pageHeight-toolsHeight-footerHeight-headHeight-20);
}
if(o.fixParent){
$('.data-table-body',s.g.gridBody).height(parentHeight-toolsHeight-footerHeight-headHeight-20);
}
//var width=$('.data-table-body table',s.g.gridView2).outerWidth();
//$('.data-table-body',s.g.gridView2).width(width);
};
// // fullPageGrid();
// $(window).resize(fullPageGrid);
setInterval(fullPageGrid,100);
if(o.fixWidth){
var fixWidthFun=function(){
var width=s.g.simpleGrid.width()-45,perWidth=width/s.g.gridWidthTotal;
var tr1=$('tr',s.g.gridView1);
var cols1=s.getHeaderTh(tr1);
$(cols1).each(function(i){
var tw=$(this).find('.th-wapper');
fwidth=parseInt(tw.data('width')*perWidth);
tw.width(fwidth);
$('.data-table-body tr',s.g.gridView1).each(function(){
$('td',this).eq(i).find('.td-text').width(fwidth);
});
});
var tr2=$('tr',s.g.gridView2);
var cols=s.getHeaderTh(tr2);
$(cols).each(function(i){
var tw=$(this).find('.th-wapper');
fwidth=parseInt(tw.data('width')*perWidth);
tw.width(fwidth);
$('.data-table-body tr',s.g.gridView2).each(function(){
$('td',this).eq(i).find('.td-text').width(fwidth);
});
});
};
fixWidthFun();
$(window).resize(fixWidthFun);
}
return this;
},
tdEvent:function(){
var s=this;
$('td',s.g.gridBody).hover(function(){
var index=$(this).attr('index');
$(this).addClass(o.tdHoverClass);
$('td[index="'+index+'"]',s.g.gridBody).addClass(o.tdHoverClass);
},function(){
var index=$(this).attr('index');
$(this).removeClass(o.tdHoverClass);
$('td[index="'+index+'"]',s.g.gridBody).removeClass(o.tdHoverClass);
}).click(function(e){
if(e.target.nodeName=="INPUT"){
return;
}
var index=$(this).attr('index');
var checkbox=$('.data-table-body tr',s.g.gridBody).eq(index).find(':checkbox');
if(checkbox.attr('checked')){
checkbox.attr('checked','');
$('td[index="'+index+'"]',s.g.gridBody).removeClass(o.trClickClass);
checkbox.trigger('change');
}else{
checkbox.attr('checked','checked');
$('td[index="'+index+'"]',s.g.gridBody).addClass(o.trClickClass);
checkbox.trigger('change');
}
});
$('.data-table-body :checkbox',s.g.gridBody).change(function(){
var index=$(this).parents('td').attr('index');
if($(this).attr('checked')){
$('td[index="'+index+'"]',s.g.gridBody).addClass(o.trClickClass);
}else{
$('td[index="'+index+'"]',s.g.gridBody).removeClass(o.trClickClass);
}
});
return s;
},
/**
* 负责将colModel转换成HTML
*/
buildTableHeader:function(model){
var gridHeader,s=this;
gridHeader = $('<div/>').addClass(o.headerClass).css('position','relative').append('<div class="data-table-header-inner"><table><thead></thead></table></div>');
//css(relative)
if(model){
var trs=$('<tr/>'),width=0;
$.each(model,function(index,item){
//判断是多表头还是单表头
if($.isArray(item)){
s.multiple=true;
var tr=$('<tr/>');
$.each(item,function(i,n){
var th=s.setThElement(n);
if(typeof n.width == 'number'){
width+=n.width;
}
// $(th).attr('col-index',index);
tr.append(th);
});
$('thead',gridHeader).append(tr);
}else{//is object 单表头
if(typeof item.width == 'number'){
width+=item.width;
}
var th=s.setThElement(item);
// $(th).attr('col-index',index);
trs.append(th);
$('thead',gridHeader).append(trs);
}
});
s.g.gridWidthTotal=width;
}
s.g.tableHeader.push(gridHeader);
return gridHeader;
},
//如果table没有表头将colModel转换成表头
setThElement:function(item){
var s=this;
var th=document.createElement('th');
if(item.name){
$(th).attr('name',item.name);
}
if(item.rowspan){
$(th).attr('rowspan',item.rowspan);
}
if(item.checkbox){
$(th).append('<div style="width:20px;"><input type="checkbox" name="'+item.name+'"/></div>').attr('type','checkbox');
$(':checkbox',th).change(function(){
var that=$(this);
if(that.attr('checked')){
$('.data-table-body :checkbox',s.g.gridBody).attr('checked','checked');
}else{
$('.data-table-body :checkbox',s.g.gridBody).attr('checked','');
}
$('.data-table-body :checkbox',s.g.gridBody).change();
});
return th;
}
if(item.radio){
$(th).append('<div style="width:20px;"></div>').width(20).attr('type','radio');
return th;
}
if(item.display){
$(th).append('<div class="th-wapper"></div>')
$('.th-wapper', th).append('<div class="text">' + item.display + '</div>').append('<span></span>');
}
if(item.format){
$(th).data('format',item.format);
}
if(item.sortable){
$(th).attr('sortable',item.sortable);
}
if(item.width){
if(o.fixWidth){
$('.th-wapper',th).data('width',item.width);
}else{
$('.th-wapper',th).width(item.width);
}
}
if(item.colspan){
$(th).attr('colspan',item.colspan);
$(th).attr('colResize','disabled');
$('.th-wapper',th).data('width','auto');
$('.th-wapper',th).width('auto');
//th.colspan=item.colspan
}
if(item.align){
$(th).attr('tdAlign',item.align);
}
return th;
},
/**
* 解析带有自定义标记的HTML
* 顺带绑定事件
*/
parseHeader:function(){
var s=this,gh=s.g.tableHeader;
if(gh){
$.each(gh,function(i,n){
$('th',n).each(function(){
var that=this;
if($(that).attr('sortable')){
//$(s.s).extend({
// sortName:that.name,
// dir:'asc'
//});
$(that).data('order','asc');
$('.text',that).click(function(){
s.w.sort(that);
});
}
$(that)
.mouseover(function(){
if(s.d.colDrag){
s.d.to=this;
$(this).addClass('data-table-drag-over');
}else if(!s.d.colResize){
$(this).addClass('data-table-over');
}
})
.mouseout(function(){
$(this).removeClass();
});
if(o.colDrag){
$(that).mousedown(function(e){
s.d.colDrag=true;
s.w.drag(e,'colDrag');
});
}
if(o.colResize){
$('span', that).mousedown(function(e){
if($(that).attr('colresize')=="disabled"){
return;
}
e.stopPropagation();
s.w.drag(e, 'colResize');
});
}
});
});
}
},
getHeaderTh:function(tr){
var cols=[],index=0,subIndex=0,totalIndex=0;
tr.eq(0).find('th').each(function(i){
if($(this).attr('colspan')>1){
$(this).attr('col-index',index);
index++;
}
});
tr.eq(0).find('th').each(function(){
if($(this).attr('colspan')>1&&$(this).attr('col-index')>-1){
getsubCol($(this));
}else{
cols.push($(this));
}
});
function getsubCol(el){
var colIndex=el.attr('col-index');
colspan=el.attr('colspan');
totalIndex=totalIndex*1+colspan*1;
for(var i=subIndex;i<totalIndex;i++){
cols.push(tr.eq(1).find('th').eq(i));
}
subIndex=subIndex*1+colspan*1;
}
return cols;
},
buildGridToolBar:function(){
var s = this;
if(o.header){
var gridTools = $('<div/>').addClass(o.toolsClass);
if (o.buttons != null) {
$.each(o.buttons, function(i, n){
var divBtn = $('<div/>').addClass(o.buttonClass).append('<span class="simple-button-text">' + n.name + '</span>');
if ($.isFunction(n.event)) {
divBtn.click(n.event).hover(function(){
$(this).addClass('simple-button-hover');
},function(){
$(this).removeClass('simple-button-hover');
});
}
if(n.disabled){
divBtn.addClass('simple-button-disabled');
// divBtn.unbind();
// var condition = n.condition();
// console.log(condition)
//if(condition){
// divBtn.click(n.event);
// divBtn.removeClass('simple-button-disabled');
// }
}
if (n.icon != null) {
divBtn.prepend('<span class="simple-button-icon ' + n.icon + '"></span>');
}
gridTools.append(divBtn);
});
}
//简单单字段查询
if (o.simpleSearch) {
var divSearch = $('<div/>').addClass('simpleSearchFormDiv');
$.each(o.simpleSearchKey,function(i,n){
if(n.type=="input"){
var input = $('<input/>').attr('name', n.name).addClass('text');
divSearch.append(input);
}
});
//simpleSearchKey = o.simpleSearchKey || 'name';
var a = $('<a/>').addClass('simpleSearch').html('查询');
divSearch.append(a);
a.click(function(){
s.form = $.json(divSearch[0]);
s.getData();
});
gridTools.append(divSearch);
}
if(o.complexSearch){
$('a.query',s.g.simpleGrid).click(function(){
s.form=$.json($(o.complexSearchForm));
s.getData();
});
}
s.g.gridTools = gridTools;
return gridTools;
}
},
buildGridBody:function(){
var s=this;
s.buildGridView();
//如果配置了colModel
if(o.colModel){
var viewThead2=s.buildTableHeader(o.colModel);
s.g.gridView2.append(viewThead2);
s.g.gridView2.append('<div class="data-table-body"><table><tbody></tbody</table></div>');
if(o.fixCol){
var viewThead1=s.buildTableHeader(o.fixCol);
s.g.gridView1.append(viewThead1);
s.g.gridView1.append('<div class="data-table-body"><div class="data-table-body-innder"><table><tbody></tbody</table></div></div>');
}else{
s.g.gridView1.width(0).height(0);
}
}
//如果都没有配置从thead里找
else{
if($('thead',t)[0]!=null){
s.g.gridView2.append('<div class="'+o.headerClass+'"></div>')
.find('.'+o.footerClass).append($('thead',t));
}
else if($('tbody',t)[0!=null]){
s.g.gridView2.append('<div class="data-table-body"></div>')
.find('.data-table-body').append($('tbody',t));
}
}
$('.data-table-body',s.g.gridBody).height(o.fixHeight);
$('.data-table-body',s.g.gridView2).scroll(function(){
var scrollTop=this.scrollTop;
$('.data-table-body',s.g.gridView1).scrollTop(scrollTop);
var scrollLeft=this.scrollLeft;
$('.data-table-header',s.g.gridView2).scrollLeft(scrollLeft);
var dataTableBodyView2Width=$('.data-table-body table',s.g.gridView2).width();
//$('.data-table-header table',s.g.gridView2).width(dataTableBodyView2Width-36);
});
},
buildGridView:function(){
var s=this;
var divBody=$('<div/>').addClass('data-table-wapper');
var divView1=$('<div/>').addClass('data-table-view1');
var divView2=$('<div/>').addClass('data-table-view2');
divBody.append(divView1).append(divView2);
s.g.gridView1=divView1;
s.g.gridView2=divView2;
s.g.gridBody=divBody;
},
buildGridPager:function(){
if (o.pagination) {
var s = this;
var p = $('<div/>').addClass(o.footerClass).append('<div class="data-table-pager"></div><div class="data-table-info"></div>');
var first = $('<a/>').addClass('page-first pageA'), prev = $('<a/>').addClass('page-prev pageA'), next = $('<a/>').addClass('page-next pageA'), last = $('<a/>').addClass('page-last pageA');
$('.data-table-pager',p).prepend(first).prepend(prev).append(next).append(last);
s.g.gridPager = p;
return p;
}
},
mixData: function(){
var s = this;
s.hiddenForm=$.json(o.hiddenForm);
var pdata = $.extend({}, {
"currentPage": o.currentPage,
"pageSize": o.pageSize
}, o.param);
// if (o.type == 'action') {
// pdata = $.extend({}, pdata, {
// currentPage: s.getCurrentPage()
// });
// }
var sdata = $.extend({}, pdata,s.hiddenForm, s.s, s.form);
return sdata;
},
addData:function(data){
var s=this;
s.parseJSON(data);
},
getData:function(){
var s = this, data = s.mixData();
$.ajax({
url: o.url,
data: data,
type: 'post',
cache:false,
beforeSend: function(){
// if (datacontainer.find('tr').length >= 1) {
Overlay(s.g.simpleGrid).init();
//.init();
//}
},
// dataType: o.dataType,
success: function(datas){
s.addData(datas);
Overlay(s.g.simpleGrid).uninit();
s.fixAll().tdEvent();
setTimeout(function(){
if($.isFunction(o.callback)){
o.callback();
}else if($.isArray(o.callback)){
$.each(o.callback,function(i,k){
k();
});
}
},200)
},
error: function(data){
alert('返回的数据格式不对或者服务器繁忙!');
}
});
},
parseJSON:function(data){
var s = this;
//待修正
// datacontainer.empty();
$('tbody',s.g.gridBody).empty();
$('.noData').remove();
if (!$.isArray(data)) {
data = eval('(' + data + ')');
data=data[0];
}
if(data.length<1){
s.g.gridBody.find('.data-table-body').append('<div class="noData"><div>没有任何数据显示!</div></div>');
return false;
}
var totalPage = data.totalPage,
currentPage = data.currentPage,
pageSize = data.pageSize,
totalCount=data.totalCount,
data = data.list;
s.g.totalCount=totalCount;
var pageInfo=pageSize*(currentPage-1)+1*1;
pageInfo2=pageSize*currentPage>totalCount?totalCount:pageSize*currentPage;
$('.data-table-info',s.g.gridPager).html('共有'+totalCount+'条数据,当前显示'+pageInfo+'~'+pageInfo2+'条');
$.each(data,function(index,item){
var tr = $('<tr/>').dblclick(o.dblclick);
var thView1Tr=$('.data-table-header tr',s.g.gridView1);
var cols=s.getHeaderTh(thView1Tr);
$(cols).each(function(){
var that = $(this);
if(that.attr('type')=="checkbox"){
var td=$('<td/>').html('<div style="width:20px;text-align:center;"><input type="checkbox" name="'+that.attr('name')+'"/></div>').attr('index',index);
tr.append(td);
}
if(that.attr('type')=="radio"){
var td=$('<td/>').html('<div style="width:20px;text-align:center;"><input type="radio" name="'+that.attr('name')+'" class="data-table-radio"/></div>').attr('index',index);
tr.append(td);
}
$.each(item, function(key, value){
if (key=="id"){
tr.data('id',value);
}
if (that.attr('name') == key) {
if ($.isFunction(that.data('format'))) {
if(value=='null'){
value="";
}
value = that.data('format').call(this, value);
}
var td = $('<td/>').html('<div class="td-text">' + value + '</div>').attr({
'name': that.attr('name'),
'index':index,
'align':that.attr('tdalign')
});
tr.append(td);
}
});
});
$('.data-table-body tbody',s.g.gridView1).append(tr);
var tr2= $('<tr/>').dblclick(o.dblclick);
var thView2Tr=$('.data-table-header tr',s.g.gridView2);
var cols2=s.getHeaderTh(thView2Tr);
$(cols2).each(function(){
var that = $(this);
if(that.attr('type')=="checkbox"){
var td=$('<td/>').html('<div style="width:20px;text-align:center;"><input type="checkbox" name="'+that.attr('name')+'"/></div>').attr('index',index);
tr2.append(td);
}
if(that.attr('type')=="radio"){
var td=$('<td/>').html('<div style="width:20px;text-align:center;"><input type="radio" name="'+that.attr('name')+'" class="data-table-radio"/></div>').attr('index',index);
tr2.append(td);
}
$.each(item, function(key, value){
if (key=="id"){
tr2.data('id',value);
}
if (that.attr('name') == key) {
if ($.isFunction(that.data('format'))) {
if(value=='null'){
value="";
}
value = that.data('format').call(this, value);
}
var td = $('<td/>').html('<div class="td-text">' + value + '</div>').attr({
'name': that.attr('name'),
'index':index,
'align':that.attr('tdalign')
});
tr2.append(td);
}
});
});
$('.data-table-body tbody',s.g.gridView2).append(tr2);
});
s.setPageStyle(o.pagerStyle, o.pagerShow, totalPage, currentPage);
},
setPageStyle: function(style, pageshow, totalPage, currentPage){
if (style == "click") {
// 待修正
}
if (style == "line") {
line.setLine(totalPage, currentPage, pageshow);
}
},
getCurrentPage: function(){
return this.g.currentPage;
},
w: {
drag: function(e, type){
var s = this, d = grid.d,w=grid.w;
if (type == 'colDrag') {
d.from = $(e.currentTarget)[0];
$(d.from).addClass("drag");
}
if (type == 'colResize') {
var x = $(e.target).offset().left;
// console.log(e.target)
d.colLeft = x;
d.colWidth = $(e.target).parents('th').width();
d.target = $(e.target).parents('th');
d.colResize = true;//判断是否是拖放的标志
}
$(document).mousemove(function(e){
w.dragmove(e, type);
});
$(document).mouseup(function(e){
w.dragstop(e, type);
});
},
dragmove: function(e, type){
var s = this, d= grid.d, w = grid.w;
if (type == "colDrag") {
var proxy = d.proxy;
//console.log(proxy)
proxy.css({
left: e.pageX + 20,
top: e.pageY + 10
}).appendTo(document.body).show();
proxy.html($(d.from).html())
}
else
if (type == "colResize") {
$(document.body).css('cursor', 'col-resize');
d.resizeProxy.css({
width:0,
'border-left':'1px solid #cc0000',
height:grid.g.gridBody.height(),
'position':'absolute',
'top':0,
'left':e.pageX-grid.g.gridBody.offset().left
}).appendTo(grid.g.gridBody).show();
}
w.noselect(document.body);
},
dragstop: function(e, type){
var s=grid;that=this;
// console.log(grid)
$(document).unbind('mousemove').unbind('mouseup');
if(type=="colDrag"){
grid.d.proxy.hide();
}else if(type=="colResize"){
$(document.body).css('cursor','default');
grid.d.resizeProxy.hide();
var addWidth=parseInt(e.pageX-grid.d.colLeft);
var table2=$('.data-table-body table',s.g.gridView2),table2Width=table2.width();
//console.log(grid.d)
//console.log(addWidth)
// $('.th-wapper',grid.d.target).width(grid.d.colWidth+addWidth);
var thName=grid.d.target.attr('name');
var select='.data-table-body table';
that.setWidth(select,s.g.gridView2,thName,addWidth);
// that.setWidth(select,s.g.gridView1,thName,addWidth);
// $('td[name="'+thName+'"] .td-text',s.g.gridView2).width(grid.d.target.width());
table2.width(table2Width+addWidth);
}
},
setWidth:function(select,context,thName,addWidth){
var table=$(select,context),tableWidth=table.width();
$('.th-wapper',grid.d.target).width(grid.d.colWidth+addWidth);
$('td[name="'+thName+'"] .td-text').width(grid.d.target.width());
//table.width(tableWidth+addWidth);
},
//拖动过程中不选中文字
noselect: function(target){
if (typeof target.onselectstart != "undefined") //IE route
target.onselectstart = function(){
return false
}
else
if (typeof target.style.MozUserSelect != "undefined") //Firefox route
target.style.MozUserSelect = "none"
else //All other route (ie: Opera)
target.onmousedown = function(){
return false
}
//target.style.cursor = "default"
},
sort: function(el){
var g = grid,el=$(el);
// $('.text', g.g.gridHeader).removeClass();
if (el.data('order') == 'asc') {
$.extend(g.s, {
sort: el.attr('name'),
dir: 'desc'
});
el.data('order', 'desc')
el.find('.text').removeClass('asc').addClass('desc');
g.getData();
}
else {
$.extend(g.s, {
sort: el.attr('name'),
dir: 'asc'
});
el.data('order', 'asc')
el.find('.text').removeClass('desc').addClass('asc');
g.getData();
}
}
}
};
var line = {
setLine: function(totalPage, currentPage, pageshow){
grid.g.currentPage = currentPage;
var g = grid,page = $('.data-table-pager',g.g.gridPager);
page.empty();
var s = this, displayPage = s.getLimit(pageshow, totalPage, currentPage);
// console.log(displayPage)
for (var i = displayPage.start; i <= displayPage.end; i++) {
var a = $('<a/>').html('<span>' + i + '</span>').addClass('pageA').bind('click', function(){
//wait;
//console.log('ccc')
o.currentPage = g.g.currentPage = $(this).text();
grid.getData();
});
//当前页
if (i == currentPage) {
a.addClass('pageActive');
}
page.append(a);
}
var pageCount = $('<a/>').html('<span>' + currentPage + '/' + totalPage + '</span>').addClass('pageA');
var first = $('<a/>').html('<span>首页</span>').addClass('pageA').data('first', 'first').click(function(){
o.currentPage = g.g.currentPage = 1;
grid.getData();
});
var prev = $('<a/>').html('<span>上一页</span>').addClass('pageA').data('prev', 'prev').click(function(){
var currentPage = grid.getCurrentPage();
o.currentPage = g.g.currentPage = currentPage - 1 < 0 ? totalPage : currentPage - 1;//如果当前页为首页,上一页返回到最后一页
grid.getData();
});
var next = $('<a/>').html('<span>下一页</span>').addClass('pageA').data('next', 'next').click(function(){
var currentPage = grid.getCurrentPage();
// console.log(currentPage)
o.currentPage = g.g.currentPage = currentPage * 1 + 1 > totalPage ? totalPage : currentPage * 1 + 1;//如果当前页为末页,
grid.getData();
});
var last = $('<a/>').html('<span>末页</span>').addClass('pageA').data('last', 'last').click(function(){
o.currentPage = g.g.currentPage = totalPage;
grid.getData();
});
page.prepend(prev).prepend(first).prepend(pageCount).append(next).append(last);
},
getLimit: function(pageShow, totalPage, start){
// var start = parseInt(o.pager.find('a.pageActive').text());
start = parseInt(start - pageShow / 2) < 0 ? 1 : parseInt(start - pageShow / 2);
if (start + o.pageShow > totalPage) {
start = totalPage - pageShow < 0 ? 1 : totalPage - pageShow;
}
var end = (start + pageShow) > totalPage ? totalPage : start + pageShow;
return {
start: start,
end: end
}
}
}
grid.init();
t.data('grid',grid);
t.data('config',o);
};
$.json = function(form){
//判断是否有序列化的东东
if (!$(form).html() || $(form).html() == null || $.trim($(form).html()) == "") {
return null;
}
var formEl = $(form).find('input[type="text"],input[type="hidden"]');
var formselect = $(form).find('select');
var json = "{";
if (formEl.length > 1) {
for (var i = 0; i < formEl.length - 1; i++) {
var name = formEl.eq(i).attr('name');
var val = "'" + formEl.eq(i).val() + "'";
json += name;
json += ":";
json += val;
json += ",";
}
}
var lname = formEl.eq(formEl.length - 1).attr('name');
var lval = "'" + formEl.eq(formEl.length - 1).val() + "'";
json += lname;
json += ":";
json += lval;
if (formselect) {
json += ",";
if (formselect.length > 1) {
for (var i = 0; i < formselect.length - 1; i++) {
var name = formselect.eq(i).attr('name');
var val = "'" + formselect.eq(i).val() + "'";
json += name;
json += ":";
json += val;
json += ",";
}
var lname = formselect.eq(formselect.length - 1).attr('name');
var lval = "'" + formselect.eq(formselect.length - 1).val() + "'";
json += lname;
json += ":";
json += lval;
}
}
json += "}";
var jsonObj = eval("(" + json + ")");
return jsonObj;
};
})(jQuery);
关于表格控件,我觉得最重要的就是数据的解析~~其他的功能都是附加的。
数据怎么样才能显示在正确的位置呢~~尤其是多表头的情况,更加棘手~
下面是我的解决方法
只要按照表头顺序去对比数据就可以。关键就是对表头的重排序~
首先观察表格头部的结构,按照顺序遍历,并将其push到新的对象中~当发现有colspan>1(因为默认=1)的表头,找到其子列,并将它们push到新的对象中~
这样得到的新对象便是排好顺序的表头~(这部分代码没有优化!!)
getHeaderTh:function(tr){
var cols=[],index=0,subIndex=0,totalIndex=0;
tr.eq(0).find('th').each(function(i){
if($(this).attr('colspan')>1){
$(this).attr('col-index',index);
index++;
}
});
tr.eq(0).find('th').each(function(){
if($(this).attr('colspan')>1&&$(this).attr('col-index')>-1){
getsubCol($(this));
}else{
cols.push($(this));
}
});
function getsubCol(el){
var colIndex=el.attr('col-index');
colspan=el.attr('colspan');
totalIndex=totalIndex*1+colspan*1;
for(var i=subIndex;i<totalIndex;i++){
cols.push(tr.eq(1).find('th').eq(i));
}
subIndex=subIndex*1+colspan*1;
}
return cols;
}
未完待续(。。。)工作了~~