hoverさせた項目より、クリックでフォームに文字を挿入する
実装概要
hoverさせた項目メニューをクリックした時にフォームに文字を挿入することをやってみます。
実装にあたっては、まずjQueryを読み込ませておく必要があります。
手順としては、まず、ある要素にカーソルがきた時点でhoverさせる。次に、hoverしたメニューをクリックした時に、フォームに文字を挿入するという流れです。
マウスがのっているかのっていないかの判定
まずは、htmlでテーブルを組みますが、その際に、hoverさせるulメニューをつくりますが、これは、hoverした時に、show()メソッドに表示したいので、ulを style=”display: none;で隠しておきます。
<table class="table"> <thead> <tr> <th>no</th> <th> </th> <th>意味</th> <th>単語</th> </tr> </thead> <tbody> <tr> <td>1</td> <td> <div class="insert"><div class="button">▲</div> <ul class="insert_character" style="display: none;"> <li class="verb">動</li> <li class="adjective">形</li> <li class="noun">名</li> <li class="adverb">副</li> <li class="conjunction">接</li> <li class="preposition">前</li> </ul> </div> </td> <td> <input type="text" name="" value=""> </td> <td id="td_1"> <input type="text" name="" value=""> </td> <td> <button type="button">削除</button> </td> </tr> </tbody> <tfoot> <tr> <td colspan="2"> <button type="button">追加</button></span> </td> </tr> </tfoot> </table>
次に、javascriptの部分ですが、hover()を使って、insertクラスの上にhoverした際に、ulをshow()で表示させます。また、離れた場合は、hide()で隠します。
$('.insert').hover( function(){ $(this).children("ul").show(); },function() { $(this).children("ul").hide(); });
ただこれだけでは不十分で、メニューが上に表示されませんので、CSSを編集する必要があります。
CSSは次のようにします。ポイントとしては、ベースとなるクラスのポジションをposition: absolute;で指定し、hoverさせたいクラスのポジションをposition: relative;とし、z-indexで重なりを指定します。
<style> .insert{ position: absolute; margin: 0px; padding: 0px; text-align: left; } .insert_character{ position: relative; top: -65px; height:25px; z-index: 2; border:1px solid black; margin: 0; text-align: left; background:#D3D3D3; padding: 2px; } ul.insert_character { border:1px solid black; padding:2px; font-size:0px; } ul.insert_character li { width:23px; border:1px solid black; display: inline-block; text-align: center; font-size:13px; padding:2px; background: #F5F5F5; } ul.insert_character li:hover{ color: #FFD700; background: #000000; text-decoration: none; } .button{ position: relative; top: -15px; right: 2px; } </style>
クリックしたら挿入する
hoverさせたメニューをクリックした場合、まずは、val()でフォームの値を取得します。次に、取得したデータの後ろに、挿入する文字を付け加えて、val()で挿入します。また、フォーム上のカーソルは、挿入した後においておきたいのでfocus()を使います。
$('.verb').click(function() { var elements = $(this).parent().parent().parent().next().children(); var data = String(elements.val()); elements.val( data + '[動]' ).focus(); });
また、同様に、そのたのメニュー項目も、書いていきますが、ほとんどが共通しているので、このあたりは関数化します。
<script> $(function() { $('.insert').hover( function(){ $(this).children("ul").show(); },function() { $(this).children("ul").hide(); }); function insert(c, w){ $(c).click(function() { var elements = $(this).parent().parent().parent().next().children(); var data = String(elements.val()); elements.val( data + w ).focus(); }); } insert('.verb','[動]'); insert('.adjective','[形]'); insert('.noun','[名]'); insert('.adverb','[副]'); insert('.conjunction','[接]'); insert('.preposition','[前]'); }); </script>
on()で実装すると
上記のやり方では、hover()やchick()メソッドを使用していますが、このメソッドの場合は、例えば、動的に追加したフォームに適用されません。そこで、動的に追加した要素にも適用させるためには、on()メソッドを使用します。下記のコードは、上記で書いたものをon()メソッドに置き換えてみました。動作は同じですが、動的に追加したフォームにも適用されるようになります。
<script> $(function() { $(document).on('mouseenter','.insert',function(){ $(this).children("ul").show(); }); $(document).on('mouseleave','.insert',function(){ $(this).children("ul").hide(); }); function insert(c, w){ $('table').on('click', c, function() { var elements = $(this).parent().parent().parent().next().children(); var data = String(elements.val()); elements.val( data + w ).focus(); }); } insert('.verb','[動]'); insert('.adjective','[形]'); insert('.noun','[名]'); insert('.adverb','[副]'); insert('.conjunction','[接]'); insert('.preposition','[前]'); }); </script>
フォームのカーソル位置に挿入できるようにする
上記のやり方では、.val()取得、文字列の末尾に、付け加えて、書き換えを行ったあとに、.focus()で、末尾にカーソルをもってきているだけなので、どうしても、後ろに文字が挿入されてしまうので、場合によっては不便です。そこで、文字列の中に挿入するように改良してみたいと思います。
ポイントとしては、jQueryで取得した、要素情報は、変数elementsに入れておいて、そこからget(0).で必要な情報のみ取得して、加工して最後に、書き換えるといった感じです。
<script> $(function() { $(document).on('mouseenter','.insert',function(){ $(this).children("ul").show(); }); $(document).on('mouseleave','.insert',function(){ $(this).children("ul").hide(); }); function insert(c,w){ $('table').on('click', c, function(e) { var elements = $(this).parent().parent().parent().next().children(); var sentence = String(elements.val()); //文字列取得 var len = sentence.length; //文字列の長さ var pos = elements.get(0).selectionStart; //カーソル位置 var before = sentence.substr(0, pos); //カーソルの前にある文字列 var after = sentence.substr(pos, len); //カーソルの後にある文字列 sentence = before + w + after; //合体させる elements.val( sentence ).focus(); //書き換える //カーソル位置を挿入後の位置に変更 elements.get(0).selectionStart =(before + w).length; elements.get(0).selectionEnd=(before + w).length; }); } insert('.verb','[動]'); insert('.adjective','[形]'); insert('.noun','[名]'); insert('.adverb','[副]'); insert('.conjunction','[接]'); insert('.preposition','[前]'); }); </script>