jqGrid 實用技巧 (七) 上傳檔案

[anti-both]

最 多 朋 友 奇 怪 的 ,就 是 為 何 jqGrid 內 建 有 edittype:’file’,卻 沒 有 內 建 檔 案 上 傳 之 功 能 。於 是 筆 者 今 次 就 實 作 一 個 圖 片 的 欄 位 給 大 家 參 考 參 考 。

根 據 jqGrid wiki 的 介 紹 ,我 們 尚 要 使 用 另 一 個 plugin – Ajax File Upload 來 完 床 上 傳 檔 案 的 動 作 。

1
2
3
4
5
6
7
...
<head>
...
<script type="text/javascript" src="ajaxfileupload.js"></script>
...
</head>
...

跟 使 用 其 它 jquery plugin 一 樣 ,首 先 要 include 那 個 plugin 的 javascript file。

然 後 就 到 設 定 圖 片 欄 位 的 colModel。

1
2
3
4
5
6
7
...
colModel :[
....
{name:'imgurl',index:'imgurl',width:50,formatter:showPicture,search:false,editable:true,edittype:'file',editoptions:{enctype:"multipart/form-data"},formoptions:{elmsuffix:'<font color=red>*Suggested Size:220x220px</font>'}},
....
],
...

筆 者 不 太 喜 歡 把 圖 片 儲 存 到 資 料 庫 裡 面 ,所 以 資 料 庫 裡 面 的 資 料 只 會 是 圖 片 的 路 徑 。於 是 筆 者 就 要 在 formatter 用 一 條 custom function (showPicture) 把 圖 片 顯 示 出 來 。要 上 傳 檔 案 ,除 了 edittype 要 用 file,那 個 editoptions 還 要 增 加  enctype:”multipart/form-data”。

上 傳 檔 案 的 表 單 ,很 多 時 候 都 會 加 點 註 釋 ,讓 使 用 者 知 道 要 上 傳 什 麼 、有 沒 有 大 小 之 類 的 限 制 等 等 。jqGrid 的 formoptions 就 有 elmprefix 和 elmsuffix,可 以 在 輸 入 項 目 的 前 面 或 者 後 面 加 入 額 外 的 註 釋 。

1
2
3
function showPicture(cellvalue, options, rowObject){
return "<img src='" + cellvalue + "?" + Math.floor(Math.random()*100) + "' height='50' width='50'>";
}

前 面 幾 回 筆 者 也 講 過 圖 片 的 formatter,不 外 乎 是 把 資 料 庫 的 圖 片 路 徑 變 成 一 個 tag 而 已 。因 為 筆 者 喜 歡 用 index number 來 做 圖 片 名 稱 (貪 其 不 會 重 複 ),於 是 同 一 筆 資 料 ,不 管 更 新 多 少 次 ,圖 片 的 名 稱 都 是 一 樣 (例 如 :1.jpg)。所 以 ,筆 者 就 會 在 圖 片 後 面 加 一 串 隨 機 亂 數 ,確 保 圖 片 每 一 次 都 會 從 伺 服 器 更 新 (www.abc.com/1.jpg?234)。

因 為 沒 有 加 上 hidden 參 數 ,所 以 圖 片 是 會 顯 示 在 grid 的 ,所 以 要 規 定 其 大 小 ,以 至 不 會 破 壞 grid 的 排 位 (height=50 width=50)。

在 jqGrid 儲 存 資 料 到 資 料 庫 ,我 們 要 指 定 editurl。但 那 個 editurl 是 不 會 管 檔 案 上 傳 的 ,於 是 我 們 要 在 Form Add 和 Form Edit 的 afterSubmit 事 件 ,加 入 我 們 做 檔 案 上 傳 的 function(processFile)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
$("#list").jqGrid({
....
colModel :[
....
{name:'imgurl',index:'imgurl',width:50,formatter:showPicture,search:false,editable:true,edittype:'file',editoptions:{enctype:"multipart/form-data"},formoptions:{elmsuffix:'<font color=red>*Suggested Size:220x220px</font>'}},
....
],
...
});

$("#list").jqGrid('navGrid','#pager',
{edit:true,add:true,del:false,search:false, view:true},
{afterSubmit:processFile},
{afterSubmit:processFile},
{},
{},
{}
);

afterSubmit 事 件 ,是 在 submit 完 成 之 後 引 發 的 ,就 是 說 ,其 他 資 料 都 已 經 寫 入 了 資 料 庫 了 。

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
function processFile(response, postdata){
var success = true;
var message = "";
var json = eval('(' + response.responseText + ')');
var id = json.id;

$.ajaxFileUpload({
 url: 'file_upload.php',
 secureuri: false,
 fileElementId: imgurl,
 dataType: 'json',
 data: { id: id },
 success: function (data, status) {
  if (typeof (data.success) != 'undefined') {
   if (data.success == true) {
    return;
   } else {
    alert(data.message);
   }
  }
 }
})

return [success,message];
}

這 條 自 定 義 function processFile,因 為 是 承 接 aftersubmit 事 件 ,所 以 會 有 response 的 json 資 料 ,這 是 從 你 的 editurl 傳 回 來 的 。

1
2
3
4
5
6
7
<?php
...
$id = mysql_insert_id();
$data['id'] = $id;
echo json_encode($data);
...
?>

例 如 我 在 上 面 的 editurl 的 php 檔 案 ,就 用 json 傳 回 了 剛 剛 新 增 的 index number 了 。

那 為 什 麼 要 id 呢 ?因 為 我 們 上 傳 檔 案 之 後 ,一 定 有 東 西 要 寫 入 資 料 庫 的 ,不 管 是 把 整 個 圖 像 寫 入 資 料 庫 ,還 是 像 筆 者 只 把 路 徑 寫 入 資 料 庫 。要 寫 東 西 入 資 料 庫 ,那 個 id 就 很 必 要 了 。

至 於 接 受 上 傳 檔 案 的 php,也 就 跟 你 平 常 用 form 做 的 upload 沒 兩 樣 。最 後 ,你 也 可 以 傳 回 success 和 error message 。

1
2
3
4
5
6
7
8
9
10
11
12
<?php
...
$id = $_POST['id'];
if($_FILES['imgurl']['size'] > 0){
 $target_path = "xxx/xxx/".$id.".jpg";
 move_uploaded_file($_FILES['imgurl']['tmp_name'], $target_path);
 ...
 $SQL="UPDATE xxx SET imgurl='$target_path' WHERE id=$id";
 ...
 $data['success']=true;
 echo json_encode($data);
}
ctleung張先生,男性,肖龍。
職業:I.T. Consultant
簡介:不好好讀書;七尺差五寸,手長過膝,雙耳垂肩;性寬和,寡言語,喜怒不形於色。據說少時曾斬白蛇於鳳凰山下……

This entry was posted in jqGrid and tagged , , , , . Bookmark the permalink.

5 Responses to jqGrid 實用技巧 (七) 上傳檔案

  1. Jack says:

    Hi Mr. Zhang,

    請問非圖片的檔案,如PDF也可以依照上面的模式來使用嗎?
    有嘗試修改過,但是檔案在VIEW上面顯示不出資訊,想請問該如何顯示並下載上傳的檔案?
    以下是我的參數代碼:
    edittype: ‘file’,
    editoption: {enctype: “multipart/form-data” },
    formatter: showFile,

    function showFile(cellvalue, options, rowObject) {
    if (cellvalue != “”) {
    return “”;
    }

    }

    如果維持原樣採用版主原本的圖片設定一樣可以下載檔案,但是就會變成破圖的圖案顯示,請版主指教,謝謝

    • C.T. Leung says:

      吐血了。你為什麼不學一點簡單的 html 呀?我想把上傳圖片在 grid 裡面顯示出來,所以我幻想個 cell 裡面應該會有以下的 html:

      <img src=”path/filename?12345″ width=”50″ height=”50″ />

      所以,我才把我的 formatter showPicture 寫成文中那樣。

      好了,那你告訴我,你的 cell 裡面的 html 想要如何寫呢。你給我 html,我就幫你寫 showFile 的內容吧,好麼?

      • Jack says:

        真的不好意思….
        看完版主的說法就知道該怎樣解決了….
        代碼:
        <a href='” + cellvalue + “?” + Math.floor(Math.random() * 100) + “‘ rel=”nofollow”>” + cellvalue + “</a>

        已經可以呈現出我想要的樣子了,謝謝

        • C.T. Leung says:

          鼓掌!

          我原來的例子用了圖片,因為圖片會被 browser cache ( 快取 ),所以才在圖片的 URL 後面加了隨機數。

          但一般檔案下載的檔案類型,都是不會被 browser cache 的,所以 URL 是不需要加隨機數的。

          新的 browser 越來越強勁,識得自動打開的檔案越來越多 ( pdf / mp3 / mp4 / … ),而唔會自動下載。( 唔係講笑,真係有好多朋友唔識得將 browser 自動打開左的檔案下載到自己的電腦 )

          所以很多時都會加點小技巧來控制檔案下載時的行為。例如:

          <a href=”path-to-file” download>Click here</a>

          <a href=”path-to-file” download=”specificfilename”>Click here</a>

          <a href=”path-to-file” target=”_blank”>Click here</a>

          給你參考。

Leave a Reply

Your email address will not be published. Required fields are marked *