LoginSignup
4
2

More than 5 years have passed since last update.

kintone.events.on をハックする

Last updated at Posted at 2016-11-18

kintone使ってますか?

俺はけっこう使ってます。
みんなも使ったら良いじゃない。そしてプラグインを買ったらいいじゃない。(まだうちのリリースしてないけど……)
(リリースしました! よろしくお願いします)→『機能拡張スタンダード All-In』

kintoneでスクリプトを書いてると湧き上がってくる疑問のひとつに……
「ユーザー環境ではどこでイベントのオブジェクトが書き換えられてるかわかったもんじゃねーな」
があります。

地味に困るのは”フィールドにエラーを表示させるとそれまで変更した内容が全て無効化される”という点。
「ちまちま書き換えた内容が一瞬でパーなんじゃああああああ!」とばかりの結果になります。
「フィールドにエラー吐いてほしくないんじゃあああああ!」

実はいまですね

条件書式とか自動計算とかフィールドの入力値からテキスト自動生成とか、その他もろもろの基本的な機能拡張をゴリっとまとめたプラグインを最終デバッグ中です。
これらの機能はまとめておいた方がたぶん作る方も使う方も楽です。もうすぐリリース予定なのでその時はよろしくお願いします。

それはさておき

機能をモリモリと実装してる時に自動計算とエラー判定が競合して困ったのですよ。いやーあれは困った。半日くらい悩んでた。

これは対処のしようが無いです。サイボウズ様のご沙汰ですから。ええ、普通ならな
普通じゃない(サイボウズが絶対に推奨しないであろう)方法ならある。

その方法とは「せっかくだから俺はこのkintone.events.onを書き換えるぜ!」というもの。
なんとこのfunctionってconfigurableなのですね。(きっと「上書きしていいよ♪」というサイボウズの中の人の温情ですねこれは。うむ間違いないw)

そんなわけでちょっと書いてみました。
小一時間で急いで書いたものなので、最低限の動作テストはしたけど例のアレな感じです。「使ってみて何か酷い目にあっても知らんよ」と言っておきます。サーセン。ここは概念を学ぶためのインターネッツですw
ちょっと思いつくとこだと、falseを返したい場合とかに対応してないのでdelete.submitとかが絶対にキャンセルされなくなる。あとkintone.Promise返したいのとかね。要するに何を返したかったのかちゃんと見て調整しないとまるっきり同じというわけには行かない感じですか。
テストはとても大事

ぶっちゃけコードはこんな感じです

はぢめてのkintone.events.on
(function(){
    //private的なものども
    var refOriginalEventsOn = kintone.events.on; //ガチで上書きしちゃうわけないのでとりあえず退避的な
    var Events = {}; //コールバック退避用的な

    //それじゃあ遠慮なく書き換えさせてもらいやすぜサイボウズの旦那
    kintone.events.on = function(_events, _callback){

        //引数の補完と型保証をします的な
        if(typeof _events === "string"){ _events = [_events]; }
        if(!(_events instanceof Array) || (typeof _callback !== "function")){ return false; }

        //指定のイベントトリガーで走査して個別に設定するよ的な
        for(var i=0; i<_events.length; i++){

            //コールバック退避用のオブジェクトのキーにイベントトリガーがまだなければkintone.events.onに設定するよ的な
            if(!Events.hasOwnProperty(_events[i])){
                Events[_events[i]] = [];

                //kintoneイベントに登録しますわ的な
                // refOriginalEventsOnは元々のkintone.events.onを参照してます
                refOriginalEventsOn(
                    _events[i],
                    function(event){

                        //はいここテストに出ます
                        //Eventsには kintone.events.on で呼ばれるfunctionが入ってます。
                        //そいつを参照して実行してるので、あとから追加しても問題なく呼ばれるというすんぽうです。
                        //まあ難しい話ではないですな。

                        var fn = Events[event.type] || [];
                        for(var i=0; i < fn.length; i++){
                            fn[i](event); //ちゃんとやりたいヒトはこの戻り値を受け取っていろいろ対処する
                        }

                        //唯一の return event となるわけなんだなこれが
                        return event;
                    }
                );
            }

            //はいここもテストに出ます
            //というか対になってるとこですね。ここに追加するとあとで参照実行されます。
            Events[_events[i]].push(_callback);
        }
    };
})();

さてこのスクリプトをどこに置いたものか……

当然、他の処理が走る前ですわな。
kintone.events.on を書き換える前に設定されたものは触れることができません。
1. kintone全体のカスタマイズ
2. アプリのカスタマイズ
3. プラグイン
さあどれだ!?
プラグイン化は論外ですかね。意味ナス。
じゃあせっかくだからkintone全体にぶちかましますか!
いやいや。そんなクソ度胸いらんわ。心臓が毛むくじゃらでも情シスは尊敬してくれねーぜってな。
実はこの順番はいま(2016/11/18)確かめてみたところkintoneがスクリプトを読み込む順番なんですな。この仕様はどっかに書いてあるのかな?
プラグインが複数入ってる場合にそのなかでの順番がどうなるかはよく調べてないけど、たぶん調べる意味はないのでほっときます。
たぶん大事なのはプラグインより先に入れることです。

イベントトリガー丸裸!

これをやっとくとですね、ブラウザのデベロッパーモードとかでプラグインがどんなイベントトリガーをフックしてるのかゴンヌズバーと見れちゃうのですよ。
あとね、
return event;
の前に、eventの中身を調整することも当然できるわけです。
冒頭で吠えた問題点、
「フィールドにエラー吐いてほしくないんじゃあああああ!」
がなんと解決できる、とこういうわけです。

これにてハック終了、かどうかはわかりませんが。
そんな感じでーす。

4
2
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
4
2