Search code examples
javascriptphplaravellaravel-livewireunicode-string

Input Value set by javascript returning empty in controller in PHP


Good morning my friends,

I'm creating a small chat in lan, and i decided to put some emojis. However, when I retrieve the value from input, and add the chosen emoji to it, if I don't do more manual additions to the input string, PHP receives the emoji as empty.

chat-room.blade.php - Here I create a balloon with emojis created by the unicode range

<div class="container-fluid" id="emoji-list" style="display: none; height: 0; width: 0;">
   <div id="emoji-scroll">
   @php
      $emojiUnicodeRange = [[0x1f600, 0x1f64e], [0x1f910, 0x1f91e], [0x1f920, 0x1f927], [0x1f300, 0x1f5ff], [0x1f680, 0x1f6c1], [0x1f950, 0x1f95e], [0x1f980, 0x1f991]];
   @endphp
   @foreach ($emojiUnicodeRange as $range)
      @for ($emojiUnicode = $range[0]; $emojiUnicode <= $range[1]; $emojiUnicode++)
         <span id="{{ html_entity_decode('&#' . $emojiUnicode . ';', 0, 'UTF-8') }}" class="emoji-item" onClick="inserirEmoji(this.id)">{{ html_entity_decode('&#' . $emojiUnicode . ';', 0, 'UTF-8') }}
         </span>
      @endfor
   @endforeach
   </div>
</div>

chat-room.blade.php - Here is the button that opens the emoji balloon and the input text

<span id="show-emoji-list" onclick="showEmojiList()">
       <i class="far fa-grin" aria-hidden="true"></i>
</span>
    <input wire:model="body" type="text" class="form-control input-sm rounded" id="msg-input" placeholder="Escreva sua mensagem...">

chat-room.blade.php - Here are the js functions I use to open and close the emoji balloon, and to insert the emoji clicked into the input

var emoji_list = document.getElementById('emoji-list');

function showEmojiList() {
   if (this.emoji_list.style.display == 'none') {
      this.emoji_list.style.display = 'block';
      this.emoji_list.style.height = '200px';
      this.emoji_list.style.width = '90%';
   } else {
      this.emoji_list.style.display = 'none';
      this.emoji_list.style.height = '0';
      this.emoji_list.style.width = '0';
   }
}

function inserirEmoji($id) {
   var input = document.getElementById('msg-input');
   var emoji = document.getElementById($id);
   input.value = input.value + emoji.id;
   this.emoji_list.style.display = 'none';
   this.emoji_list.style.height = '0';
   this.emoji_list.style.width = '0';
   input.focus();
}

ChatRoom.php - This is the chat controller

public function sendMessage(Request $request)
{
   $user = $request->user();
   $room = $this->room;
   $body = $this->body;
   dd(html_entity_decode($body));
   if (!$body) {
      $this->addError('body', 'Digite uma mensagem.');
      return;
   }
   $message = Message::create([
       'body' => $body,
       'user_id' => $user->id,
       'room_id' => $this->room->id
   ]);
        
   event(new MessageCreated($user, $room, $message));
   return view('livewire.chat-room')->with(compact('room'));
}

The dd(); called on the 6th line returns an empty string unless I type something along with the inserted emoji, and if I type something and insert the emoji later, the emoji comes empty in the string...

PS: chat-room.blade.php - It's a Laravel/Livewire component blade


Solution

  • The secret is here: Inside the javascript inline function that populates the input with the chosen Emoji, as soon as it populates the input, it should update the value of the Livewire wire:model calling:

    @this.set('body', input.value);
    
    function inserirEmoji($id) {
       var input = document.getElementById('msg-input');
       var emoji = document.getElementById($id);
       input.value = input.value + emoji.id;
       @this.set('body', input.value);
       this.emoji_list.style.display = 'none';
       this.emoji_list.style.height = '0';
       this.emoji_list.style.width = '0';
       input.focus();
    }