カテゴリー: Web開発

  • SQLite3 で 1 Query で BOOL 値の toggle

    SQLite3 で BOOL 値を扱うとき、SQLite3 には BOOLEAN 型がないので INTEGER で代用することになる。

    0 を false, 1 を true とするときに、例えば

    • 現在の値が 0 なら 1 にセット
    • 現在の値が 1 なら 0 にセット

    としたいときがあると思う。

    現在の値を確認するために、まず “SELECT …” で値を読み込んで、その値から判断して “UPDATE …” とすると、2 Queries になってしまう。

    Making an sql “toggle” using a single query?」を参考に

    UPDATE table SET flag = flag + 1 % 2 WHERE id = 127;

    と剰余を使ってできた。他の SQL 環境では MOD 関数を使って

    MOD(flag + 1, 2)

    のような感じなるだろう。

  • jQuery UI + Python で ajax な autocomplete

    社内向けシステムの使い勝手向上と、今後のシステム開発に向けてフォームにオートコンプリートをつけようと苦戦した記録。

    静的候補を表示する

    jQuery で autocomplete を実現しようとすると jQuery UI のお世話になる。参考にしたページはこちら。

    最も簡潔な実装方法は、フォームと同じファイルにリストを用意する方法。

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.css">
    https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js
    
    $(function() {
        var data = [
            'にんじん',
            'たまねぎ',
            'じゃがいも',
            'きゅうり'
        ];
        
        $('#item').autocomplete({
            source: data
        });
    });
    
    <title>autocomplete のサンプル</title>
    </head>
    <body>
    <input type="text" id="item" value="" />
    </body>
    </html>
    

    最も簡潔な例はこんな感じ。単に配列を用意するだけ。

    Ajax で動的に候補を読み込む

    これも同じサイトの別記事を参考にした。

    $(function() {
        $('#item').autocomplete({
            source: './autocomplete.py'
        });
    });
    

    パラメータ “source” を候補を取得する CGI 等にするだけで OK. CGI 側は候補を JSON で返せば良い。クライアント側の実装はこれで完了なのだが、サーバ側の実装で苦戦したのでそれについて記述する。

    動的候補を用意するサーバ側の実装

    今回は実装しているサーバの都合で Python による実装としている。(余談だが、PHP 使わなかったのは Linux PHP + FreeTDS + Windows SQL Server という特殊な環境でどうしても PHP のドライバが落ちて使えなかったから。ソースを修正してリビルド……というところまでしたけど、実用に持っていくのに手間がかかりすぎて使い慣れた Python  に逃げた)

    今になって冷静に読んでみると参考ページには書いてあるのだが、初めクライアントからの入力途中の値を得るのにフィールドの名前がわからずに随分と彷徨った。答えは簡単で、 term というフィールドがそれだ。

    なので例えば Python であれば

    import cgi
    
    form = cgi.FieldStorage()
    term = form.getfirst('term')

    という感じで取得する。

    取得した term を使ってデータベースなどに照会をかけて、得られた結果をクライアントに JSON 形式で返す。

    以下は簡潔にするため固定値の場合。

    import json
    
    data = [
        {label: 'にんじん', value: '00000001'},
        {label: 'たまねぎ', value: '00000002'},
        {label: 'きゅうり', value: '00000003'}
    ]
    
    print('Content-type: application/json; charset=UTF-8\r\n')
    print(json.dumps(data))

    Content-type を出力していないと 500: Internal Server Error をはいてしばらく悩んだ。

    Ajax でのデバッグは通信内容が目に見えないことも多いので、例えば IE なら F12 キーで Web 開発ツールを起動して Network の通信内容を見てみると原因を特定しやすい。