頻繁に発生する転記作業を省力化するブックマークレットを作ってほしいです。

A・B2つのASPシステムがあり、ブックマークレットXでAの表示内容をクッキーに保存し、ブックマークレットYでBのフォームに1クリックで転記したいです。

■A画面
<FORM method="POST"> (name, idなし)
<input type="hidden" name="company" value="はてな">はてな
<input type="hidden" name="guest" value="しなもん">しなもん
…(10項目ぐらいある)
</FORM>

■B画面
<FORM name="contact" method="POST" action="…">
<input type="text" name="company_name" id="company" value="" /> ←「はてな」と入れたい
<input type="text" name="guest_name" id="company" value="" /> ←「しなもん」と入れたい

</FORM>

※AとBでは各項目のnameが一致していません。
※項目の順番についてはBの項目を並べ替えることで揃えることができます。

よろしくお願いします。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2013/09/13 12:26:11
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:a-kuma3 No.1

回答回数4974ベストアンサー獲得回数2154

ポイント1500pt

ざくっと書いてみました。
幾つかの前提があります。

  • クッキーを介してデータを受け渡すので、A・B二つのシステムのドメインが同一である必要があります。
    例えば、システムA:http://main_A.hogehoge.co.jp、システムB:http://sub_B.hogehoge.co.jp というように。
  • コピー元のフォームの探し方が明示されていないので、company という項目を持つフォームをコピー対象としています
  • 互いのフォームの項目名の対応付けのルールが分からなかったので、対応テーブルを持たせています
  • クッキーの有効期間は一時間としています
  • URL に詰め込むには、ちょっと厳しいので、外部スクリプトとしています(使い方は後述)

まず、フォームの内容をクッキーに保存するスクリプト。

(function() {
    var COOKIE_NAME = "capsuleq_form_item";
    var KEY_VALUE_SEP = "☆☆☆";
    var ITEM_SEP = "★★★";

    function find_form() {
        var f = document.getElementsByTagName("FORM");
        for (var i = 0 ; i < f.length ; ++i) {
            for (var j = 0 ; j < f[i].length ; ++j) {
                if (f[i].elements.item(j).name == "company") {
                    return f[i];
                }
            }
        }
    }

    var f = find_form();
    if (f) {
        var vv = [];
        for (var i = 0 ; i < f.length ; ++i) {
            vv.push(f.elements.item(i).name + KEY_VALUE_SEP + f.elements.item(i).value);
        }
        var s = vv.join(ITEM_SEP);

        s = COOKIE_NAME + "=" + escape(s) + "; ";
        s += "path=/; ";
        s += "expires=" + (new Date(new Date().getTime() + 60*60*1000).toUTCString()) + "; ";
        
        // クッキーに保存
        document.cookie=s;
    }
})();

次に、クッキーに保存したデータをフォームに貼り付けるスクリプトです。

(function() {
    var COOKIE_NAME = "capsuleq_form_item";
    var KEY_VALUE_SEP = "☆☆☆";
    var ITEM_SEP = "★★★";

    var re = new RegExp(COOKIE_NAME + "=([^;]*);?");
    var match = re.exec(document.cookie);
    if (match) {
        var s = unescape(match[1]);

        // コピー元の項目名 → ペースト先の項目名
        var key_map = {
                        'company' : 'company_name' ,
                        'guest'   : 'guest_name'   ,
                        'from_a'  : 'to_a'         ,
                        'from_b'  : 'to_b'         ,
                        'from_c'  : 'to_c'         ,
                        'from_d'  : 'to_d'         ,
                        'from_e'  : 'to_e'         ,
                        'from_f'  : 'to_f'         ,
                        'from_g'  : 'to_g'         ,
                        'from_h'  : 'to_h'         ,
                        'from_i'  : 'to_i'         ,
                        'from_k'  : 'to_k'         ,
                    }
        var arr = s.split(ITEM_SEP);
        var value_map = {}
        for (var i in arr) {
            var kv = arr[i].split(KEY_VALUE_SEP);
            value_map[ key_map[kv[0]] ] = kv[1];
        }

        var f = document.getElementsByName("contact");
        if (f[0]) {
            for (var i = 0 ; i < f[0].length ; ++i) {
                var item = f[0].elements.item(i);
                if (value_map[item.name]) {
                    item.value = value_map[item.name];
                }
            }
        }
    }
})();

クッキーに保存するときの名前、データを区切るための文字列(×2)は、仮に決めましたが、その ASP のシステムのクッキーとして保存されるので、できるだけ変な値(というか、ユニークになるような値)にしてください。
両方のスクリプトとも、先頭の方に書いてありますので。



使い方についてです(知っているのであれば、読み飛ばしてください)。

