EasyUI datagrid实现翻页客户端保存checkbox状态

1、首先设置datagrid属性的idField主键,这里假如为id,若idField为其他的,记住下面的代码里的 id也要做相应的修改。

2、建立一个全局的javascript数组var checkedItems = [],用来存放选中checkbox的值。

3、核心方法,addcheckItem()removeAllItem(rows)removeSingleItem(rowIndex, rowData)当选中或者取消checkbox时触发。

  用来将checkbox的主键值保存在checkedItems数组,或者从数组中删除对应的id值,findCheckedItem(ID)这个函数用来查找数组中是否存在checkbox的值,存在则返回id值,不存在则返回-1.

4、什么时候调用这些方法呢?分别在datagridonCheckAll: addcheckItem,onCheck: addcheckItem,onUncheckAll: removeAllItem,onUncheck: removeSingleItem 这四个事件中调用对应的方法。

5、翻页后如何给checkbox赋值呢?关键就在这里,datagrid重写了$.fn.datagrid.defaults.viewonAfterRender事件,因此在datagrid的view事件里绑定这个函数就OK了。onAfterRender事件是当easyui的元素渲染完毕后执行的事件,在这里会调用手写的 ischeckItem 函数来实现对checkbox的赋值!
  
下面为大家贴上实现的具体代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 $("#maingrid").datagrid({ 
idField: 'id',
view: fileview
});

var fileview = $.extend({}, $.fn.datagrid.defaults.view, { onAfterRender: function (target) { ischeckItem(); } });

var checkedItems = [];
function ischeckItem() {
for (var i = 0; i < checkedItems.length; i++) {
$('#maingrid').datagrid('selectRecord', checkedItems[i]); //根据id选中行
}
}

function findCheckedItem(ID) {
for (var i = 0; i < checkedItems.length; i++) {
if (checkedItems[i] == ID) return i;
}
return -1;
}

function addcheckItem() {
var row = $('#maingrid').datagrid('getChecked');
for (var i = 0; i < row.length; i++) {
if (findCheckedItem(row[i].id) == -1) {
checkedItems.push(row[i].id);
}
}
}
function removeAllItem(rows) {

for (var i = 0; i < rows.length; i++) {
var k = findCheckedItem(rows[i].id);
if (k != -1) {
checkedItems.splice(i, 1);
}
}
}
function removeSingleItem(rowIndex, rowData) {
var k = findCheckedItem(rowData.id);
if (k != -1) {
checkedItems.splice(k, 1);
}
}

下面是批量删除的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function destroyItems(items) {
var row = null;
if (items == "list") {
items = checkedItems.join(',');
row = $('#maingrid').datagrid('getSelections');
}
else {
row = items;
}
if (row != null) {
$.messager.confirm('Confirm', '您确定要删除此记录?', function (r) {
if (r) {
$.post(location.href, { id: items, action: "deletelist" }, function (result) {
if (result == "1") {
$('#maingrid').datagrid('reload');
} else {
$.messager.show({
title: 'Error',
msg: result
});
}
});
}
});
}
else { $.messager.alert('-警告-', '请选择至少一条记录才能进行删除', 'info'); }

}

一个小攻城师2014年的总结

今儿是2014的最后一天,我是不是要写点东西总结下自己呢?

2014年一路走过

对于一个北漂的人来说,唉,每年都TMD过的太快了,一线城市的生活就是这么快节奏,就是这么任性!还计划着今年要干什么干什么,却一晃就漂到年底了,猛的醒过来,“fuck,什么都没完成!于是有了下面一幅图的出现”

看完这个段子,大家是不是感觉趟枪了,o(∩_∩)o 哈哈,事实就是这个样子!


说点认真的吧,这年还是收获很多的。
工作上,掌握一些新的技术和一些编程理念,最重要的是自己由后台慢慢转变为一名前端攻城师,接触了angularjs前端框架,后端语言也由asp.net 转变成了 java,遇到问题更加冷静去思考去寻找解决问题的方案。总之呢,时间长了,会突然觉得所谓的大神,所谓的高手 不是他们的技术有多牛,不是他们的学历有多高,而是在工作中日积月累的解决问题的能力,慢慢培养出解决问题的思维方式和编程理念,当然我不否认在此基础之上需要夯实的基础知识!

在说说大部队吧,由开始的十几个人,由于各种原因,走了一批人,来了一批人,来不及感伤,来不及道别,只能快速融入新组建的团队中。然后嘻嘻嘻哈哈开始新产品的规划与开发。很幸运,大家相处很融洽和舒服,我们在朝着共同的目标奋斗着,希望有一天我们的产品能有越来越多的用户!

我呢,是一个不善言谈的人,在人际交际中,不喜欢阿谀奉承,不喜欢勾心斗角,不喜欢拍人马屁,喜欢较真,喜欢说大实话。说到这里,像我这种性格的人也许不适合在当今的社会中生存,更别说什么搞好层级关系,职位提升等等。但随着时间的流逝和自己意志力的流逝,自己总会被周遭所同化,你必须学会阿谀奉承、必须学会拍人马屁、必须学会掩饰自己,必须学会如何处理人际关系,我们必须扮演好在生活中、在工作中的角色,正如 《楚门的世界》 里所反应的,我们每个人都是生活中的演员!

查看更多

highchart 自定义事件插件

highchart 插件之自定义事件

下面是扩展插件的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
(function (HC) {
/*jshint expr:true, boss:true */
var UNDEFINED;
//reseting all events, fired by Highcharts
HC.Chart.prototype.callbacks.push(function (chart) {
var resetAxisEvents = chart.customEvent.resetAxisEvents,
series = chart.series,
serLen = series.length,
xAxis = chart.xAxis,
yAxis = chart.yAxis,
i = 0;

resetAxisEvents(xAxis, 'xAxis', chart);
resetAxisEvents(yAxis, 'yAxis', chart);

for (; i < serLen; i++) {
series[i].update({
customEvents: {
series: series[i].options.events,
point: series[i].options.point.events
},
events: {
click: null
},
point: {
events: {
click: null
}
}
},false);
}

chart.xAxis[0].isDirty = true;
chart.redraw();
});

//custom event body
var customEvent = HC.Chart.prototype.customEvent = function (obj, proto) {
customEvent.add = function (elem, events, obj) {
for (var key in events) {

(function (key) {
if (events.hasOwnProperty(key)) {
if(!elem[key] || elem[key] === UNDEFINED) {
HC.addEvent(elem.element, key, function (e) {
events[key].call(obj, e);
return false;
});
}

elem[key] = true;
}
})(key)

}
};

HC.Chart.prototype.customEvent.resetAxisEvents = function(axis, type, chart) {
var axisLength = axis.length,
userOptions = chart.userOptions,
i = 0,
j = 0,
redraw = false,
customEvents, plotBandsLength, plotLinesLength, plotLines, plotBands,cAxis;

for(;i<axisLength;i++) {

if(type === 'xAxis' && userOptions.xAxis !== UNDEFINED) {

cAxis = HC.splat(userOptions.xAxis);
plotLines = cAxis[i].plotLines;
plotBands = cAxis[i].plotBands;

} else if(type === 'yAxis' && userOptions.yAxis !== UNDEFINED) {

cAxis = HC.splat(userOptions.yAxis);
plotLines = cAxis[i].plotLines;
plotBands = cAxis[i].plotBands;
}

if(plotLines !== UNDEFINED) {
plotLinesLength = plotLines.length;

for(j=0;j<plotLinesLength;j++){
var t = plotLines[j].events;
if(t) {
plotLines[j].customEvents = t;
plotLines[j].events = null;
}
};

redraw = true;
}

if(plotBands !== UNDEFINED) {
plotBandsLength = plotBands.length;

for(j=0;j<plotBandsLength;j++) {
var t = plotBands[j].events;
if(t) {
plotBands[j].customEvents = t;
plotBands[j].events = null;
}
};

redraw = true;
}

if(redraw) {
chart.yAxis[i].update({
plotLines: plotLines,
plotBands: plotBands
},false);
}
};
};


HC.wrap(obj, proto, function (proceed) {
var events,
element,
eventsPoint,
elementPoint,
op;

//call default actions
proceed.apply(this, Array.prototype.slice.call(arguments, 1));

//switch on object
switch (proto) {
case 'addLabel':
events = this.axis.options.labels.events;
element = this.label;
break;
case 'setTitle':
events = this.options.title.events;
element = this.title;
break;
case 'drawDataLabels':
events = this.dataLabelsGroup ? this.options.dataLabels.events : null;
element = this.dataLabelsGroup ? this.dataLabelsGroup : null;
break;
case 'render':
if (this.axisTitle) {
events = this.options.title.events;
element = this.axisTitle;
}
if (this.options.value || this.options.from) {
events = this.options.customEvents;
element = this.svgElem;
}
break;
case 'drawPoints':
op = this.options;
events = op.customEvents ? op.customEvents.series : op,
element = this.group;
eventsPoint = op.customEvents ? op.customEvents.point : op.point.events;
elementPoint = this.points;
break;
case 'renderItem':
events = this.options.itemEvents;
element = this.group;
break;
}


if (events || eventsPoint) {

if (eventsPoint) {
var len = elementPoint.length
j = 0;

for (; j < len; j++) {
var elemPoint = elementPoint[j].graphic;

if (elementPoint[j].y && elemPoint !== UNDEFINED) {
customEvent.add(elemPoint, eventsPoint, elementPoint[j]);
}
}
}

customEvent.add(element, events, this);
}


});
};

//labels
customEvent(HC.Tick.prototype, 'addLabel');

//axis
//title
customEvent(HC.Axis.prototype, 'render');
//plotbands + plotlines
customEvent(HC.PlotLineOrBand.prototype, 'render');

//series events & point events
customEvent(HC.Series.prototype, 'drawPoints');
customEvent(HC.seriesTypes.column.prototype, 'drawPoints');
customEvent(HC.seriesTypes.pie.prototype, 'drawPoints');

//datalabels events
customEvent(HC.Series.prototype, 'drawDataLabels');
customEvent(HC.seriesTypes.column.prototype, 'drawDataLabels');
customEvent(HC.seriesTypes.pie.prototype, 'drawDataLabels');

//title events
customEvent(HC.Chart.prototype, 'setTitle');

//legend items
customEvent(HC.Legend.prototype, 'renderItem');

//bubble charts
if(HC.seriesTypes.bubble) {
customEvent(HC.seriesTypes.bubble.prototype, 'drawPoints');
customEvent(HC.seriesTypes.bubble.prototype, 'drawDataLabels');
}

})(Highcharts);

