[Cordova] 顯示自訂的 confirm/alert 對話框
上次將舊的 HTML+CSS+JS Android app 移到 Cordova之後,
就有注意到 alert() 和 confirm() 跳出來的對話框,
標題部分變成了 Alert 和 Confirm 的英文字,
按鈕的文字也變成英文的 OK 和 Cancel,頗為突兀:
在以前直接在網頁裡用 confirm() 的話,標題應該是顯示頁面的名稱,
所以就會是中文的「圖書館多重帳戶登入」這樣子~
但換成 Cordova 之後,這個行為被改變了…
查了一下網路,大家是說要用 Cordova 的 navigator.notification 模組,
裡面提供的 alert 和 confirm 函式,會用系統原生的對話框,
就可以自訂對話框的標題了~
參考資料:
1. 安裝 notification 模組
本來看到有 notification API 的我,傻傻的就開始改我的 JavaScript,
結果跑起來之後發現 navigator.notification 這個屬性一直不存在…
後來才注意到要先安裝相關的模組才行呀~~
先用 cordova plugin search 找找看…
找出來一堆跟 notification 相關的東西,不過我們要的是 org.apache.cordova 開頭的,
所以是 org.apache.cordova.dialogs:
testuser@localhost ~ $ cordova plugin search notification
.......
org.apache.cordova.dialogs – Cordova Notification Plugin
…….
使用 cordova plugin add 來安裝這個模組:
cordova plugin add org.apache.cordova.dialogs
或是從官網文件上可以看到下面的安裝法:
cordova plugin add cordova-plugin-dialogs
2. 在程式中呼叫 notification 模組提供的 confirm() 函式
我的程式除了要在 Android/iOS 上執行以外,同時也是一個 Chrome extension,
因此在 Chrome 環境下是沒有 Cordova 的,
所以我寫了一個 jsConfirm() 函式,裡面先判斷 navigator.notification.confirm 是否可用,
可以的話就呼叫它,不然就使用一般的 confirm()~
不過比較麻煩的是,原本的 confirm() 算是同步呼叫,
而 navigator.notification.confirm() 則需要提供一個 callback 在使用者選擇之後呼叫,
因此 jsConfirm() 就設計成要傳入兩個 callback 函式,
一個給按下 OK 時使用,一個給按下 Cancel 時使用:
function jsConfirm(message, callbackOnOK, callbackOnCancel) { if (navigator.notification && navigator.notification.confirm) { navigator.notification.confirm( message, // message function(buttonIndex) { if (buttonIndex === 1) { if (callbackOnOK) { callbackOnOK(); } } else { if (callbackOnCancel) { callbackOnCancel(); } } }, '圖書館多重帳戶登入', ['確定', '取消']); } else { if (window.confirm(message)) { if (callbackOnOK) { callbackOnOK(); } } else { if (callbackOnCancel) { callbackOnCancel(); } } } }
關於 notification.confirm() 的最後一個參數,
原本是一個字串像是 “確定,取消” 這樣子,網路上大部分的範例也都是這麼寫,
不過用 Logcat 可以看到下面的警告訊息:
I/Web Console( 1571): Notification.confirm(string, function, string, string) is deprecated. Use Notification.confirm(string, function, string, array). at file:///android_asset/www/plugins/org.apache.cordova.dialogs/www/notification.js:60
查證最新的 Cordova API 介紹的話,
發現最後一個參數應該是個陣列,改成 [‘確定’, ‘取消’] 就 OK 了~
加上這個 jsConfirm() 函式後,原本呼叫 confirm() 的地方也不能直接改成呼叫 jsConfirm(),
因為處理函式參數和回傳值的部分都要修改~
舉例來說,下面的程式片段是呼叫了 jsConfirm(),同時給了一個 callback,
當使用者按下確認 OK 鈕時,就會執行 callback function 來退出 app:
jsConfirm("確定離開程式嗎?", function() { navigator.app.exitApp(); });
修改好之後,對話框的標題看起來好多囉:
上述是 confirm() 的改法,而 alert() 其實也蠻類似的~
Cordova 在 notification.alert 也提供了 callback 函式,
不過原本 JavaScript 的 alert() 通常只是秀個訊息,
所以我的程式裡是還不需要對 alert() 加上 callback 的,
簡單實作一個 jsAlert() 讓它可以同時支援 Cordova 和一般瀏覽器:
function jsAlert(message) { if (navigator.notification && navigator.notification.alert) { navigator.notification.alert( message, function() { }, '圖書館多重帳戶登入', '確定'); } else { window.alert(message); } }
下面是使用 jsAlert() 的結果: