PAGE TOP


hoverさせた項目より、クリックでフォームに文字を挿入する

2017年11月15日Javascript

実装概要

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>