13
13

More than 5 years have passed since last update.

jQueryしか使ってはいけないときの、適当なテンプレートエンジン

Posted at

jQueryしか使っちゃダメ!?

 そういう案件あるみたいです。
 でも、私はDOMいじりが苦手です。
 というか、入力値→表示値→入力値と行き来するのがすごくつらい。

なので、やっつけました。

動き

  • 初期化時に、指定したID以下にある、templateクラスがついたものを奪い取る。
  • updateイベントのハンドラを追加する。
  • updateイベントでは、データをデータ件数レンダリングしてHTMLをがさっと書き換える。

before.PNG

をテンプレートにして、

jquery_control.gif

こういう動きをさせる。

実装

template.js
(function(global) {
    if (!global.$kl) global.$kl = {};
    if (!global.$kl.t) global.$kl.t = {};
    var templates = {};
    var escapeMap = {
        '&': '&',
        '\x27': ''',
        '"': '"',
        '<': '&lt;',
        '>': '&gt;',
    };

    function escapeCallback(char) {
        if (!escapeMap.hasOwnProperty(char)) {
            throw new Error;
        }
        return escapeMap[char];
    }

    global.$kl.t.escapeHtml = function(str) {
        return String(str).replace(/[&"'<>]/g, escapeCallback);
    }
    global.$kl.t.getTemplate = function(holderId) {
        var template = $("#" + holderId + " > .template").prop('outerHTML');
        $("#" + holderId + " > .template").remove();
        return template;
    }
        //テンプレートを奪い取ってしまうやつ
    global.$kl.t.setupTemplate = function(holderId) {
        templates[holderId] = global.$kl.t.getTemplate(holderId);
        //Updateされたら、中身を再度レンダリングして更新する
        $("#" + holderId).on('update', function(e, params) {
            //独自イベント:レンダリング
            $("#" + holderId + " > .template").remove();
            var all = "";
            var data = params.list;
            if (params.list.length == 0) {
                $("#" + holderId).css('display', 'none');
                return;
            }
            $("#" + holderId).css('display', '');
            for (var k in data) {
                var row = templates[holderId];
                row = row.replace(/\{\{(.*?)\}\}/g, function(all, key) {
                    return !data[k][key] ? "" : data[k][key];
                });
                row = row.replace(/\{(.*?)\}/g, function(all, key) {
                    return !data[k][key] ? "" : global.$kl.t.escapeHtml(data[k][key]);
                });
                all += row;
            }
            $("#" + holderId).html(all);
        });
        $("#" + holderId).trigger('update', {
            list: []
        });
    }

})((this || 0).self || global);

使い方

hoge.html

<input type="text" id="search" onkeyup="doSearch()">

<div id="lookup_list" style="position:absolute;background-color:white;z-index:10;border:1px solid black;height:auto">
    <div class="template" onclick="select('{code}')">{code}:{name}</div>
</div>

<scirpt>
    $(document).ready(function() {
        $kl.t.setupTemplate("lookup_list");
    }
    function doSearch() {
        var searchKey = $("#search").val();
        $.ajax({
            'url': './search.php',
            'dataType': 'json',
            'data': {
                searchkey: searchKey
            }
        }).then(function(result) {
            $("#lookup_list").trigger('update', {list:result});
        });
    }
</script>

※search.phpはこんな結果を返します。

[
    {"code":"aaaa","name":"ああああ"},
    {"code":"aaai","name":"あああう"},
    {"code":"aaau","name":"あああえ"}
]
13
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13