2009年12月11日 星期五

ExtJS: Ext.ux.Wiz and my problem

Many ExtJS developer release their own extension, because their project require some function but official ExtJS library doesn't provide the function. In my project, I have to implement a "Wizard." Wizard means a step by step user interface. It leads user finish a process.

Ext.ux.Wiz is an open source project created by a Germany developer --Thorsten Suckow-Homberg. This extension include java script source code and graphic content.

I try to use the extension to implement my complex workflow. For example, in first card, user can choose a job by a radio button. but this extension only provide linear sequential control. It can't let user control the show card flow. First step choose delete and next jump to card 6th. In 6th card, click previous, it should switch to first card not 5th card. And also have to consider the problem of finish button show. It's not an easy job.

So I think the bad solution. Divide the steps, and use "window.open" function to control the step manually.

*******

Ext.ux.Wiz提供使用者一個快速的方法,設計自己的精靈介面。但是他仍有不少限制,尤其遇到複雜的流程控制。像是第一張卡的某一個選項,讓下一張跑到第6張卡片,但是在第6張卡片出現時,按上一步不應該跑到第5張卡片。還有,有時候不能等到最後一張卡片,就必須讓Finish的按鈕出來。這時候該怎麼處理?

不才我做了一個月之後,怎麼弄就是搞不定。貼問題到官方的論壇後,遲遲沒有回應。沒耐心又受不了,於是寫信給原作者。原作者表示他沒有實作到這麼複雜,當初只是為了他的PIM專案所以開發這個Wiz的框架。沒有解決我提出的問題,也沒有太多時間處理。所以我只能自己去實作一個符合我需求的框架。

但是想也知道,我怎麼可能短時間內做出來。最後我老闆給了一個提示,於是我用比較投機取巧的方法達成。所以前面才會貼出一些小細節的解決方法,就是讓這個東西可以有機會做出來。這邊要講的,是怎麼控制Finish、Cancel按鈕的行為。

關於Finish按鈕的行為,有兩個方法控制,一個是用Lintener,另一個是用Overide的方法。

Listener的方式見下面程式碼
listeners: {
finish : function(){

}

}

Override的方式如下,定義onFinish的方法。筆者選擇用這方法完成我要的功能!
設定前面Radio Button的範例,設定對應的動作,即切換到新的頁面。

onFinish: function(){

if (this.fireEvent('finish', this, this.getWizardData()) !== false) {
var selValue = Ext.DomQuery.selectValue('input[name=functional]:checked/@value');

if (selValue == 1)
window.open('create.html','_self','')
else if (selValue == 2)
window.open('update.html','_self','')
else if (selValue == 3)
window.open('delete.html','_self','')
else
window.open('query.html','_self','')

}
}

另外也在後面開啟的頁面,用Listener的方法讓Cancel回到上面判斷下一步的頁面。
listeners: {
cancel : function(){
window.open('entry.html','_self','')
}
}
不知道Cancel鈕為何不能用override達成控制,所以我用listener解決。


看得懂嗎?就是第一頁entry.html會切換到create.html、query.html、delete.html、update.html
然後這四頁中的Cancel鈕又可以回到entry.html這頁

方法確實很爛,但是可以解決需求。細部還要處理的,就是Previous按鈕。還有entry.html的按鈕,顯示Finish真的好嘛?
因為還有其他步驟,Finish按鈕會誤導使用者。關於這部份,要改的是Ext.ux.Wiz原始檔案中的Wizard.js,裡面有提到按鈕文字的顯示。

這方法不佳的最大理由,就是違反One page, one application的原則。Ajax不就是要避免畫面閃爍的切換方式嘛?從entry.html到其他頁面,就會遇到畫面切換的問題。顯示技巧的粗糙!

*******

Please use listener or override to control the button's behavior. (Cancel, Finish or Previous button)

Listener like the following shown
listeners: {
finish : function(){

}

}

If you want to use override, just like
onFinish: function(){

if (this.fireEvent('finish', this, this.getWizardData()) !== false) {
var selValue = Ext.DomQuery.selectValue('input[name=functional]:checked/@value');

if (selValue == 1)
window.open('create.html','_self','')
else if (selValue == 2)
window.open('update.html','_self','')
else if (selValue == 3)
window.open('delete.html','_self','')
else
window.open('query.html','_self','')

}
}

Cancel button can't use override, I don't know why. But finally I using a listener define cancel button's behavior.

The rule (or target) of RIA or Ajax is one page, one application. But my solution is betray the rule.

沒有留言: