2020 年 7 月 10 日星期五
作者:Sandy Galloway

編輯器 QR 掃描器整合

最近我們收到一個有趣的論壇帖子,詢問是否有可能將 QR 掃描器整合到編輯器中。我很高興地說,這確實是可行的,在這篇部落格文章中,我將示範如何為編輯器建立欄位類型外掛程式,使 QR 碼可以讀取到欄位中。我使用了第三方 Instascan 函式庫在您自己的系統中實作此功能。

在我們深入探討之前,以下是您可以從這個外掛程式中預期的預覽。只需編輯或建立一個新列,然後按一下「描述」欄位輸入元素旁邊的「掃描」按鈕。從這裡,您應該可以掃描 QR 碼並在輸入元素中看到結果。

名稱 城市 描述

快速開始

如果您想使用編輯器和 Instascan 作為 QR 掃描器,您可以從 NPM 安裝 Instascan (npm install --save instascan) 或直接在 script 標籤中匯入它

JS

您還需要整合外掛程式才能使其與編輯器一起使用,您可以從這裡下載

JS

最後,(是的,就這麼簡單!)您需要將 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 : '');
},

將所有這些函式組合成一個外掛程式,就會產生上面顯示的行為。最終腳本可以從以下位置下載

JS

進階使用

當然,還有更進階的方法可以將 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"/>