用Web寫應用程式比較不爽的就是不能像Windows程式那樣自由自在,想跳窗就跳一個,尤其是在做資料維護畫面的時候,雖然跳轉畫面也是個解決辦法,但順暢度總是比不上Windows程式來得流暢。

jQuery提供了overlay的工具,應用在Yes/No的對話框也不成問題,但是如果想要讓對話框裏面還可以維護資料,那就是個大工程了。我希望能看到如下畫面:

image

你必須在按下修改按鈕的時候產生一個overlay,接著透過ajax向伺服器提取資料維護的頁面,再顯示出來。當使用者按下保存按鈕的時候透過ajax向伺服器提交表單資料,然後關閉overlay。

jQuery Tools提供的overlay方法很清楚,你只要在button的class='close'就可以讓你的overlay關閉,看起來似乎蠻容易的,實際做的時候才會想到問題。因為我們的按鈕是要透過ajax載入的,而宣告修改按鈕要連動到overlay卻是在ajax提取畫面之前就已經執行了,所以這兩個按鈕在當時並不存在。

<a href='/inneruser/modify/5' rel='#modeldialog'>改</a>
<a href='/inneruser/modify/6' rel='#modeldialog'>改</a>
<a href='/inneruser/modify/7' rel='#modeldialog'>改</a>
<a href='/inneruser/modify/8' rel='#modeldialog'>改</a>
<a href='/inneruser/modify/9' rel='#modeldialog'>改</a>

為了解釋方便,我省略掉一大堆程式碼。假設你的頁面上有一大堆的修改按鈕,網址的最後一欄就是你的ID,因為我用MVC架構開發,自然網址就變成這個樣子,沒有問號,其實都是差不多的,應該很容易看得懂。

順便準備一個可以放模態窗口的位置<div id='modeldialog'></div>,一開始它應該是隱藏的,CSS的部份我都先跳過,把焦點集中在程式碼上。接著用標準的方法設定上面那些超鏈接會啟動overlay:

$('[rel]').overlay( {
    mask: { color: '#ebecff', loadSpeed: 100, opacity: 0.7 },
    closeOnClick: true,
    onBeforeLoad: function() {
        $('#modaldialog').width('400px');
        trigger = this.getTrigger();
        $.post( trigger.attr('href'), function(data) { 
            $('#'+_settings.dialogid).html(data);
        });
    }
});

記住,一開始的時候closeOnClick要設為true,這樣即使點按鈕關閉不了,還可以點旁邊。這裡我設定了一個事件onBeforeLoad,當overlay載入的時候,設定維護窗的寬度,然後用jQuery的post方法,向伺服器取得頁面,而網址則是看使用者按的是哪個鏈接,就從上面偷過來,這樣這個網址就帶了ID,伺服器才能夠取出資料。伺服器的資料就像是上面的畫面一樣,應該很容易想像它的程式碼。這時候這兩個按鈕按下去頁面只會被跳轉到保存資料的頁面去,如果你覺得這樣OK那就不用再看下去了。

$('#form1').submit( function() {
    $.post( $(this).attr('action'), $(this).serialize(),
        function(data) { 
            $('#content').html(data)
        });
    return false;
});

 

如果我希望我的維護窗不會跳轉,那麼你應該加上像上面這樣的程式碼,在form被submit的時候,使用serialize()這個jQuery所提供的函數,將所有的欄位內容序列化,然後同樣用post方法將資料提交給伺服器,資料回傳就直接將當前的窗體內容置換掉,以免有錯誤發生,最後傳回false,讓原本應該要post的動作不會發生,這樣就不會跳轉頁面了。

雖然現在已經能將資料提交給伺服器,但是窗體還不會關掉,也就是我前面所說的原因,因為在綁定修改按鈕為overlay的時候,窗體內容還沒有產生,所以上面的按鈕並沒有被overlay所綁定。原本我的想法是在onBeforeLoad之後做,這樣的想法應該是很合情合理的,但是卻完全不理我,有可能是post使用非同步的關係,於是我再加了一個事件處理函數,在onLoad的時候重新進行按鈕的綁定動作。

onLoad: function() {
    $('#modaldialog button').bind('click', function() {
        trigger.overlay().close();
    });
}

這樣完成了後來的綁定動作,接著就是讓保存會保存,放棄能放棄,綁個click事件就可以了。不要看這個沒幾行程式碼,因為要測試這樣的功能需要很多前置動作,程式碼轉來轉去的,要做出來還是挺不容易的。

這樣整個過程其實有點小複雜,如果大量應用起來發生問題要改就很痛苦了。最好還是能將這些程式碼段變成jQuery的插件,用起來才會輕鬆愉快。

$('.modify').ajaxdialog( { 
    width:'360px',
    onClose: function() { 
        $.post('/inneruser/maintain/grid', function(data) {
        $('#content').html(data);
    }); }
} );
//
$('#inquiry').ajaxForm();
 

可以看到我的最終版本還外帶刷新原本的grid頁面,當然它也是ajax的。做這些事情的過程,感覺就像是我第一次接觸到ASP的時候,那時候NT4.0和ASP都還在BETA,只是想著要一個功能,就一步一步的把他試出來,不過我相信之後的成果會是豐碩的,現在我幾乎已經可以用PHP以ASP.NET的速度來開發MVC架構並且大量利用AJAX技術的網頁應用程式。

創作者介紹

人生四十宅開始 二號宅

漠哥 發表在 痞客邦 PIXNET 留言(0) 人氣()