查看更多

highchart legend 可拖拽扩展

highchart 插件之legend 拖拽扩展

下面是扩展插件的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
(function (H) {
var addEvent = H.addEvent;

H.wrap(H.Chart.prototype, 'init', function (proceed) {
proceed.apply(this, Array.prototype.slice.call(arguments, 1));

var chart = this,
legend = chart.legend,
box = legend.box,
options = legend.options,
isDragging,
downX,
downY,
optionsX,
optionsY,
currentX,
currentY;
if (options.draggable) {
box.css({
cursor: 'move'
});
addEvent(box.element, 'mousedown', function (e) {
e = chart.pointer.normalize(e);
downX = e.chartX;
downY = e.chartY;
optionsX = options.x;
optionsY = options.y;
currentX = legend.group.attr('translateX');
currentY = legend.group.attr('translateY');
isDragging = true;
});
addEvent(chart.container, 'mousemove', function (e) {
if (isDragging) {
e = chart.pointer.normalize(e);
var draggedX = e.chartX - downX,
draggedY = e.chartY - downY;

options.x = optionsX + draggedX;
options.y = optionsY + draggedY;

// Do the move is we're inside the chart
if (currentX + draggedX > 0 && currentX + draggedX + legend.legendWidth < chart.chartWidth && currentY + draggedY > 0 && currentY + draggedY + legend.legendHeight < chart.chartHeight) {
legend.group.placed = false; // prevent animation
legend.group.align(H.extend({
width: legend.legendWidth,
height: legend.legendHeight
}, options), true, 'spacingBox');
}
if (chart.pointer.selectionMarker) {
chart.pointer.selectionMarker = chart.pointer.selectionMarker.destroy();
}

}
});
addEvent(document, 'mouseup', function () {
isDragging = false;
});
}
});
}(Highcharts));

前端初始化代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line'
},
title: {
text: 'Highcharts Draggable Legend Demo'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
labels: {
zIndex: 6
}
},
yAxis: {
title: {
text: 'Temperature (°C)'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}],
labels: {
zIndex: 6
}
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' + this.x + ': ' + this.y + '°C';
}
},
legend: {
layout: 'vertical',
backgroundColor: 'white',
align: 'right',
verticalAlign: 'top',
y: 165,
x: -220,
borderWidth: 1,
borderRadius: 5,

floating: true,
draggable: true,
zIndex: 20
},
series: [{
name: 'Tokyo',
data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
}, {
name: 'New York',
data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
}, {
name: 'Berlin',
data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
}, {
name: 'London',
data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8]
}]
});
});

效果图

demo在线预览

Highcharts部分图表圆角显示

highchart 插件之给column和bar 圆角

下面是扩展插件的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
(function (H) {
H.wrap(H.seriesTypes.column.prototype, 'translate', function (proceed) {
var options = this.options,
rTopLeft = options.borderRadiusTopLeft || 0,
rTopRight = options.borderRadiusTopRight || 0,
rBottomRight = options.borderRadiusBottomRight || 0,
rBottomLeft = options.borderRadiusBottomLeft || 0;

proceed.call(this);

if (rTopLeft || rTopRight || rBottomRight || rBottomLeft) {
H.each(this.points, function (point) {
var shapeArgs = point.shapeArgs,
w = shapeArgs.width,
h = shapeArgs.height,
x = shapeArgs.x,
y = shapeArgs.y;

// Preserve the box for data labels
point.dlBox = point.shapeArgs;

point.shapeType = 'path';
point.shapeArgs = {
d: [
'M', x + rTopLeft, y,
// top side
'L', x + w - rTopRight, y,
// top right corner
'C', x + w - rTopRight / 2, y, x + w, y + rTopRight / 2, x + w, y + rTopRight,
// right side
'L', x + w, y + h - rBottomRight,
// bottom right corner
'C', x + w, y + h - rBottomRight / 2, x + w - rBottomRight / 2, y + h, x + w - rBottomRight, y + h,
// bottom side
'L', x + rBottomLeft, y + h,
// bottom left corner
'C', x + rBottomLeft / 2, y + h, x, y + h - rBottomLeft / 2, x, y + h - rBottomLeft,
// left side
'L', x, y + rTopLeft,
// top left corner
'C', x, y + rTopLeft / 2, x + rTopLeft / 2, y, x + rTopLeft, y,
'Z'
]
};

});
}
});
}(Highcharts));

