Toggle switch for Model field Livewire - laravel

I'm trying to implement a slider checkbox that automatically updates a field in my Post column.
Here's my css
.toggle-checkbox:checked {
#apply: right-0 border-green-400;
right: 0;
border-color: #68D391;
}
.toggle-checkbox:checked + .toggle-label {
#apply: bg-green-400;
background-color: #68D391;
}
And this is my toggle button component
namespace App\Http\Livewire\Admin\Table;
use Illuminate\Database\Eloquent\Model;
use Livewire\Component;
class Published extends Component
{
public Model $model;
public string $field;
public bool $isPublished;
public function mount()
{
$this->isPublished = (bool) $this->model->getAttribute($this->field);
}
public function render()
{
return view('livewire.admin.table.published');
}
public function updating($field, $value)
{
$this->model->setAttribute($this->field, $value)->save();
}
}
This is my blade for the toggle button
<div>
<div class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in bg-red-300">
<input wire:model="isPublished" type="checkbox" name="toggle" id="toggle" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer" />
<label for="toggle" class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"></label>
</div>
</div>
This is the parent component for the toggle button
#foreach ($values as $value)
<td class="px-4 py-3">
#livewire('admin.table.published', ['model' => $value, 'field' => 'status'], key($value->id))
</td>
#endforeach
mount method seems to work fine, but whenever I try the updating method, it updates a different ID. Can anyone help? Thanks!
I'm using Php 7.3 ; Laravel 8.75; livewire 2.10

Related

