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>