前端初始化代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},

plotOptions: {
series: {
groupPadding: 0
}
},

series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4],
borderRadiusTopLeft: 5,
borderRadiusTopRight: 5
//borderRadiusBottomRight: 10,
//borderRadiusBottomLeft: 10
}]
});
});

效果图

demo在线预览

highchart 点击图表弹出层展示新图表

人太懒了,都不想写描述了,直接上代码吧 o(∩_∩)o 哈哈

简要说明步骤

  • 页面先初始化一个图表
    初始化代码我就省略了…

  • 在plotOptions 里的series events 增加点击事件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     plotOptions:{
    series: {
    cursor: "pointer",
    point: {
    events: {
    click: function () {
    //弹出方法 参数自己定义 需要什么传什么
    showDetails(this.category);
    }
    }
    }
    }
    }
  • 然后是弹出的方法,调用了lghdialog

查看更多

如何监听angularjs列表数据是否渲染完毕

有时候我们需要在ng列表元素渲染完毕后去执行一段js脚本,angularjs 刚好提供了ng-repeat 的一个属性$last,然后为大家简单介绍2种方式

第一种通过回调函数

前端HTML
1
2
3
4
5
<ul class="smart-timeline-list">
<li data-ng-repeat="item in lists" on-finish-render-filters="Complete">
<a href="{{item.url}}">{{item.title}}</a>
</li>
</ul>

#####js脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
angular.module('mainApp').directive('onFinishRenderFilters', function ($timeout) {
return {
restrict: 'A',
link: function(scope,element,attr) {
if (scope.$last === true) {
var finishFunc=scope.$parent[attr.onFinishRenderFilters];
if(finishFunc)
{
finishFunc();
}
}
}
};
})
.controller('test',["$scope",function($scope){
$scope.Complete=function(){
$('#div_scrollbar').tinyscrollbar();
}
}]);

  • 分析:on-finish-render-filters 传入一个回调函数Complete ,渲染时每次会判断当前渲染记录是否为最后一条,若为最后一条,则执行Complete 函数。

第二种方法是用消息传递的机制

1
2
3
4
5
<ul class="smart-timeline-list">
<li data-ng-repeat="item in lists" on-finish-render-filters>
<a href="{{item.url}}">{{item.title}}</a>
</li>
</ul>
js脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
angular.module('mainApp').directive('onFinishRenderFilters', function ($timeout) {
return {
restrict: 'A',
link: function(scope,element,attr) {
if (scope.$last === true) {
$timeout(function() {
//根据controller的关系是选择$emit或者$broadcast
scope.$emit('ngRepeatFinished');
});
}
}
};
})
.controller('test',["$scope",function($scope){
$scope.$on('ngRepeatFinished'function (ngRepeatFinishedEvent) {
$('#div_scrollbar').tinyscrollbar();
});
}]);
  • 分析:渲染时同样每次会判断当前渲染记录是否为最后一条,若为最后一条,则想父类或者子类的controller传递消息,对应的controller里添加消息的接受监听方法。

highchart+table 结合phantomjs 一并生成图片

其实是看到群里有小伙伴有这个需求,我才制作了这个DEMO,因为之前用phantomjs实现过纯后台导出图片,所以顺便改了下以前的DEMO分享给大家。
phantomjs 纯后台导出 请参考:http://www.peng8.net/2014/07/21/render-charts-serverside/

准备工作

  1. 去官网下载最新的phantomjs,官网提供三个版本下载,我电脑是window 7,所以用的是windows版,至于其他系统的请下载对应的版本。
  2. 解压文件,只需要对应的处理文件,例如windows版本里的就要 phantomjs.exerasterize.jsrasterize.js 用来向 phantomjs 发起请求生成快照

前端整理

  • 这里我们需要2个页面,一个页面用来专门显示图表(default),一个用来触发弹出图表(index)
    为什么我们需要2个页面呢?因为这里我们是用到了phantomjs的一个功能,生成快照!所以需要一个干净的页面,只有图表,图片生成的内容也就是我们想要生成最后样子的图片。
  • 我借用了lhgdialog 弹窗插件来弹出展现我们要生成的图表

查看更多