給jMaki的Dojo.table控件增加分頁功能。Author: bsspirit
Source:
http://gocom.primeton.com/blog7168_14478.htm分頁原理:前臺(tái)分頁技術(shù)。一次性得到全部結(jié)果集,通過Javascript進(jìn)行分頁。
使用方法:
<a:ajax name="dojo.table2" service="${parameters}" args="{size:5}"/>
說明:
name="dojo.table2" //這是帶分頁的table控件
service="url" //提供json串的url地址
arg="{size:5}" //分頁大小為,每頁5個(gè)。如果不在頁面上定義,默認(rèn)為10個(gè)。
使用方法看起來很簡單,復(fù)雜的就是對(duì)控件的修改了。
component.htm文件:
<table id="${uuid}" class="filterTable"></table>
<div align="right" id="page_${uuid}" class="filterTable"></div>
component.js文件:(復(fù)雜度其中在這個(gè)文件里)
/* Copyright 2007 You may not modify, use, reproduce, or distribute this software except in compliance with the terms of the License at:
http://developer.sun.com/berkeley_license.html
$Id: component.js,v 1.2 2008/02/15 09:14:02 zhangdan Exp $
*/
djd43.require("djd43.widget.FilteringTable");
// define the namespaces
jmaki.namespace("jmaki.widgets.dojo.table2");
jmaki.widgets.dojo.table2.Widget = function(wargs) {
var _widget = this;
var columns = [];
var uuid = wargs.uuid;
var topic = "/dojo/table2";
var subscribe = ["/dojo/table2", "/table"];
var filter = "jmaki.filters.tableModelFilter";
var container = document.getElementById(uuid);
var table;
var counter = 0;
// 分頁
var pageInfo = document.getElementById("page_"+uuid);
//分頁對(duì)象
var page = {
total:100, //結(jié)果集總數(shù)
size:10, //每頁結(jié)果集數(shù)
index:0, //當(dāng)前的位置
rows:[], //結(jié)果集所有值
pageAccount:function(){ //總頁數(shù)
var tmp = page.total/page.size;
if(page.total%page.size == 0){
return tmp;
}
return Math.floor(tmp)+1;
},
pageNow:function(){ //當(dāng)前的頁
if(page.index>page.total){
return page.pageAccount();
}
if(page.index<page.size){ //不足一頁的情況
return page.first;
} else if(page.index>=page.size){
return Math.floor(page.index/page.size)+1;
}
},
first: 1,//1是開始頁
front:function(){//上一頁
if(page.pageNow()<=1){
return page.first;
}
return page.pageNow()-1;
},
next: function(){//下一頁
if(page.pageNow()>=page.last()){
return page.last();
}
return page.pageNow()+1;
},
last: function(){//最后一頁
return page.pageAccount();
},
total2String:function(){
return "total:"+page.total;
},
size2String:function(){
return "size:"+page.size;
},
index2String:function(){
return "index:"+page.index;
},
first2String:function(){
return "<a href=javascript:jmaki.attributes.get(""+uuid+"").pageAction.toPage(""+page.first +"");>首頁"+"</a>";
},
front2String:function(){
return "<a href=javascript:jmaki.attributes.get(""+uuid+"").pageAction.toPage(""+page.front ()+"");>上頁"+"</a>";
},
next2String:function(){
return "<a href=javascript:jmaki.attributes.get(""+uuid+"").pageAction.toPage(""+page.next ()+"");>下頁"+"</a>";
},
last2String:function(){
return "<a href=javascript:jmaki.attributes.get(""+uuid+"").pageAction.toPage(""+page.last()+"");>last:"+"</a>";
},
goto2String:function(){
var tmp = "轉(zhuǎn)到第";
tmp += "<select name="gotopage" onchange=jmaki.attributes.get(""+uuid+"").pageAction.toPage(this.value)>";
for(var i=1;i<=page.last();i++){
if(i==page.pageNow()){
tmp+= "<option selected value=""+i+"">- "+i+" -</option>";
continue;
}
tmp+= "<option value=""+i+"">- "+i+" -</option>";
}
tmp += "</select>";
tmp += "頁";
return tmp;
},
twoSpace:function(){
return " ";
}
};
this.pageAction={
toPage:function(idx){
page.index = (idx-1) * page.size;
// alert("pageIdx:"+idx+" index:"+page.index+" pageNow:" +page.pageNow());
_widget.rows = page.rows.slice(page.index,page.index+page.size);
var data = [];
// add an Id for everything as it is needed for sorting
for (var i=0; i < _widget.rows.length; i++) {
var nRow;
if (!(_widget.rows[i] instanceof Array)) {
nRow = _widget.rows[i];
} else {
nRow = {};
for (var cl = 0; cl < columns.length; cl++) {
nRow[columns[cl].id] = _widget.rows[i][cl];
}
}
if (typeof _widget.rows[i].id == "undefined") {
nRow.id = genId();
} else {
nRow.id = _widget.rows[i].id;
}
data.push(nRow);
}
count = _widget.rows.length;
table.store.setData(data);
djd43.event.connect(table, "onSelect", _widget, "onSelect");
_widget.pagedInfo();
}
};
//分頁導(dǎo)航
this.pagedInfo = function(){
pageInfo.innerHTML=page.first2String()+page.twoSpace()+page.front2String()+page.twoSpace()+page.next2String()+page.twoSpace()+page.goto2String();
}
//service屬性加載URL
this.loadService = function(){
djd43.io.bind({
//url: wargs.service,
url: encodeURI(wargs.service+"×tamp=" + new Date().getTime()),
method: "get",
mimetype: "text/json",
load: function (type,data,evt) {
if (data == false) {
container.innerHTML = "Data format error loading data from " + wargs.service;
} else {
// convert value if a jmakiRSS type
if (data.dataType == "jmakiRSS") {
data = jmaki.filter(data, filter);
}
if (!data.rows) {
showModelDeprecation();
return;
}
if (data.rows) {
_widget.rows = data.rows;
}
if (data.columns) {
columns = data.columns;
}
page.total = _widget.rows.length;
page.rows = _widget.rows;
_widget.rows = page.rows.slice(page.index,page.index+page.size);
_widget.init();
}
}
});
}
// FIXME: this code can be removed for 1.0 release
var showedModelWarning = false;
function showModelDeprecation() {
if (!showedModelWarning) {
jmaki.log("Dojo table widget uses the incorrect data format. " +
"Please see <a +
"http://wiki.java.net/bin/view/Projects/jMakiTableDataModel</a> for the proper format.");
showedModelWarning = true;
}
}
function genId() {
return wargs.uuid + "_nid_" + counter++;
}
if (wargs.args) {
if (wargs.args.topic) {
topic = wargs.args.topic;
jmaki.log("Dojo table: widget uses deprecated topic property. Use publish instead. ");
}
if (wargs.args.filter) {
filter = wargs.args.filter;
}
//從JSP得到分頁大小
if(wargs.args.size){
page.size = wargs.args.size;
}
}
if (wargs.publish ) {
topic = wargs.publish;
}
if (wargs.subscribe){
if (typeof wargs.subscribe == "string") {
subscribe = [];
subscribe.push(wargs.subscribe);
} else {
subscribe = wargs.subscribe;
}
}
// initialize the widget
this.init = function() {
// backwards compatibility
if (typeof columns[0] != "object") {
showModelDeprecation();
} else if (_widget.rows.length > 0 && _widget.rows[0] instanceof Array) {
showModelDeprecation();
}
table = djd43.widget.createWidget("FilteringTable",{valueField: "id"},container);
// provide generic column names if they were not provided.
for (var l = 0; l < columns.length; l++) {
var c = columns[l];
if (!c.id)c.id = l + "" ;
c.field = c.id;
if (c.title) c.label = c.title;
c.dataType = "String";
}
for (var x = 0; x < columns.length; x++) {
table.columns.push(table.createMetaData(columns[x]));
}
var data = [];
// add an Id for everything as it is needed for sorting
for (var i=0; i < _widget.rows.length; i++) {
var nRow;
if (!(_widget.rows[i] instanceof Array)) {
nRow = _widget.rows[i];
} else {
nRow = {};
for (var cl = 0; cl < columns.length; cl++) {
nRow[columns[cl].id] = _widget.rows[i][cl];
}
}
if (typeof _widget.rows[i].id == "undefined") {
nRow.id = genId();
} else {
nRow.id = _widget.rows[i].id;
}
data.push(nRow);
}
count = _widget.rows.length;
table.store.setData(data);
djd43.event.connect(table, "onSelect", _widget, "onSelect");
_widget.pagedInfo();
}
// set columns from the widget arguments if provided.
if (wargs.args && wargs.args.columns) {
columns = wargs.args.columns;
}
// pull in the arguments
if (wargs.value) {
// convert value if a jmakiRSS type
if (wargs.value.dataType == "jmakiRSS") {
wargs.value = jmaki.filter(wargs.value, filter);
}
if (!wargs.value.rows) {
showModelDeprecation();
return;
}
if (wargs.value.rows){
_widget.rows = wargs.value.rows;
} else if (wargs.value instanceof Array) {
_widget.rows = wargs.value;
}
if (wargs.value.columns) {
columns = wargs.value.columns;
}
_widget.init();
} else if (wargs.service) {
_widget.loadService();
} else {
djd43.io.bind({
url: wargs.widgetDir + "/widget.json",
method: "get",
mimetype: "text/json",
load: function (type,data,evt) {
if (data == false) {
container.innerHTML = "Data format error loading data widget.json file.";
} else {
var _d;
// convert value if a jmakiRSS type
if (data.dataType == "jmakiRSS") {
_d = jmaki.filter(data, filter);
} else {
if (data.value.defaultValue) _d = data.value.defaultValue;
}
if (_d.rows) {
_widget.rows = _d.rows;
}
if (_d.columns) {
columns = _d.columns;
}
_widget.init();
}
}
});
}
this.clearFilters = function(){
table.clearFilters();
}
this.clear = function() {
table.store.setData([]);
table.store.clearData();
counter = 0;
}
this.addRows = function(b){
if (b.message)b = b.message;
for (var i=0; i < b.value.length; i++) {
_widget.addRow({ value : b.value[i]}, false);
}
}
this.removeRow = function(b){
var index;
if (b.message)b = b.message;
if (b.targetId) {
index = b.targetId;
} else {
index = b;
}
if (index && table.store.getDataByKey(index)) {
table.store.removeDataByKey(index);
}
}
this.updateRow = function(b, d) {
var index;
var data;
if (d) data = d;
if (b.message) {
b = b.message;
}
if (b.value) {
data = b.value;
}
if (b.targetId) {
index = b.targetId;
} else {
index = b;
}
if (typeof index != "undefined" && table.store.getDataByKey(index)) {
var s = table.store.getDataByKey(index);
if (s) {
var r = table.getRow(s);
for (var i in data) {
s[i] = data[i];
}
// update the table cells to match the model
for (var j = 0; j < table.columns.length; j++) {
r.childNodes[j].innerHTML = data[table.columns[j].id];
}
}
}
}
this.select = function(b){
var index;
if (b.message)b = b.message;
if (b.targetId) {
index = b.targetId;
} else {
index = b;
}
if (index && table.store.getDataByKey(index)) {
var s = table.store.getDataByKey(index);
if (s) {
var r = table.getRow(s);
r.isSelected = true;
table.resetSelections();
table.toggleSelectionByRow(r);
table.renderSelections();
jmaki.publish(topic + "/onSelect", { widgetId : wargs.uuid, type : "onSelect", targetId : index, value : s });
}
}
}
this.addRow = function(b){
var r;
if (b.message)b = b.message;
if (b.value) {
r = b.value;
} else {
r = b;
}
var targetId;
if (r.id) targetId = r.id;
if (table.store.getDataByKey(targetId)) {
jmaki.log(wargs.uuid + " : Warning. Attempt to add record to dojo.table. with duplicate row id: " + targetId + ". Autogenerating new id.");
r.id = genId();
}
// add an id for sorting if not defined
if (typeof r.id == "undefined") {
r.id = genId();
}
table.store.addData(r, null, false);
}
this.onSelect = function(e) {
var _s = [];
var data;
var d = table.store.get();
for (var i = 0; i < d.length; i++) {
if (d[i].isSelected) {
_s.push(d[i].src.id);
data = d[i].src;
}
}
// later we may want to support multiple selections
jmaki.publish(topic + "/onSelect", { widgetId : wargs.uuid, type : "onSelect", targetId : _s[0], value : data });
}
function doSubscribe(topic, handler) {
var i = jmaki.subscribe(topic, handler);
_widget.subs.push(i);
}
this.destroy = function() {
for (var i=0; _widget.subs && i < _widget.subs.length; i++) {
jmaki.unsubscribe(_widget.subs[i]);
}
}
this.postLoad = function() {
// track the subscribers so we can later remove them
_widget.subs = [];
for (var _i=0; _i < subscribe.length; _i++) {
doSubscribe(subscribe[_i] + "/clear", _widget.clear);
doSubscribe(subscribe[_i] + "/addRow", _widget.addRow);
doSubscribe(subscribe[_i] + "/addRows", _widget.addRows);
doSubscribe(subscribe[_i] + "/updateRow", _widget.updateRow);
doSubscribe(subscribe[_i] + "/removeRow", _widget.removeRow);
doSubscribe(subscribe[_i] + "/select", _widget.select);
}
}
}
說明:
1. jmaki.namespace("jmaki.widgets.dojo.table2"); //在這里使用dojo.table2的命名空間,避免和原dojo.table重復(fù)。
2. var pageInfo = document.getElementById("page_"+uuid); //得到component.htm中的div,給分頁進(jìn)行輸出。
3. var page = {..} //定義一個(gè)分頁對(duì)象,分頁的算法,和操作都定義在這個(gè)分頁對(duì)象中。
4. this.pageAction() //網(wǎng)頁點(diǎn)擊,上一頁/下一頁等等操作,會(huì)觸發(fā)這個(gè)方法。
5. this.pagedInfo = function() //輸出上-頁/下-頁的標(biāo)簽到網(wǎng)頁上。
6. this.loadService = function() //從service屬性里,得到URL,取出URL的數(shù)據(jù)。
7. wargs.args.size //從JSP得到分頁大小