編輯器 QR 掃描器整合
最近我們收到一個有趣的論壇帖子,詢問是否有可能將 QR 掃描器整合到編輯器中。我很高興地說,這確實是可行的,在這篇部落格文章中,我將示範如何為編輯器建立欄位類型外掛程式,使 QR 碼可以讀取到欄位中。我使用了第三方 Instascan 函式庫在您自己的系統中實作此功能。
在我們深入探討之前,以下是您可以從這個外掛程式中預期的預覽。只需編輯或建立一個新列,然後按一下「描述」欄位輸入元素旁邊的「掃描」按鈕。從這裡,您應該可以掃描 QR 碼並在輸入元素中看到結果。
名稱 | 城市 | 描述 |
---|
快速開始
如果您想使用編輯器和 Instascan 作為 QR 掃描器,您可以從 NPM 安裝 Instascan (npm install --save instascan
) 或直接在 script 標籤中匯入它
您還需要整合外掛程式才能使其與編輯器一起使用,您可以從這裡下載
最後,(是的,就這麼簡單!)您需要將 fields.type
選項設定為 qr
- 例如
fields: [
{
label: 'Code:',
name: 'code',
type: 'qr'
},
// ...
]
從這裡,您會發現當您編輯或建立記錄時,您可以按一下出現在您指定為 QR 欄位的欄位輸入旁邊的掃描按鈕。然後,這應該會顯示您的網路攝影機的即時饋送,當您掃描 QR 碼時,值將顯示在輸入元素中。
建立外掛程式
使用它非常簡單,所以讓我們深入了解它的工作原理,我們可以研究如何為編輯器建立自訂欄位類型外掛程式。
Instascan
首先,我們需要一個 QR 碼掃描器,而 Instascan 是我們可以使用的函式庫。它將自己描述為「即時網路攝影機驅動的 HTML5 QR 碼掃描器」,這非常符合我們的需求。
有一些 API 方法和設定選項我們不會在這裡討論,但它們可能對您有用,我鼓勵您閱讀他們在 github 上的 readme 檔案,以便您可以設定 Instascan 以滿足您自己的需求。他們還有一個 演示頁面,很好地展示了他們提供的功能。
將 Instascan 與編輯器整合
為了使 QR 碼掃描器完全可重複使用,並允許在單個表單中使用多個 QR 碼,我們將為編輯器建立一個自訂欄位類型外掛程式。我們需要為我們的編輯器外掛程式定義三個函式
create
- 在欄位首次初始化時呼叫get
- 從欄位取得值set
- 將值設定到欄位中。
create
這幾乎是這個外掛程式中所有有趣的事情發生的地方!以下是我們函式的結構,分為幾個部分(因為當所有部分放在一起時會變得相當大)
create: function (conf) {
create: function (conf) {
// Section 1 - DOM setup, including container
// Section 2 - Instascan setup
// Section 3 - Toggle control
// Section 4 - Close behaviour
return container;
},
我們 create
函式的第一個部分用於建構欄位的 DOM,因為我們需要將幾個不同的元素放在一起。請注意,我們將 input
元素分配給 conf
物件,允許在其他外掛程式方法中存取它。
// Section 1 - DOM setup
var safeId = DataTable.Editor.safeId(conf.id);
var video = $('<video/>').css({
display: 'none',
'max-width': '100%',
padding: '2% 0%',
});
var input = $('<input id="' + safeId + '"/>');
var scan = $('<button>Scan</button>').css({ margin: '0% 1%' });
var container = $('<div/>').append(input).append(scan).append(video);
conf.qrInput = input;
接下來是初始化 Instascan 實例。我們需要為 Instascan 實例新增一個 scan
監聽器。當偵測到 QR 碼時,將觸發此監聽器,並將 input
元素的值設定為 QR 碼的值。這裡新增的另一個點是,為 input
元素和影片饋送都新增一個半秒的邊框。這會在視覺上向使用者指示已進行掃描。
var scanner = new Instascan.Scanner({ video: video[0] });
scanner.addListener('scan', function (content) {
input.val(content).css({ border: 'blue 2px solid' });
video.css({ border: 'blue 2px solid' });
setTimeout(() => {
input.css({ border: 'none' });
video.css({ border: 'none' });
}, 500);
});
現在我們有了準備就緒的 Instascan 實例,我們需要使用它!在這個外掛程式中,當點擊上面定義的 scan
按鈕元素時,我們將啟動欄位的攝影機。為了啟動掃描,我們使用 Instascan.Camera.getCameras
方法,該方法會回傳一個 Promise
,然後使用實例的 start()
方法。我們也會顯示 video
元素,以便使用者可以看到攝影機看到的東西。切換的相反操作會呼叫 Instascan 實例的 stop()
方法。在這兩種情況下,按鈕的內容都會更新,以反映點擊它會做什麼。
// Section 3 - Toggle control
scan.on('click', function () {
if (this.innerHTML === 'Scan') {
Instascan.Camera.getCameras()
.then(function (cameras) {
if (cameras.length > 0) {
video.css({ display: 'block' });
scanner.start(cameras[0]);
} else {
console.error('No cameras found.');
}
})
.catch(function (e) {
console.error(e);
});
this.innerHTML = 'Stop';
} else if (this.innerHTML === 'Stop') {
video.css({ display: 'none' });
scanner.stop();
this.innerHTML = 'Scan';
}
});
最後要新增的是表單關閉的監聽器,以確保我們在表單關閉時停止掃描 QR 碼並關閉攝影機。
// Section 4 - Close behaviour
this.on('close', function () {
scanner.stop();
});
get
get 函式很簡單。因為我們在 create 函式中將 input
元素新增到 config
物件中,並且我們在 create
函式中安裝的 Instascan scan
事件處理常式會將值寫入其中,所以我們可以直接取得它的值
get: function ( conf ) {
return conf.qrInput.val();
}
set
set 函式也相對簡單,在此案例中,將給定的值設定到 input
元素中
set: function (conf, val) {
conf.qrInput.val(val !== null ? val : '');
},
將所有這些函式組合成一個外掛程式,就會產生上面顯示的行為。最終腳本可以從以下位置下載
進階使用
當然,還有更進階的方法可以將 QR 讀取器與編輯器整合。您可能有 QR 碼表示一系列以逗號分隔的字串,您想直接將它們放入表格中。您可以讀取程式碼,將結果拆分開,然後分別放入每個欄位,或者根據掃描的程式碼,查詢另一個 API 以填寫其他欄位(例如,地理位置 API)。
實作計數系統也是有可能的。假設您有一份物品庫存,您需要掃描每個物品並追蹤每個物品的計數。您可以在表格之外執行 Instascan,並使用 DataTables API 在每次掃描時增加每個物品類型的計數。
意見回饋
與往常一樣,我們很想聽聽您如何使用 DataTables 和編輯器。請在論壇中給我們留言,說明您如何使用我們的軟體,或者您是否遇到任何問題,或者對未來增強功能有任何想法。我們很想知道人們是否能夠將 Instascan 整合到他們的專案中。
根據意見回饋新增的內容
自發布這篇部落格文章以來,我們收到了一些關於如何在 Android 和 IOS 行動裝置上改進它的意見回饋。感謝 Daniel Bierschwale 的貢獻。
後置鏡頭
大多數行動裝置都有後置和前置鏡頭,您要鎖定哪個鏡頭可能取決於您使用的裝置和應用程式。在 Android 上,存取後置鏡頭很簡單,您只需在第二個鏡頭上開始掃描即可。這表示要變更
scanner.start(cameras[0]);
至此
scanner.start(cameras[1]);
但是在 IOS 上,這沒有那麼簡單。如這個 Github 問題 中詳細說明,您必須修改 camera.js 檔案並設定
facingMode: "environment"
然而,這樣做的一個缺點是您無法在鏡頭之間切換。
IOS 上第一個畫面凍結的修復
在 IOS 上第一次開啟攝影機時,有時影片不會立即播放,只會顯示第一個畫面。這可以透過編輯影片標籤來修復,使其成為
<video autoplay muted id="video" controls="true"/>