ブックマークレットで外部スクリプトを取り込む場合、ローカルのファイルにはアクセスできず、http を介する必要があります。
スクリプトを置くことができるサーバを探すか、ローカルに Apache や IIS を建てます。
ローカルにサーバを建てて、それぞれを scripts/ 配下の copy.js 、paste.js とした場合、それぞれのブックマークレットは、以下のようになります。

・フォームの内容を保存する

javascript:(function(src){var%20s=document.createElement('script');s.setAttribute('type','text/javascript');s.setAttribute('charset','UTF-8');s.setAttribute('src',src);document.body.appendChild(s);})('http://localhost/scripts/copy.js');


・保存した内容をフォームに貼りつける

javascript:(function(src){var%20s=document.createElement('script');s.setAttribute('type','text/javascript');s.setAttribute('charset','UTF-8');s.setAttribute('src',src);document.body.appendChild(s);})('http://localhost/scripts/paste.js');



「ローカルに Apache を建てるのはなあ...」ということであれば、Hatena::Let が使えると思います(その代わり、外部と接続できる環境である必要があります)。
Hatena::Let は、こちら(はてラボからたどれます)。
http://let.hatelabo.jp/

ログインした後に、それぞれのスクリプトを入力して、「公開」とします。
http://let.hatelabo.jp/images/config-icon-advanced-on.png のアイコンか、その横のタイトル名を右クリックしてブックマークします。

試しに、自分でも置いてみました。

ぼくが保存したやつは、消しちゃうかもしれないので、ご自分のブックマークレットとして保存して使ってください。





クッキーが使えなさそうだ、ということで HTML5 の Web Storage を使うように変えてみました。
と言っても、ちょっとだけです。

まず、フォームの内容を Web Storage に保存するスクリプト。

(function() {
    var KEY_NAME = "capsuleq_form_item";
    var KEY_VALUE_SEP = "☆☆☆";
    var ITEM_SEP = "★★★";

    function find_form() {
        var f = document.getElementsByTagName("FORM");
        for (var i = 0 ; i < f.length ; ++i) {
            for (var j = 0 ; j < f[i].length ; ++j) {
                if (f[i].elements.item(j).name == "company") {
                    return f[i];
                }
            }
        }
    }

    var f = find_form();
    if (f) {
        var vv = [];
        for (var i = 0 ; i < f.length ; ++i) {
            vv.push(f.elements.item(i).name + KEY_VALUE_SEP + f.elements.item(i).value);
        }
        var s = vv.join(ITEM_SEP);

        // Web Storage に保存
        localStorage.setItem(KEY_NAME, escape(s));
    }
})();

次に、Web Storage に保存したデータをフォームに貼り付けるスクリプトです。

(function() {
    var KEY_NAME = "capsuleq_form_item";
    var KEY_VALUE_SEP = "☆☆☆";
    var ITEM_SEP = "★★★";

    var s = localStorage.getItem(KEY_NAME);
    if (s) {
        s = unescape(s);

        // コピー元の項目名 → ペースト先の項目名
        var key_map = {
                        'company' : 'company_name' ,
                        'guest'   : 'guest_name'   ,
                        'from_a'  : 'to_a'         ,
                        'from_b'  : 'to_b'         ,
                        'from_c'  : 'to_c'         ,
                        'from_d'  : 'to_d'         ,
                        'from_e'  : 'to_e'         ,
                        'from_f'  : 'to_f'         ,
                        'from_g'  : 'to_g'         ,
                        'from_h'  : 'to_h'         ,
                        'from_i'  : 'to_i'         ,
                        'from_k'  : 'to_k'         ,
                    }
        var arr = s.split(ITEM_SEP);
        var value_map = {}
        for (var i in arr) {
            var kv = arr[i].split(KEY_VALUE_SEP);
            value_map[ key_map[kv[0]] ] = kv[1];
        }

        var f = document.getElementsByName("contact");
        if (f[0]) {
            for (var i = 0 ; i < f[0].length ; ++i) {
                var item = f[0].elements.item(i);
                if (value_map[item.name]) {
                    item.value = value_map[item.name];
                }
            }
        }
    }
})();

それぞれの使い方は、先に書いた回答と同じです。

他4件のコメントを見る
id:capsuleq

paste.jsの中で、
Bのフォーム遷移途中へ直接値を渡すようにHTMLを入れてみたら動作し、
思い通りの動作が出来そうです。

ありがとうございました!
仕事の手間が減り、また同時に勉強になりました。

2013/09/13 12:25:43
id:a-kuma3

すみません、終盤は自己解決でしたね X-(
いくばくかのお役には立てたようで、ほっとしてます。

2013/09/13 13:14:06

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません