[anti-both]
在 Grid 裡 面 ,我 們 少 不 免 會 顯 示 數 字 、數 值 。而 為 了 使 用 閱 讀 得 更 準 確 、快 速 ,很 多 時 候 這 些 數 值 都 會 按 照 會 計 準 則 加 上 紅 色 和 綠 色 。究 竟 要 如 何 做 才 能 改 變 Grid 裡 面 的 文 字 的 顏 色 呢 ?
初 學 者 大 概 會 馬 上 想 到 jqGrid 裡 面 的 formatter 和 Custom formatter。是 的 ,雖 然 是 笨 一 點 的 方 法 ,但 還 算 是 做 得 到 的 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
...
$("#list").jqGrid({
...
colModel:[
...
{name:'value', width:50, align:'right', formatter:valueFormatter, ....},
...
],
...
});
...
function valueFormatter(cellvalue, options, rowObject) {
if (cellvalue<0) {
return '<span style="color:red;" >' + cellvalue + '</span>';
} else {
return '<span style="color:green;" >' + cellvalue + '</span>';
}
}
|
看 起 來 真 不 錯 ,但 為 什 麼 就 笨 呢 ?因 為 formatter 是 直 接 改 寫 了 cellvalue 的 ,例 如 資 料 庫 裡 面 的 值 是 123.00,經 過 上 面 的 custom formatter 之 後 ,整 個 cell 就 變 成 了 <span style=”color:green;” >123.00</span>。當 你 要 再 在 jqGrid 裡 面 edit 這 個 cell 時 你 就 會 很 X 痛 了 。所 以 ,Custom Formatter 只 能 用 在 不 會 edit 的 cell 上 面 ( 例 如 editable:false 的 那 些 )。
要 是 不 想 改 變 cellvalue,那 我 們 只 好 在 cellvalue 外 面 的 那 一 個 element 來 加 style 了 ,對 不 ?查 一 查 jqGrid 的 documentation,呵 呵 ,還 真 有 這 麼 一 個 method 可 以 做 得 到 ,它 就 叫 做 setCell。
setCell - This method can change the content of particular cell and can set class or style properties. — jqGrid WiKi
setCell 的 用 法 也 簡 單 ,為 了 要 指 明 你 想 edit 那 一 個 cell,於 是 你 需 要 輸 入 那 個 cell 的 rowid 和 column name,然 後 你 可 以 設 定 cellvalue,加 個 class,或 者 是 直 接 設 定 style。
setCell 方 法 ,一 般 最 方 便 就 用 在 loadComplete event 裡 面 ,然 後 loop 一 次 所 有 rowid,每 一 行 都 設 定 一 次 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
...
$("#list").jqGrid({
...
colModel:[
...
{name:'value', width:50, align:'right', ....},
...
],
...
loadComplete: function (data) {
var allRows = $('#list').jqGrid('getDataIDs');
for (var i=0; i < allRows.length; i++) {
var rowid = allRows[i];
if ( $('#list').jqGrid('getCell',rowid,'value') < 0 ) {
$('#list').jqGrid('setCell',rowid,'value','',{color:'red'});
} else {
$('#list').jqGrid('setCell',rowid,'value','',{color:'green'});
}
}
},
...
});
...
|
在 上 例 之 中 ,我 們 在 loadComplete 的 時 候 ,先 用 getDataIDs 將 這 一 頁 的 所 有 rowid 都 取 出 來 ( allRows 是 一 個 array )。然 後 用 for loop,逐 一 個 row 來 做 設 定 。因 為 是 要 根 據 cellvalue 來 設 定 顏 色 ,所 以 當 然 要 用 getCell 取 出 cellvalue 啦 ,然 後 根 據 cellvalue 來 設 定 那 個 cell 的 style。特 別 注 意 一 下 ,setCell method 的 第 三 個 parameter 是 cellvalue,如 果 留 空 就 是 不 設 定 的 意 思 ,所 以 setCell 之 後 仍 然 會 是 原 來 的 cellvalue。
setCell 雖 然 好 用 ,但 要 自 己 寫 個 for loop 依 然 很 麻 煩 ,有 沒 有 再 簡 單 一 點 的 方 法 呢 ?答 案 當 然 是 有 的 。那 就 是 colModel 裡 面 的 一 個 property,叫 做 cellattr。
cellattr 其 實 跟 custom formatter 很 像 ,都 是 一 條 custom function。但 formatter 是 設 定 cellvalue 的 ,cellattr 就 是 設 定 那 個 cell 的 element 的 attributes 的 。jqGrid 裡 面 的 cell,說 穿 了 其 實 就 是 一 個 <td> element 是 也 。我 們 用 cellattr 加 attributes,就 是 加 在 那 個 <td> 裡 面 ,所 以 ,一 定 要 <td> 支 援 的 attributes 才 能 加 ,不 然 加 了 也 沒 有 用 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
...
$("#list").jqGrid({
...
colModel:[
...
{name:'value', width:50, align:'right', cellattr:valueAttr, ....},
...
],
...
});
...
function valueAttr(rowId, cellValue, rawObject, cm, rdata) {
if (cellValue < 0) {
return ' style="color: red"';
} else {
return ' style="color: green"';
}
}
|
在 上 例 中 ,我 們 在 colModel 裡 面 增 加 了 cellattr,並 把 它 設 定 為 一 條 custom function — valueAttr。跟 custom formatter 一 樣 ,cellattr 也 會 把 cellvalue 傳 給 custom function 的 。檢 查 了 cellvalue 的 值 ,我 們 就 可 以 傳 回 相 對 應 的 attribute 了 。記 住 ,這 裡 傳 回 的 是 html tag 裡 面 的 attribute,是 要 乎 合 attribute 的 格 式 的 ,而 不 是 隨 隨 便 便 傳 回 一 個 string 就 可 以 啊 。
在 使 用 cellattr 時 ,還 有 一 點 要 注 意 。cellattr 是 在 formatter 之 後 執 行 的 ,所 以 如 果 你 的 cellattr 是 與 formatter 一 起 用 的 ,就 是 要 小 心 那 個 cellvalue 了 。例 如 在 database 的 值 是 1234.05,如 果 你 設 定 了 formatter: ‘currency’,那 在 cellattr 接 收 到 的 cellvalue 很 可 能 就 變 成 了 $ 1,234.05。如 果 你 還 以 為 它 是 數 值 來 if ( cellvalue>0 ),那 鐵 定 是 會 出 錯 的 。
這篇真是good idea, 居然沒人回應, 趕快來按個讚!
good article