簡単にいうと、この図の通りになってしまうのですが、自分が社内でWebツールを作ったときの備忘録として載せておきます。
いまさらjQueryという感も否めませんが、スクラッチでなにか動くもの(デモ)を作るときに、肩肘張らなくていいので大好きです。
このツールは、とある番号から該当するファイル一覧を表示し、そのファイル名をクリックするとソースコード内の修正候補を表示するというものです。
とにかくCDN
読み込むものは以下の通りです。
- jQuery
- jQuery UI
- Font Awesome
- Google Code Prettify
1 2 3 4 5 |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet"> <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=sons-of-obsidian"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script> <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"> |
jQueryは説明不要かと思います。Font AwesomeはWebFontを使ったアイコンセットで、Google Code Prettifyはソースコードのシンタックスハイライトをしてくれるライブラリです。
Formの内容をAjaxで送信
とある番号を送出するときに、Formをシリアライズしています。別に単なる番号を送るだけなので、自前でオブジェクトを作ってもよいのですが、検索オプションをつけたりする可能性も考えてこのような作りにしました。
以下は最初に表示されるHTML部分の肝となるコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<form name="eqt_srch"> <input name="eqt_id" type="text" value=""> <input name="eqt_snd" type="submit" value="検索"> </form> <div id="pickupinfo"></div> <div> <h2><i class="fas fa-list-ul"></i>対象ファイル一覧</h2> <div id="filesArea"></div> </div> <div> <h2><i class="fas fa-code"></i>修正候補ソース表示</h2> <div> <h3 id="filename"></h3> <div id="srcView"></div> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
jQuery(function($){ // 2秒応答がなかったらエラーにする $.ajaxSetup({ timeout: 2000 }); // とある番号入力 $('form[name="eqt_srch"]').on('submit',function(){ var url = "filePickUp.php"; var obj = $(this).serialize(); var jqxhr = $.post(url, obj); // 表示の初期化 $('#filesArea').empty(); $('#srcView').empty(); $('#fileinfo').empty(); $('#filename').empty(); //成功したときの処理 jqxhr.done(function(data){ var returnObj = {}; try { returnObj = JSON.parse(data); } catch (error) { console.log(data); $('#pickupinfo').text(data); return; } $('#pickupinfo').text(''); // 対象ファイル一覧に展開 $('#filesArea').empty(); $.each(returnObj, function(k, v){ $('#filesArea').append('<div class="partNo" data-pn="' + k + '"><h3>とある番号:' + k + '</h3><ul data-pn="' + k + '"></ul></div>'); $.each(v, function(kk, vv){ var cName = vv.err?'fa-exclamation-circle':'fa-check'; $('#filesArea ul[data-pn="' + k + '"]').append('<li data-fp="' + vv.pass + '" data-pn="' + k + '"><input type="checkbox"><i class="fas ' + cName + '"></i>' + vv.pass + '</li>'); }); }); }); // 失敗したときの処理 jqxhr.fail(function(){ console.log("error"); }); //常に行う処理 jqxhr.always(function(){ console.log("always"); }); // 通常のFormの動きを抑止 return false; }); }); |
ポイントがいくつかあります。
- アイコンは「<i class=”fas fa-file-video”></i>」という感じで表示できます。Font Awesomeのページでアイコンを検索してコードをコピペしてください。CSSで文字として扱うことで大きさや色を変更することもできます。
- Ajaxのデフォルト設定ではタイムアウトが設定されていないので、2秒で設定しています。
- Formのserializeをするときには、通常送信するときと同様にnameを設定しておかねばなりません。
- jsonをparseするときはtry-catch文を使います。(ここではうまく行けば正常処理で、失敗すれば受け取ったデータをエラー文字列として表示しています。)
- formのsubmitイベントをトリガーにしているので、このままだと自分自身にPOSTをしてしまうため、最後にreturn falseをして抑止します。
- 「対象ファイル一覧に展開」の部分は、次のPHP部分を参照してください。
以下がAjaxで叩いているPHP部分(いわゆるAPI)です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php $eqt_id = null; // POSTデータ展開 foreach ( $_POST as $key => $val ) { ${ $key } = $val; } /* エラーがあれば、エラー文をechoしてdie。 うまく処理できれば、$target_fileに各ディレクトリごとのファイル一覧の配列 ※ファイル一覧の配列の下に連想配列がぶら下がっています。 $target_file[ディレクトリ名][数字] = array("pass" => ファイルパス, "err" => エラーの有無) */ echo str_replace('\/','/',json_encode($target_file)); |
PHP 5.4.0 以降でjson_encodeのオプションにJSON_UNESCAPED_SLASHESを使用可能です。それ以前の場合は「/」のエスケープを自力で削る必要があります。
一覧のファイル名をクリック
一覧のファイル名をクリックして個々のファイルを解析していきます。今度はjsonは使わず、受け取ったデータをそのままDOMの中に突っ込んでいきます。
追記したJSの部分は以下の通りとなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
jQuery(function($){ // 2秒応答がなかったらエラーにする $.ajaxSetup({ timeout: 2000 }); // とある番号入力 $('form[name="eqt_srch"]').on('submit',function(){ var url = "filePickUp.php"; var obj = $(this).serialize(); var jqxhr = $.post(url, obj); // 表示の初期化 $('#filesArea').empty(); $('#srcView').empty(); $('#fileinfo').empty(); $('#filename').empty(); //成功したときの処理 jqxhr.done(function(data){ var returnObj = {}; try { returnObj = JSON.parse(data); } catch (error) { console.log(data); $('#pickupinfo').text(data); return; } $('#pickupinfo').text(''); // 対象ファイル一覧に展開 $('#filesArea').empty(); $.each(returnObj, function(k, v){ $('#filesArea').append('<div class="partNo" data-pn="' + k + '"><h3>とある番号:' + k + '</h3><ul data-pn="' + k + '"></ul></div>'); $.each(v, function(kk, vv){ var cName = vv.err?'fa-exclamation-circle':'fa-check'; $('#filesArea ul[data-pn="' + k + '"]').append('<li data-fp="' + vv.pass + '" data-pn="' + k + '"><input type="checkbox"><i class="fas ' + cName + '"></i>' + vv.pass + '</li>'); }); }); }); // 失敗したときの処理 jqxhr.fail(function(){ console.log("error"); }); //常に行う処理 jqxhr.always(function(){ console.log("always"); }); // 通常のFormの動きを抑止 return false; }); // 一覧のファイル名をクリック $('#filesArea').on('click', 'li', function(e){ $('#filesArea li').removeClass('select'); $(this).addClass('select'); var url = "sourceDiff.php"; var obj = {fp:$(this).data('fp')}; var link = obj.fp.split('../').join('').split('/'); var fn = link.pop(); link = link.join('/'); $('#filename').html('<i class="far fa-folder-open"></i>' + fn); var jqxhr = $.post(url, obj); //成功したときの処理 jqxhr.done(function(data){ console.log(data); $('#srcView').html(data); PR.prettyPrint(); }); // 失敗したときの処理 jqxhr.fail(function(){ console.log("error"); }); //常に行う処理 jqxhr.always(function(){ console.log("always"); }); }); }); |
ポイントの多くは「sourceDiff.php」のほうにあるのですが、このファイルはいわゆる社内ツールのごちゃごちゃしたコードなので、開示しても意味もわからなければ参考にもならないので、コード自体は割愛させていただきます。
- ajaxがsuccessしたら「PR.prettyPrint();」をしてシンタックスハイライトのJSを動かす。
- 「sourceDiff.php」でのechoでscriptタグを出力してjQuery(function($){});の中に処理を書けば、Ajaxのsuccess時に動く。
- Google Code Prettifyはそのpreタグのclassに「linenums:数字」を追加すれば(もちろん「prettyprint」も必要)その行番号から始まる。
最後に
これはベストプラクティスではないですが、書き散らせるのがjQueryの楽しさでもあります。例えるなら、方眼紙にフリーハンドでフロー図を書いている気分です。
フレームワークはプロトタイプを作ってから導入を検討したらいいのではないでしょうか。