2009年8月11日 星期二
誤用比不會用更可怕
最近因為研究extjs,所以花了些時間去研究一下Java Script, 才發現其實Java Script一直讓人誤解為非常簡單且基本的語言,原來是寫Java Script的大多應用在Web上,而且都只是執行非常簡單的功能,再加上大家都沒有花時間去研究這一語言,造成Java Script成為被誤解最深的語言。後來終於因為Ajax的流行,造成許多的Java Script Library的大量發展(如extjs或jquery),我們才有動力真正的想去了解Java Script。其實速食文化的興起,很多人都想(code)寫得少(function)做得多,很多都是抄來抄去的,根本就沒有去了解整個來龍去脈,進而導致誤用,很多也都沒被發現,甚至還為這個bug做workaround。 不過有時候這問題是沒有找到一本好的書,又是因為那該死的速食文化,造成輕鬆學會xxx或這24hr學會xxx之類的書大賣,而其他的書卻是又貴又不好賣,大師們也就不願意花時間去寫一本好書,更甚者,連課堂上也開始講求短時間內學會哪些東西,上了一個月的C,就可以在園區當RD,拚工時,拚廉價,那麼花大把時間在研究的人怎麼能堪的住哩,又有誰願意花時間去研究,畢竟大家都是夠用就好,而研究是想讓原本的東西更好。 總結上述,當您在使用任何東西時,應該要對其有一定程度的了解,至少先翻翻使用手冊吧,不要一在的抄襲前人的東西,而不知道為何要這樣做。好的書是值得大家支持的,不然好的書會越來越少。
extjs - Ext.grid.EditorGridPanel簡介
Ext.grid.EditorGridPanel繼承自Ext.grid.GridPanel,提供編輯Cell的能力。除了將Ext.grid.GridPanel改變成Ext.grid.EditorGridPanel外,還要設定Ext.grid.ColumnModel的欄位的editor。
Ext.onReady(function() { var data = [['Brook', '0921'], ['Rene', '0918']]; var cm = new Ext.grid.ColumnModel([ new Ext.grid.RowNumberer(), {header: 'Name', dataIndex: 'name', editor: new Ext.grid.GridEditor(new Ext.form.TextField())}, {header: 'Tel', dataIndex: 'tel', editor: new Ext.grid.GridEditor(new Ext.form.TextField())} ]); var store = new Ext.data.Store({ proxy: new Ext.data.MemoryProxy(data), reader: new Ext.data.ArrayReader({},[ {name: 'name'}, {name: 'tel'} ]) }); store.load(); var grid = new Ext.grid.EditorGridPanel({ renderTo: Ext.getBody(), store: store, cm: cm, sm: new Ext.grid.RowSelectionModel(), viewConfig: { forceFit: true }, title: "Brook's address book", loadMask: true, height: 200, width: 330 }); });
新增/刪除
我們在tbar新增兩個按鈕add/remove,add的流程如下:
- 停止grid的編輯。
- 接著插入一筆空白的資料到第一列的位置。
- 將第一行第一列變成編輯模式。
刪除的流程如下:
- 取得所有選取的列。
- 反覆的將所有選取列,移到store.removed(暫存起來,不然後面會遺失移除的列)。
Ext.onReady(function() { var record = Ext.data.Record.create([ {name: 'name', type: 'string'}, {name: 'tel', type: 'string'} ]); var data = [['Brook', '0921'], ['Rene', '0918']]; var cm = new Ext.grid.ColumnModel([ {header: 'Name', dataIndex: 'name', editor: new Ext.grid.GridEditor(new Ext.form.TextField())}, {header: 'Tel', dataIndex: 'tel', editor: new Ext.grid.GridEditor(new Ext.form.TextField())} ]); var store = new Ext.data.Store({ proxy: new Ext.data.MemoryProxy(data), reader: new Ext.data.ArrayReader({},[ {name: 'name'}, {name: 'tel'} ]), removed: [] /* 放置移除的列 */ }); store.load(); var grid = new Ext.grid.EditorGridPanel({ renderTo: Ext.getBody(), store: store, cm: cm, sm: new Ext.grid.RowSelectionModel(), viewConfig: { forceFit: true }, title: "Brook's address book", loadMask: true, height: 200, width: 330, tbar: new Ext.Toolbar(['-', /* '-' 是按鈕分隔符號 */ { text: 'add', handler: function() { var r = new record({ name: '', tel: '' }); grid.stopEditing(); store.insert(0, r); grid.startEditing(0,0); } }, { text: 'remove', handler: function() { var rows = grid.getSelectionModel().getSelections(); for (var i = 0; i < rows.length; i++) { store.removed.push(rows[i]); /* 暫存 */ store.remove(rows[i]); /* 移除 */ } } } ]) }); });
修改
Ext.onReady(function() { var data = [['Brook', '0921'], ['Rene', '0918']]; var cm = new Ext.grid.ColumnModel([ new Ext.grid.RowNumberer(), {header: 'Name', dataIndex: 'name', editor: new Ext.grid.GridEditor(new Ext.form.TextField())}, {header: 'Tel', dataIndex: 'tel', editor: new Ext.grid.GridEditor(new Ext.form.TextField())} ]); var store = new Ext.data.Store({ proxy: new Ext.data.MemoryProxy(data), reader: new Ext.data.ArrayReader({},[{name: 'name'}, {name: 'tel'}]) }); store.load(); var grid = new Ext.grid.EditorGridPanel({ renderTo: Ext.getBody(), store: store, cm: cm, sm: new Ext.grid.RowSelectionModel(), viewConfig: { forceFit: true }, title: "Brook's address book", loadMask: true, height: 200, width: 330, tbar: new Ext.Toolbar([{ text: 'show modified', handler: function () { var records = store.getModifiedRecords(); for (var i = 0; i < records.length; i++) { alert(Ext.encode(records[i].getChanges())); } } }]) }); });
Ext.grid.EditorGridPanel提供直接編輯Cell的能力,透過store.getModifiedRecords()可以取得修改過的rows,針對修改過的rows可以再透過getChanges()取得修改過的欄位,被修改的cell會出現紅色的標記。
限制輸入
cell通常都是由Ext.form.Field的Subclasses組成,而這些元件都具有regex的property可以限制使用者的輸入,比如regex:/[0-9]/就是限制只能輸入數字,一但輸入格式不對就會出現紅線啦。更多資訊可以參考一下Ext.form.Field。
Ext.onReady(function() { var data = [['Brook', '0921'], ['Rene', '0918']]; var cm = new Ext.grid.ColumnModel([ new Ext.grid.RowNumberer(), { header: 'Name', dataIndex: 'name', editor: new Ext.grid.GridEditor( new Ext.form.TextField({allowBlank:false})) }, { header: 'Tel', dataIndex: 'tel', editor: new Ext.grid.GridEditor( new Ext.form.TextField({regex:/[0-9]/})) } ]); var store = new Ext.data.Store({ proxy: new Ext.data.MemoryProxy(data), reader: new Ext.data.ArrayReader( {},[{name: 'name'}, {name: 'tel'}]) }); store.load(); var grid = new Ext.grid.EditorGridPanel({ renderTo: Ext.getBody(), store: store, cm: cm, sm: new Ext.grid.RowSelectionModel(), viewConfig: { forceFit: true }, title: "Brook's address book", loadMask: true, height: 200, width: 330 }); });
2009年8月10日 星期一
extjs - Ext.grid.GridPanel簡介
組成元件
要能正確顯示資料,必須包含資料倉儲(Store),資料欄位的定義(ColumnModel)。
首先我們先定義資料欄位:
var cm = new Ext.grid.ColumnModel({ {header: 'Name', dataIndex: 'name'}, {header: 'Tel', dataIndex: 'tel'} });
接著設定store,store包含資料取得方式(Proxy),以及分析方式(reader)。
var data = [ ['Brook', '0921'], ['Rene', '0918'] ]; var store = new Ext.data.Store({ proxy: new Ext.data.MemoryProxy(data), reader: new Ext.data.ArrayReader({},[ {name: 'name'}, {name: 'tel'} ]); }); store.load(); // 載入資料
最後再將他們和grid整合在一起:
var grid = new Ext.grid.GridPanel({ renderTo: Ext.getBody(), store: store, cm: cm, viewConfig: { forceFit: true // 自動調整欄寬[註1], }, title: "brook's guest book", width: 200, stripeRows: true, loadMask: true, height: 120 });
註1:forceFit在EditorGridPanel底下會出現錯誤(EditorGridPanel編輯後欄位錯亂的問題).
欄寬設定
調整欄寬除了forceFit以外,還可以設定autoExpandColumn: id,將特定欄寬expand以符合grid的大小,但如果設定了forceFit,autoExpandColumn將會被忽略。
var cm = new Ext.grid.ColumnModel([ { header:'Name', dataIndex:'name' }, { header:'Tel', dataIndex:'tel', id: 'tel' } ]); var grid = new Ext.grid.GridPanel({ renderTo: Ext.getBody(), store: store, cm: cm, title: "brook's guest book", loadMask: true, height: 120, autoExpandColumn: 'tel' });因為autoExpandColumn必須指定id,所以cm欄位也必須指定id。
排序
在cm中,將sortable設定為true後,該欄位就可以進行排序。
var cm = new Ext.grid.ColumnModel([ { header:'Name', dataIndex:'name', sortable: true }, { header:'Tel', dataIndex:'tel', id: 'tel' } ]);
也可以設定cm.defaultSortable = true,讓所有欄位都可以sort。
也可以預設某欄位排序的方向(由大到小,或由小到大),在store.sortInfo: {field: 'name', direction: "ASC"},就會將name以升冪排列,DESC則會降冪排列。
var store = new Ext.data.Store({ proxy: new Ext.data.MemoryProxy(data), reader: new Ext.data.ArrayReader({}, [ {name: 'name'}, {name: 'bd', type: 'date', dateFormat: 'Y-m-d'} ]), sortInfo: { field: 'name', direction: 'DESC' } });
日期顯示
在reader中將type設定為date,並且指定date的format,該欄位就會以date方式讀取,顯示的方式則要透過cm的renderer。
Ext.onReady(function() { var cm = new Ext.grid.ColumnModel([ { header: 'Name', dataIndex: 'name' }, { header: 'Birthday', dataIndex: 'bd', renderer: Ext.util.Format.dateRenderer('Y年m月d日') } ]); var data = [ ['Brook', '1999-12-03'], ['Rene', '1998-12-04'] ]; var store = new Ext.data.Store({ proxy: new Ext.data.MemoryProxy(data), reader: new Ext.data.ArrayReader({}, [ {name: 'name'}, {name: 'bd', type: 'date', dateFormat: 'Y-m-d'} ]) }); store.load(); var grid = new Ext.grid.GridPanel({ renderTo: Ext.getBody(), store: store, cm: cm, viewConfig: { forceFit: true }, title: "brook's guest book", loadMask: true, height: 120, }); });
由上例可知,只要透過cm.renderer就可以在顯示時加入一些變化。renderer函數包含value, metadata, css, record, rowIndex, colIndex, store等參數。
- value : Object 這個cell的資料
- metadata : Object 包含要套用在該CELL的CSS和HTML屬性的物件
- record : Ext.data.record 該列的資料物件
- rowIndex : Number Row index
- colIndex : Number Column index
- store : Ext.data.Store The Ext.data.Store object from which the Record was extracted.
Check box
CheckboxSelectionModel會在該欄位上顯示check box,讓使用者勾選。預設是多選,設定singleSelect為true可以改變為單選。
Ext.onReady(function() { var sm = new Ext.grid.CheckboxSelectionModel(); var cm = new Ext.grid.ColumnModel([ sm, { header: 'Name', dataIndex: 'name' }, { header: 'Tel', dataIndex: 'tel' } ]); var data = [ ['Brook', '0921'], ['Rene', '0918'] ]; var store = new Ext.data.Store({ proxy: new Ext.data.MemoryProxy(data), reader: new Ext.data.ArrayReader({}, [ {name: 'name'}, {name: 'tel'} ]) }); store.load(); var grid = new Ext.grid.GridPanel({ renderTo: Ext.getBody(), store: store, cm: cm, viewConfig: { forceFit: true }, title: "brook's guest book", loadMask: true, height: 120, width: 200 }); });
自動顯示行號 自動顯示行號是由Ext.grid.RowNumberer()提供的功能,和CheckboxSelectionModel一樣,放入cm就可以達到自動顯示行號之功能。
var cm = new Ext.grid.ColumnModel([ new Ext.grid.RowNumberer(), { header: 'Name', dataIndex: 'name' }, { header: 'Tel', dataIndex: 'tel' } ]);
Selection Model
在Ext.grid.GridPanel中,Selection Model預設是使用Ext.grid.RowSelectionModel,而且是可以多選,如果是單選就必須設定RowSelectionModel.singleSelect=true。
var grid = new Ext.grid.GridPanel({ renderTo: Ext.getBody(), store: store, cm: cm, sm: new Ext.grid.RowSelectionModel({singleSelect: true}), viewConfig: { forceFit: true }, title: "brook's guest book", loadMask: true, height: 120, width: 200 });
被選到的Row,可以透過grid.getSelectionModel().getSelections()取得。
var grid = new Ext.grid.GridPanel({ renderTo: Ext.getBody(), store: store, cm: cm, sm: new Ext.grid.RowSelectionModel(), viewConfig: { forceFit: true }, title: "brook's guest book", loadMask: true, height: 120, width: 200, buttons: [{ text:'show select', handler: function() { var selections = grid.getSelectionModel().getSelections(); for (var i = 0; i < selections.length; i++) { alert(selections[i].get('name') + ' is selection'); } } }] });
也可以選擇Cell Model,EditorGrid的預設Selection Model就是CellSelectionModel。
var grid = new Ext.grid.GridPanel({ renderTo: Ext.getBody(), store: store, cm: cm, sm: new Ext.grid.CellSelectionModel(), viewConfig: { forceFit: true }, title: "brook's guest book", loadMask: true, height: 120, width: 200 });
改變cell中的顯示(render)
圖文並茂的網頁是現在的趨勢,您可以透過Ext.grid.ColumnModel.renderer設定顯示cell時,要做哪些變化,比如,我想判斷電話號碼,顯示出電話號碼屬於哪家電信業者,程式碼如下:
Ext.onReady(function() { var record = Ext.data.Record.create([ {name: 'name', type: 'string'}, {name: 'tel', type: 'string'} ]); var data = [ ['Brook', '0921'], ['Rene', '0918'], ['John', '0980'] ]; function renderTel(value, metaData, record, rowIndex, colIndex, store) { if ('0921' == value) { return '<img src="images/cht.gif"/>' + value; } else if ('0918' == value) { return '<img src="images/twm.gif"/>' + value; } return value; } var cm = new Ext.grid.ColumnModel([ {header: 'Name', dataIndex: 'name'}, {header: 'Tel', dataIndex: 'tel', renderer: renderTel} ]); var store = new Ext.data.Store({ proxy: new Ext.data.MemoryProxy(data), reader: new Ext.data.ArrayReader({},[ {name: 'name'}, {name: 'tel'} ]), removed: [] }); store.load(); var grid = new Ext.grid.GridPanel({ renderTo: Ext.getBody(), store: store, cm: cm, sm: new Ext.grid.RowSelectionModel(), viewConfig: { forceFit: true }, title: "Brook's address book", loadMask: true, height: 200, width: 330 }); });
render function的參數說明如下:
- value: 將要顯示到cell的值。
- metaData:cell的屬性,包含css。
- record:該行資料。
- rowIndex:row index。
- colIndex:column index。
- store:使用中的store。
訂閱:
文章 (Atom)
熱門文章
-
轉自 http://www.wretch.cc/blog/redsonoma/14021073 基本概念: 1> tty(終端設備的統稱): tty一詞源於Teletypes,或者teletypewriters,原來指的是電傳打字機,是通過串行線用打印機鍵盤通過閱...
-
Work queue提供一個interface,讓使用者輕易的建立kernel thread並且將work綁在這個kernel thread上面,如下圖[1]所示。 由於work queue是建立一個kernel thread來執行,所以是在process context...
-
(V)將介紹file operations中的ioctl。ioctl的prototype為: int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); ...
-
這兩天電腦的word忽然都不能存檔,即便是另存新檔也不行,最後都只能放棄修改檔案,即便重新安裝過或者更新成2007也都不能存檔,最後就乖乖的google一下,原來是暫存的資料夾不存在,按照以下方式就可以解決了。 資料來源: word 2003不能存檔問題 編輯機碼的(reg...
-
System Call在HW和user space提供一層抽象層,主要目的有: 為user space提供硬體抽象層。比如,讀取檔案時,不用管檔案所在的媒體類型與檔案儲存類型。 System call能確保系統的安全與穩定。避免user space的無意或惡意的破壞。 ...
-
在kernel中建立thread可以使用kthread_create(),建立一個task,然後在調用wake_up_process(task)讓task真正的運行,如果要kill一個kthread可以使用kthread_stop()。 在kernel中,將kthread_cr...
-
Linux module練習手札I紀錄如何撰寫一個簡單的module,並且編輯它,以及load和unload一個module。 write a module #include <linux/init.h> #include <linux/module.h...
-
幾乎任何使用 TCP,UDP或UNIX-domain socket的動作都可以用nc來達成,常見的功能如。 simple TCP proxies shell-script based HTTP clients and servers network daemon testi...
-
很多人心中都有過一個問題 What is the difference between Platform driver and normal device driver? ,簡單的來說Platform devices就non-discoverable,也就是device本身沒辦法...
-
組成元件 要能正確顯示資料,必須包含資料倉儲(Store),資料欄位的定義(ColumnModel)。 首先我們先定義資料欄位: var cm = new Ext.grid.ColumnModel({ {header: 'Name', dataIndex...