Summernote or any other wygiwys in laravel liveware that will show text in textarea :(

I have a question and problem with how to show edited text in WYSIWYG textarea. It didn't show up :(
I tried with summernote and ckeditor and always the same, it didn't show up and shows an empty textarea.
Idea is to make a "template" editor where the customer can make a template for example proof for his member that they work for him because of bus tickets or something like that. So, I made a Liveware component that shows up list of templates and when users click on a template from the list they will need to get the previously saved template so they can edit/change if needs something to change. But for some reason, I get only empty textarea if I put summernote or ckeditor and I can't find a reason why that happened. The same is in the database had some info or not.
Here is my component template:
<div>
<div class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800">
<label class="block text-sm">
<span class="text-gray-700 dark:text-white">{{__('site.team_member_document.document_type')}}</span>
<select class="block w-full mt-1 text-sm"
name="team_member_document_type_id" id="team_member_document_type_id"
wire:model="team_member_document_type_id" wire:change="onChangeDocumentType()">
<option value="">{{__('site.team_member_document.select_document_type')}}</option>
#foreach($document_types as $item)
<option value="{{$item['id']}}"
#if(old('team_member_document_type_id')==$item['id']) selected #endif
>{{$item['name']}}</option>
#endforeach
</select>
</label>
<label class="block text-sm" wire:ignore>
<span class="text-gray-700 dark:text-white">{{__('site.team_member_document.template')}}</span>
<textarea name="template" id="template" wire:model.defer="template">{{ $template }}</textarea>
</label>
<label class="block mt-4 text-sm">
<button type="button" wire:click="submitForm()"
class="px-4 py-2 text-sm font-medium">
{{__('site.save')}}
</button>
<a href="{{route('team_member_document.index')}}"
class="px-4 py-2 text-sm font-medium">
{{__('site.cancel')}}
</a>
</label>
</div>
<script>
$(function () {
$('#template').summernote({
placeholder: '',
height: 300,
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link']],
['view', ['fullscreen', 'codeview']]
],
callbacks: {
onChange: function (contents, $editable) {
#this.set('template', contents);
}
}
});
})
</script>
and here is Livewire component code:
namespace App\Http\Livewire;
use Livewire\Component;
class TeamMemberDocumentTemplate extends Component
{
public $document_types;
public $team_member_document_type_id;
public $template;
protected array $rules = [
'template' => 'required|min:30',
];
public function mount($document_types)
{
$this->template = '';
$this->document_types = $document_types;
}
public function render()
{
return view('livewire.team-member-document-template');
}
public function onChangeDocumentType()
{
$this->template = $this->document_types->filter(function ($item) {
return ($this->team_member_document_type_id == $item->id);
})->first()->template ?? '';
}
public function submitForm()
{
$this->validate();
$document_type = $this->document_types->filter(function ($item) {
return ($this->team_member_document_type_id == $item->id);
})->first();
$document_type->update([
'template' => $this->template
]);
return redirect()->route('team_member_document.index');
}
}
When adding this part of the code into livewire.team-member-document-template.blade.php all works well:
When adding this part of the code into livewire.team-member-document-template.blade.php all works well:
<script> $(function () { $('#summernote_small').on('summernote.change', function (we, contents, $editable) { #this.set('print_note', contents); }); }) </script>

Laravel Livewire Message only to a specific user

I took over a working chat application. to send a message, the original code uses a user list, which then checks whether a message exists.
In this case, it will redirect to the chat blade. If not, a new message will be created and then redirected to Chat blade.
Github to the app
https://github.com/thee-king-yodah/laravel-livewire-chat-message-application
I would like to change this and use a button on a profile page, but I'm currently working on the implementation and get stuck.
If I add the livewire into my blade it list a button for all users.
Controller: CreateChat
namespace App\Http\Livewire\Chat;
use Livewire\Component;
use App\Models\User;
use App\Models\Conversation;
use App\Models\Message;
use GuzzleHttp\Promise\Create;
use Illuminate\Support\Carbon;
use App\Http\Livewire\Chat\ChatList;
class CreateChat extends Component
{
public $users;
public $message= 'Start';
public function checkconversation($receiverId)
{
//dd($this->spieler);
$checkedConversation = Conversation::where('receiver_id', auth()->user()->id)
->where('sender_id', $receiverId)
->orWhere('receiver_id', $receiverId)
->where('sender_id', auth()->user()->id)->get();
if (count($checkedConversation) == 0) {
//dd('no conversation');
$createdConversation= Conversation::create(['receiver_id'=>$receiverId,'sender_id'=>auth()->user()->id,'last_time_message'=>Carbon::now()]);
$createdMessage= Message::create(['conversation_id'=>$createdConversation->id,'sender_id'=>auth()->user()->id,'receiver_id'=>$receiverId,'body'=>$this->message]);
$createdConversation->last_time_message= $createdMessage->created_at;
$createdConversation->save();
return redirect()->to('/chat');
//dd($createdMessage);
//dd('saved');
} else if (count($checkedConversation) >= 1) {
return redirect()->to('/chat');
//dd('conversation exists');
}
# code...
}
public function render()
{
$this->users = User::where('id','!=',auth()->user()->id)->get();
return view('livewire.chat.create-chat');
}
Create-chat.blade
<div>
<div class="flex justify-center">
<div class="bg-white rounded-lg border border-gray-200 w-96 text-gray-900">
<ul role="list" class="">
#foreach($users as $user)
<div class="flex justify-center mb-2 mt-4">
<button type="button" class="inline-block align-middle text-center select-none border font-normal whitespace-no-wrap rounded py-1 px-3 leading-normal no-underline text-blue-600 border-blue-600 hover:bg-blue-600 hover:text-white bg-white hover:bg-blue-600 ms-1"
wire:click='checkconversation({{ $user->id }})'>Nachricht</button>
</div>
#endforeach
</ul>
</div>
</div>
</div>
Controller Profile
amespace App\Http\Livewire;
use Livewire\Component;
use App\Models\User;
use Illuminate\Support\Carbon;
class Playerprofil extends Component
{
public $player;
public function render()
{
return view('livewire.playerprofile', [
'player' => $this->player,
]);
}
public function mount($id)
{
$this->player= User::find($id);
}
Profil.blade
<div>
#livewire('chat.create-chat' )
</div>
I would be very grateful if someone could help m out.
It's solved.
Controller: CreateChat
added mount
public function mount()
{
$this->users = User::find($this->user_id);
}
removed foreach in CreateChat.blade
<div>
#livewire('chat.create-chat', ['user_id' => $player->id ])
</div>

Search Laravel Using Button

I want to search for data using a primary key, with PO as an example. Btw, I'm new to Laravel. Below is my code for my controller. I want to make the system go to the new page if the data that was searched exists(click on search button). If not, it will stay on the same page. Actually, I don't know whether my code is correct or not.
public function supplierindex(){
$supp_details = Supplier::where('PO','LIKE','%'.$searchPO.'%')->get();
return view ('frontend.praiBarcode.getweight')
->with('supp_details',$supp_details);
}
public function searchindex()
{
return view ('frontend.praiBarcode.getweight');
}
public function searchPO()
{
$searchPO = Supplier::where('PO','like',"%".$search."%")->get();
if (Supplier::where('PO','like',"%".$search."%")->exists()) {
return view('frontend.praiBarcode.getweight',compact('searchPO')); }
else {
return view('frontend.praiBarcode.index');
}
}
Below is my code in blade.php. However, the data does not come out on the screen.
<div class= "form-group">
#foreach ($supp_details as s)
<div style="font-size: 16px;" class="form-group row">
<label for="supp_name" class = "col-sm-2">PO</label>
<label for="supp_name" class = "col-sm-1">:</label>
<div class="col-sm-7">
<label> {{ $s->PO }}</label>
</div>
</div>
#endforeach
In order to pass data into the view, you have to use the second argument of the view function.
Example:
public function supplierindex(){
$supp_details = Supplier::where('PO','LIKE','%'.$searchPO.'%')->get();
return view ('frontend.praiBarcode.getweight' ,['supp_details' => $supp_details]);
}
You can use count() to check if query result is empty or not
public function searchPO()
{
$searchPO = Supplier::where('PO','like',"%".$search."%")->get();
$countsearchPO = $searchPO->count();
if ($countsearchPO ) {
return view('frontend.praiBarcode.getweight',compact('searchPO')); }
else {
return view('frontend.praiBarcode.index');
}
}
And in your blade your variable is stored in session
$supp_details = Session::get('supp_details');
#foreach ($supp_details as s)
<div style="font-size: 16px;" class="form-group row">
<label for="supp_name" class = "col-sm-2">PO</label>
<label for="supp_name" class = "col-sm-1">:</label>
<div class="col-sm-7">
<label> {{ $s->PO }}</label>
</div>
</div>
#endforeach

array_merge(): Expected parameter 2 to be an array, null given pusher laravel

I'm trying to learn how to work with events and pusher, I've started with something very simple
I am working with laravel 8 livewire.
From pusher to view it works fine, but when I call the event from the component I get the error :
https://flareapp.io/share/dmkzeG65#F77
View:
<div>
<div class="mt-20 col-span-2 editor mx-auto w-10/12 flex flex-col text-gray-800 border border-gray-300 p-4 shadow-lg max-w-2xl rounded">
<textarea id="mensaje" wire:model="mensaje" class="mt-4 rounded description bg-gray-100 sec p-3 h-20 border border-gray-300 outline-none" spellcheck="false" placeholder="Aqui dispones la oportunidad de argumentar tu opiniĆ³n."></textarea>
<div class="buttons flex mt-2">
<div class="btn border border-gray-300 p-1 px-3 font-semibold cursor-pointer text-gray-500 ml-auto">
Cancel
</div>
<button wire:click="enviarMensaje" class="btn border border-indigo-500 p-1 px-3 font-semibold cursor-pointer text-gray-200 ml-2 bg-indigo-500" type="submit">
Comentar
</button>
</div>
#error('mensaje') <small class="text-red-600">{{$message}}</small> #enderror
</div>
<script>
// Enable pusher logging - don't include this in production
Pusher.logToConsole = true;
var pusher = new Pusher('d1fc007f6e1d80963c33', {
cluster: 'eu'
});
var channel = pusher.subscribe('my-channel');
channel.bind('my-event', function(data) {
alert(JSON.stringify(data));
});
</script>
</div>
LIVEWIRE COMPONENT
<?php
namespace App\Http\Livewire;
use App\Events\Mensaje;
use Livewire\Component;
use App\Events\EnviarMensaje;
use App\Events\SendMessage;
class ChatForm extends Component
{
public $mensaje;
public function mount()
{
$this->mensaje = '';
}
public function enviarMensaje()
{
event(new SendMessage($this->mensaje));
}
public function render()
{
return view('livewire.chat-form');
}
}
EVENT
<?php
namespace App\Events;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class SendMessage implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
public function __construct($message)
{
$this->message = $message;
}
public function broadcastOn()
{
return ['my-channel'];
}
public function broadcastAs()
{
return 'my-event';
}
}
I look forward to your help. Thank you very much for your help.
This error was resolved in the pusher-http-php library v5.0.1 and Laravel v8.29.0. https://github.com/pusher/pusher-http-php/issues/288
Alternatively you can use pusher-http-php v4.1
composer require pusher/pusher-php-server ^4.1

Livewire throwing error when using paginated data

So I am being given this error when trying to paginate my data and send it in to a view through a livewire component.
I am trying to get all posts and display at max 5 posts per page using pagination in laravel.
Livewire version: 2.3.1
Laravel version: 8.13.0
Error:
Livewire\Exceptions\PublicPropertyTypeNotAllowedException
Livewire component's [user-posts] public property [posts] must be of type: [numeric, string, array, null,
or boolean]. Only protected or private properties can be set as other types because JavaScript doesn't
need to access them.
My Component:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Post;
use Livewire\WithPagination;
class UserPosts extends Component
{
use WithPagination;
public $posts;
public $type;
protected $listeners = ['refreshPosts'];
public function delete($postId)
{
$post = Post::find($postId);
$post->delete();
$this->posts = $this->posts->except($postId);
}
public function render()
{
if($this->type == 'all')
$this->posts = Post::latest()->paginate(5);
else if($this->type == 'user')
$this->posts = Post::where('user_id',Auth::id())->latest()->paginate(5);
return view('livewire.user-posts', ['posts' => $this->posts]);
}
}
My Blade:
<div wire:poll.5s>
#foreach($posts as $post)
<div style="margin-top: 10px">
<div class="post">
<div class="flex justify-between my-2">
<div class="flex">
<h1>{{ $post->title }}</h1>
<p class="mx-3 py-1 text-xs text-gray-500 font-semibold"
style="margin: 17px 0 16px 40px">{{ $post->created_at->diffForHumans() }}</p>
</div>
#if(Auth::id() == $post->user_id)
<i class="fas fa-times text-red-200 hover:text-red-600 cursor-pointer"
wire:click="delete({{$post->id}})"></i>
#endif
</div>
<img src="{{ asset('image/banner.jpg') }}" style="height:200px;"/>
<p class="text-gray-800">{{ $post->text }}</p>
#livewire('user-comments', [
'post_id' => $post->id,
'type' => 'all'
],
key($post->id)
)
</div>
</div>
#endforeach
{{ $posts->links() }}
</div>
$posts should not be declared as a property in the Livewire component class, you passed the posts with the laravel view() helpers as data.
Remove the line
public $posts;
And replace $this->posts by $posts in the render function:
public function render()
{
if($this->type == 'all')
$posts = Post::latest()->paginate(5);
else if($this->type == 'user')
$posts = Post::where('user_id',Auth::id())->latest()->paginate(5);
return view('livewire.user-posts', ['posts' => $posts]);
}
}

Resources