チャットアプリにメッセージの編集と削除ボタンをつける(非同期通信対応版)

以前[チャットアプリにメッセージの編集と削除ボタンをつけた](https://qiita.com/sakuraniumarete/items/ed71654c6d50e8a88adc)のですが、
機能追加をしていくうちに、この追加した項目は非同期通信で表示させたり非表示にした方が
いいんじゃないかと思うようになりまして、今回変更しましたのでそれをまとめたいと思います。

次回、[チャットアプリでメッセージの編集と削除のAjax処理を実装する](https://qiita.com/sakuraniumarete/items/9eed397eb3597dcdb952)も投稿しました！

# 今回の目的
チャットアプリにメッセージの編集と削除ボタンを非同期通信で表示させる

# 完成イメージ
![メッセージ編集削除ボタンイメージ.gif](https://qiita-image-store.s3.amazonaws.com/0/332038/860401e6-7292-6674-2229-4291000d9283.gif)
*自分の投稿のみ表示させて、違う場合は表示しない

# 環境
ruby 2.3.1
Rails 5.0.7.2

# 今回記載すること
今回は変更したメイン部分だけ記載させていただきます。
他ソースは下記Githubをご参照ください。

[chat-space](https://github.com/ham357/chat-space)

# 変更したコード
```app/assets/javascripts/mouse_hover_action.js
$(function() {
  var message_element;
  var message_menu_element;
  var current_user_id = $('.side-header__box__user-name').attr("data-current_user_id");

  function message_btn_build() {
    var html = '<ul class="message__upper-info__menu"><li class="message__upper-info__edit-message"><i class="fa fa-pencil-square-o"></i></li><li class="message__upper-info__destroy-message"><i class="fa fa-times"></i></li></ul>';
    message_element.append(html);
  }  
  $(document).on({
    "mouseenter": function(){
      if(!$('.InlineEdit-active')[0]) {
        var message_user_id = $(this).attr("data-user_id");
        if (current_user_id == message_user_id){
          message_element = $(this).find('.message__upper-info');
          message_btn_build();
        }
      }
    },
    "mouseleave": function(){
      message_menu_element = $(this).find('.message__upper-info__menu');
      message_menu_element.remove();
    }
  }, ".message");

});
```
まず上記が今回変更が完了したコードです。
それぞれの処理を説明しますと
```「(document).on({"mouseenter": function(){}」```
上記でマウスにカーソルが乗った時の処理を記載しています。また
```"mouseleave": function(){}```
上記でカーソルが離れた時の処理を記載しています。
```}, ".message");```
最終行の上記は対象の要素を指定しています。
また```if(!$('.InlineEdit-active')[0]) {}```では編集状態である要素が無ければ行うようにしています。
次回[編集処理](https://qiita.com/sakuraniumarete/items/9eed397eb3597dcdb952)で編集状態の場合は「InlineEdit-active」クラスを追加しています。
上記が制御が無いと複数編集状態にすることが可能になってしまい特に意味も無いため、編集するのは一つずつ行うという仕様にするためです。

### メッセージ編集と削除ボタンの表示と非表示
```app/assets/javascripts/mouse_hover_action.js
function message_btn_build() {
    var html = '<ul class="message__upper-info__menu"><li class="message__upper-info__edit-message"><i class="fa fa-pencil-square-o"></i></li><li class="message__upper-info__destroy-message"><i class="fa fa-times"></i></li></ul>';
    message_element.append(html);
  }  
```
「.message」要素にカーソルが乗った際、```message_btn_build()```メソッドを呼び出し表示を行なっています。
またカーソルが離れた際には```message_menu_element.remove()```で表示したボタンを削除しています。

### 自分の投稿したメッセージ以外は編集と削除ボタンは表示させない
```app/assets/javascripts/mouse_hover_action.js
if (current_user_id == message_user_id){
      message_element = $(this).find('.message__upper-info');
      message_btn_build();
    }},
```
```if (current_user_id == message_user_id)```
ちょっと無理やり感はあるのですが、上記if文により自分の投稿したメッセージかどうかを判別するようにしました。
それぞれのid情報はHTMLのタグ属性から取得しています。タグ属性にid情報を追加するように下記のようにviewファイルを変更しております。

```app/views/shared/_side_bar.html.haml
.chat-side
  .side-header
    .side-header__box
      %p.side-header__box__user-name
      %p.side-header__box__user-name{"data-current_user_id" => "#{current_user.id}"}
        = current_user.name
      %ul.side-header__box__menu
        %li.side-header__box__menu__edit-user
```
```%p.side-header__box__user-name{"data-current_user_id" => "#{current_user.id}"}```
上記部分の「{"data-current_user_id" => "#{current_user.id}"}」でView表示の際にログインしているユーザーのid情報を追加しています。
続いてメッセージを投稿したユーザーのid情報です。

```app/views/messages/_message.html.haml
.message{"data-id" => "#{message.id}","data-user_id" => "#{message.user.id}"}
  .message__upper-info
    %p.message__upper-info__talker
      = message.user.name
```
```"data-user_id" => "#{message.user.id}"```を追加しています。
View表示の際にメッセージを投稿したユーザーのid情報を取得しています。

### 他の修正点
現在メッセージが投稿された際に非同期で投稿したメッセージを表示するようになっております。
今回上記にてid情報を追加したため、投稿したメッセージを表示する際にid情報も追加します。
投稿したメッセージが自分が投稿したものか判別ができないためです。

```app/assets/javascripts/message.js
# 一部抜粋
var html = `<div class="message" data-id="${ message.id }" data-user_id="${message.user_id}"}>
```
こちらにも```data-user_id="${message.user_id}"```を追加しました。
そして投稿したメッセージのid情報「message.user_id」を取得するため、「create.json.jbuilder」も下記のように追記します。

```app/views/messages/create.json.jbuilder
#下記を追記
json.user_id  @message.user.id
```
処理とは関係ないですが、下記の方が処理の内容がわかりやすいと思ったのでファイル名を変更しています。
```mouseover_out_btn.js →　mouse_hover_action.js```

以上です。
次回は今回追加した編集と削除ボタンの処理を実装します。
宜しければ、こちらもどうぞ！
[チャットアプリでメッセージの編集と削除のAjax処理を実装する](https://qiita.com/sakuraniumarete/items/9eed397eb3597dcdb952)

少しでも参考になりましたら、いいねやフォロー気軽にしていただけると励みになります！＼(^o^)／

# 参考
[".on()"での"hover"の記述でつまずいたので](http://blog.seeds-std.co.jp/entry/1586.html)
[jQueryのhover()でマウスオーバーの処理](https://www.flatflag.nir87.com/hover-1691)
[jQueryのonメソッドでhoverを使う](https://cgsc.info/programming/20151208_jquery_on-hover)