Getting my toggle to show correctly in laravel livewire - laravel

I have a pivot table that links my products and categories together. What I'm trying to do is in my edit page for a product I
have a list of all the categories and each category has a toggle button that will enable or disable that category for that product.
The problem I'm having is that all my categories is set to enabled, but I only have one enabled and the rest is supposed to be disabled
I'm using laravel 8 and livewire
Here is my code
namespace App\Http\Livewire\Products;
use App\Models\Product;
use Livewire\Component;
use App\Models\Category;
class Edit extends Component
{
public Product $product;
public bool $enabled;
public $name;
public $description;
public function mount()
{
$pcPivot = $this->product->categories()->where('product_id', $this->product->id)->exists();
if($pcPivot === true)
{
$this->enabled = true;
}else{
$this->enabled = false;
}
$this->name = $this->product->name;
$this->description = $this->product->description;
}
public function render()
{
$categories = Category::all();
return view('livewire.products.edit', [
'categories' => $categories,
]);
}
}
and here is my edit.blade.php
<div>
<div class="md:grid md:grid-cols-3 md:gap-6">
<div class="md:col-span-1">
<div class="px-4 sm:px-0">
<h3 class="text-lg font-medium leading-6 text-gray-900">Edit Product</h3>
</div>
</div>
<div class="mt-5 md:mt-0 md:col-span-2">
<div class="shadow sm:rounded-md sm:overflow-hidden">
<form wire:submit.prevent="submit">
<div class="px-4 py-5 bg-white sm:p-6">
<div class="grid grid-cols-3 gap-6">
<div class="col-span-3 sm:col-span-2">
<label for="title" class="block text-sm font-medium leading-5 text-gray-700">
Name
</label>
<div class="rounded-md shadow-sm">
<input id="name" wire:model="product.name" class="flex-1 form-input block w-full min-w-0 transition duration-150 ease-in-out sm:text-sm sm:leading-5">
</div>
</div>
</div>
</div>
<div class="px-4 py-5 bg-white sm:p-6">
<div class="grid grid-cols-3 gap-6">
<div class="col-span-3 sm:col-span-2">
<label for="description" class="block text-sm font-medium leading-5 text-gray-700">
Description
</label>
<div class="rounded-md shadow-sm">
<textarea id="description" wire:model="product.description" rows="3" class="form-textarea mt-1 block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5"></textarea>
</div>
</div>
</div>
</div>
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
<span class="inline-flex rounded-md shadow-sm">
<button type="submit" class="inline-flex justify-center py-2 px-4 border border-transparent text-sm leading-5 font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo active:bg-indigo-700 transition duration-150 ease-in-out">
Update
</button>
</span>
</div>
</form>
</div>
</div>
</div>
#include('spacer')
<div class="md:grid md:grid-cols-3 md:gap-6">
<div class="md:col-span-1">
<div class="px-4 sm:px-0">
<h3 class="text-lg font-medium leading-6 text-gray-900">Categories</h3>
</div>
</div>
<div class="mt-5 md:mt-0 md:col-span-2">
<div class="shadow sm:rounded-md sm:overflow-hidden">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<x-th>Title</x-th>
<x-th>Enable/Disable</x-th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
#foreach($categories as $category)
<tr>
<td class="px-6 py-4 whitespace-no-wrap">
<div class="flex items-center">
<div class="text-sm font-medium text-gray-900">
{{ $category->title }}
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-no-wrap">
<div class="mt-1 flex rounded-md">
<span role="checkbox" tabindex="0" aria-checked="false" class="#if($enabled) bg-indigo-600 #else bg-gray-200 #endif relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:shadow-outline">
<span aria-hidden="true" class="#if($enabled) translate-x-5 #else translate-x-0 #endif inline-block h-5 w-5 rounded-full bg-white shadow transform transition ease-in-out duration-200">
<input id="enabled" type="checkbox" wire:model="enabled" class="invisible">
</span>
</span>
</div>
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>

If you check the documentation for Livewire, at lifecycle hooks... you will see that:
mount : Runs once, immediately after the component is instantiated, but before render() is called
So basically you are getting an "enabled" value once, before rendering the component,then you start rendering it, with that foreach, using the same "enabled" from mount for each item of your dataset.
Consider building your cursor with the enabled value inside for each record.

Related

Why is my Laravel date column displaying a time as well?

I am developing a prototype in Laravel 9 which currently contains 7 user tables. Several of those tables contain dates and all of them are defined as Laravel dates; they are all defined as MySQL dates in the database as well. I can't figure out why one of those date columns displays all its dates as a regular date, followed by a blank and then a time - 00:00:00 - whenever displayed in my blade templates. All of the other date columns display as a date (YYYY-MM-DD) without a time.
I am NOT requesting that a time (which is always 00:00:00/midnight) be shown in that column. Why is Laravel doing this and how can I make it stop?
I realize that I can suppress the time by appending ->format('Y-m-d') but I shouldn't have to do that in the first place; if I only store a date rather that a DateTime or Timestamp, there should only be a date in the column and no need to suppress the time to keep it from displaying.
UPDATE
Here is the migration for the table that is giving me trouble:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('non_driving_weekdays', function (Blueprint $table) {
$table->date('non_driving_weekday_date');
$table->string('reason', 50);
$table->timestamps();
$table->primary('non_driving_weekday_date', 'non_driving_weekday_date_PK');
$table->foreign('reason', 'reason_FK')->references('reason_for_not_driving')->on('non_driving_reasons')->onUpdate('cascade')->onDelete('restrict');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('non_driving_weekdays');
}
};
Here is the blade that displays the index:
<x-layout>
<div class="bg-gradient-to-b from-red-500 to-purple-100">
<h1 class="text-3xl text-center text-white font-bold bg-indigo-700">Non-driving Weekdays - Index</h1>
<h1 class="pb-5"></h1><!-- spacer beneath title -->
#if (session()->has('message'))
<div id="message"
x-data="{show: true}"
x-init="setTimeout(() => show = false, 5000)"
x-show="show"
class="w-1/3 mx-auto text-center text-black bg-yellow-300 rounded-md">
<p class="text-xl py-1">{{session('message')}}</p>
</div>
#endif
<div class="flex justify-center h-screen" style="display: grid; grid-template-rows: auto auto auto auto; row-gap: 10px; padding: 10px">
<table><tr><td><img src="{{asset('icons/green-plus-circle-outline.svg')}}" width="50" alt="add icon"></td><td class="font-bold">Add a new date where the drivers didn't drive</td></tr></table>
{{-- If there are no non-driving weekdays, indicate that to the user. --}}
#if (count($nonDrivingWeekdays) == 0)
<p>No non-driving weekdays found.</p>
#else
{{-- If there are non-driving weekdays, display them. --}}
<div>
<table class="border-black border-2 bg-white">
<thead class="border-black border-2 text-white bg-gray-800">
<tr class="content-center">
<th class="border-black border-2 p-2 text-left">Date</th>
<th class="border-black border-2 p-2 text-left">Reason</th>
<th class="border-black border-2 p-2">View</th>
<th class="border-black border-2 p-2">Edit</th>
<th class="border-black border-2 p-2">Delete</th></tr>
</thead>
<tbody class="border-black border-2">
#foreach($nonDrivingWeekdays as $nonDrivingWeekday)
<tr class="border-black border-2">
{{-- ->format('Y-m-d') --}}
<td class="border-black border-2 p-2">{{$nonDrivingWeekday->non_driving_weekday_date}}</td>
<td class="border-black border-2 p-2">{{$nonDrivingWeekday->reason}}</td>
<td class="border-black border-2 p-2 text-center"><img src="{{asset('icons/magenta-details.svg')}}" width="25" alt="view icon"></td>
<td class="border-black border-2 p-2 text-center"><img src="{{asset('icons/yellow-lead-pencil.svg')}}" width="25" alt="update icon"></td>
<td class="border-black border-2 p-2 text-center">
<form method="POST" action="/nonDrivingWeekdays/destroy/{{$nonDrivingWeekday->non_driving_weekday_date}}">
#csrf
#method('DELETE')
<button><img src="{{asset('icons/red-delete.svg')}}" width="25" alt="delete icon"></button>
</form></td>
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
#endif
<div>
<p class="mt-6 p-4">{{$nonDrivingWeekdays->links()}}</p>
</div>
</div>
</div>
</x-layout>
This is the blade for the show() method:
<x-layout>
{{-- <x-card class="p-10"> --}}
<div class="bg-gradient-to-b from-purple-500 to-purple-100 h-screen">
<h1 class="text-3xl text-center text-white font-bold bg-indigo-700">Non-driving Weekdays - Show One Weekday</h1>
<h1 class="pb-5"></h1><!-- spacer beneath title -->
<form method="GET" enctype="multipart/form-data" class="w-4/5 mx-auto">
<div class="mb-6">
<label for="non_driving_weekday_date" class="inline-block text-lg mb-2">Reason</label>
<input type="text" disabled class="border border-gray-200 rounded p-2 w-full" name="non_driving_weekday_date" value="{{$nonDrivingWeekday->non_driving_weekday_date}}"/>
</div>
<div class="mb-6">
<label for="reason" class="inline-block text-lg mb-2">Reason</label>
<input type="text" disabled class="border border-gray-200 rounded p-2 w-full" name="reason" value="{{$nonDrivingWeekday->reason}}"/>
</div>
<div class="mb-6">
{{-- Cancel submission of the form --}}
<button type="button" class="text-xl text-white bg-black rounded-md py-2 px-4 hover:bg-white hover:text-black hover:outline hover:outline-2 hover:outline-black">Cancel</button>
</div>
</form>
{{-- </x-card> --}}
</div>
</x-layout>
And this is the blade template for the edit() method:
<x-layout>
{{-- <x-card xclass="p-10 max-w-lg mx-auto mt-24"> --}}
<div class="bg-gradient-to-b from-yellow-500 to-yellow-100 h-screen">
<h1 class="text-3xl text-center text-white font-bold bg-indigo-700">Non-driving Weekdays - Edit One Weekday</h1>
<h1 class="pb-5"></h1><!-- spacer beneath title -->
<form method="POST" action="/nonDrivingWeekdays/update/{{$nonDrivingWeekday->non_driving_weekday_date}}" enctype="multipart/form-data" class="w-4/5 mx-auto">
#csrf
#method('PUT')
<div class="mb-6">
<label for="non_driving_weekday_date" class="inline-block text-lg mb-2">Non-driving weekday date</label>
<input type="text" class="border border-gray-200 rounded p-2 w-full" name="non_driving_weekday_date" value="{{$nonDrivingWeekday->non_driving_weekday_date}}"/>
#error('non_driving_weekday_date')
<p class="text-red-500 font-bold text-m mt-1">{{$message}}</p>
#enderror
</div>
<div class="mb-6">
<label for="reason" class="inline-block text-lg mb-2">Reason</label>
<select id="reason" name="reason" class="h-10">
#foreach($reasons as $reason)
#if($reason->reason_for_not_driving === $nonDrivingWeekday->reason)
<option selected class="mx-10" value="{{$reason->reason_for_not_driving}}">{{$reason->reason_for_not_driving}}</option>
#else
<option class="mx-10" value="{{$reason->reason_for_not_driving}}">{{$reason->reason_for_not_driving}}</option>
#endif
#endforeach
</select>
</div>
<div class="mb-6">
{{-- Submit the completed form --}}
<button class="text-xl text-white bg-orange-500 rounded-md py-2 px-4 hover:bg-white hover:text-orange-500 hover:outline hover:outline-2 hover:outline-orange-500">Submit</button>
{{-- Cancel submission of the form --}}
<button type="button" class="text-xl text-white bg-black rounded-md py-2 px-4 hover:bg-white hover:text-black hover:outline hover:outline-2 hover:outline-black">Cancel</button>
</div>
</form>
{{-- </x-card> --}}
</div>
</x-layout>
Lastly, here is the model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class NonDrivingWeekdays extends Model
{
use HasFactory;
protected $fillable = ['non_driving_weekday_date', 'reason'];
protected $primaryKey = 'non_driving_weekday_date';
protected $keyType = 'date';
public $incrementing = 'false';
}
StewieSWS gave me the clue that helped me solve this: I wasn't displaying the dates in form fields that were <input type="date">. Frankly, I'd forgotten there was a special input type for dates! In the blade for my index() method, I was displaying the data as a cell in a table and in the blades for the edit(), show() and create() methods, I was displaying them in <input type="text"> fields. As soon as I started displaying the dates in <input type="date"> fields, they started displaying as normal dates WITHOUT any time component. I even got a little calendar icon at the right end of the box which lets me pick a date from calendar. As an added bonus, I even got some additional validating: when I tried to enter an impossible date, Feb 30, 2023, the input field detected it and displayed an appropriate message.

Vue Laravel not showing data from method

I know I am blind because I've been looking at this for 2 days off and on and I think I am just eye stuck on what is really going on. Below is the code. What SHOULD happen is an array of data should be shown into a modal. I can see the data as "rooms" in web inspector with all the fields, but it isnt populating into the v-for - all im asking for is a little help if you can see where I screwed up
<!-- This example requires Tailwind CSS v2.0+ -->
<template>
<TransitionRoot as="template" :show="open">
<Dialog as="div" class="fixed z-10 inset-0 overflow-y-auto" #close="open = false">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0" enter-to="opacity-100" leave="ease-in duration-200" leave-from="opacity-100" leave-to="opacity-0">
<DialogOverlay class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
</TransitionChild>
<!-- This element is to trick the browser into centering the modal contents. -->
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
<TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" enter-to="opacity-100 translate-y-0 sm:scale-100" leave="ease-in duration-200" leave-from="opacity-100 translate-y-0 sm:scale-100" leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
<div class="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:p-6">
<button type="button" class="bg-white rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" #click="open = false">
<div class="hidden sm:block absolute top-0 right-0 pt-4 pr-4">
<span class="sr-only">Close</span>
<XIcon class="h-6 w-6" aria-hidden="true" />
</div>
</button>
<div class="sm:flex sm:items-start">
<div class="flex flex-col">
<div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
<div class="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Room
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Description
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Type
</th>
<th scope="col" class="relative px-6 py-3">
<span class="sr-only">Enter</span>
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<tr v-for="room in chatRooms" :key="room.id">
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10">
<img class="h-10 w-10 rounded-full" :src="room.image" alt="" />
</div>
<div class="ml-4">
<div class="text-sm font-medium text-gray-900">
{{ room.name }}
</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">{{ room.description }}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full" :class="[room.is_private === 'Public' ? 'bg-green-100 text-green-800' : room.is_private === 'Private' ? 'bg-red-100 text-red-800' : '']">
{{ room.is_private }}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
Enter
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</TransitionChild>
</div>
</Dialog>
</TransitionRoot>
</template>
<script>
import { ref } from 'vue'
import { Dialog, DialogOverlay, DialogTitle, TransitionChild, TransitionRoot } from '#headlessui/vue'
import { ExclamationIcon, XIcon } from '#heroicons/vue/outline'
export default {
props: ['rooms'],
data: function () {
return {
chatRooms: [],
rooms: [],
}
},
methods: {
getRooms() {
axios.get('/chat/rooms')
.then(response => {
this.chatRooms = response.data;
})
.catch(error => {
console.log(error);
})
}
},
components: {
Dialog,
DialogOverlay,
DialogTitle,
TransitionChild,
TransitionRoot,
ExclamationIcon,
XIcon,
},
setup() {
const open = ref(true)
return {
open,
}
},
}
</script>
Try this :
Maybe this is the cause of your problem.
Add this piece of code before methods: {} and tell me :
created() {
this.getRooms();
},
The issue was not something anyone here could solve with the information provided. So I am typing this answer in a way that I hope will trigger some help to others.
When you are doing a v-for snippet, it is important to remember what data is being pulled for processing. In my case, the following line was the issue
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full" :class="[room.is_private === 'Public' ? 'bg-green-100 text-green-800' : room.is_private === 'Private' ? 'bg-red-100 text-red-800' : '']">
room.is_private is a boolean not the data I want to visualize. So by saying Public and Private, I was breaking the for statement. By changing them to True and False, I was able to process the v-for statement and actually get the code to load. The solution I used was as follows. Note there are 2 versions of true and false. This is because Postgres and sqlite both expect to see the response differently. I noticed this when it worked local with 'true' but pgsql on the deployment didn't work. So this Is why the code is this way
<div v-if="room.is_private === true" class="rounded-full py-1 px-2 bg-red-100 text-red-800">
<span>Private</span>
</div>
<div v-else-if="room.is_private === false" class="rounded-full py-1 px-2 bg-green-100 text-green-800">
<span>Public</span>
</div>
<div v-else-if="room.is_private === 'true'" class="rounded-full py-1 px-2 bg-red-100 text-red-800">
<span>Private</span>
</div>
<div v-else-if="room.is_private === 'false'" class="rounded-full py-1 px-2 bg-green-100 text-green-800">
<span>Public</span>
</div>
The important lesson here is to make sure you sample the data and fields before running into code making mistakes on the type of data being requested.

Make selected item current

EDIT: Full code for the 3 most likely files are found here.
https://codepen.io/arcticmedia-ryan/project/editor/ZEQwmN
I am not sure how best to explain this so please let me know if you want more. I am building a chat room app. When a person opens up the main vue, they are presented with a "Room List" - from there they can click enter and join the room. The issue is, when they click join, it opens up the tab for the room but doesnt make it active. I feel like I am just banging my head around a simple problem
There is a prop called "SelectedRoomID" that needs to be updated from "undefined" to the room that is selected from the list.
RoomList.vue
<!-- This example requires Tailwind CSS v2.0+ -->
<template>
<TransitionRoot as="template" :show="isOpen">
<Dialog as="div" class="fixed z-10 inset-0 overflow-y-auto" #close="$emit('onClose')">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0"
enter-to="opacity-100" leave="ease-in duration-300" leave-from="opacity-100"
leave-to="opacity-0">
<DialogOverlay class="fixed inset-0 bg-gray-700 bg-opacity-75 transition-opacity"/>
</TransitionChild>
<!-- This element is to trick the browser into centering the modal contents. -->
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
<TransitionChild as="template" enter="ease-out duration-300"
enter-from="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enter-to="opacity-100 translate-y-0 sm:scale-100" leave="ease-in duration-300"
leave-from="opacity-100 translate-y-0 sm:scale-100"
leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
<div class="inline-block align-bottom bg-black bg-opacity-20 rounded-lg px-6 pt-5 pb-4 text-left overflow-hidden shadow-2xl transform transition-all sm:my-8 sm:align-middle sm:p-6">
<div class="sm:flex sm:items-start">
<div class="flex flex-col">
<div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="align-middle inline-block min-w-full sm:px-4 lg:px-5">
<div class="shadow overflow-hidden border-8 border-gray-800 dark:border-gray-900 sm:rounded-lg">
<table class="min-w-full divide-y divide-gray-800">
<thead class="bg-gray-800 dark:bg-gray-900">
<tr>
<th scope="col"
class="px-6 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
Room
</th>
<th scope="col"
class="px-6 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
Description
</th>
<th scope="col"
class="px-6 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
Type
</th>
<th scope="col"
class="px-6 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
Users
</th>
<th scope="col" class="relative px-6 py-3">
<button type="button"
class="bg-white rounded-md text-gray-400 hover:text-gray-500 "
#click="$emit('onClose')">
<div class="hidden sm:block absolute top-0 right-0 pt-4 pr-4">
<span class="sr-only">Close</span>
<XIcon class="top-1 right-1 absolute h-6 w-6 text-gray-50 " aria-hidden="true"/>
</div>
</button>
<span class="sr-only">Enter</span>
</th>
</tr>
</thead>
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-300 dark:divide-gray-600">
<tr v-for="room in $store.state.rooms.rooms" :key="room.id">
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10">
<img class="h-10 w-10 rounded-full" :src="room.image"
alt=""/>
</div>
<div class="ml-4">
<div class="text-md font-medium text-gray-900 dark:text-gray-50">
{{ room.name }}
</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-md text-gray-900 dark:text-gray-50">{{ room.description }}</div>
</td>
<td class="px-2 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-s leading-5 font-medium rounded-full">
<div v-if="room.is_private === true" class="rounded-full py-1 px-2 bg-red-100 text-red-800 dark:bg-red-800 dark:text-red-100">
<span>Private</span>
</div>
<div v-else-if="room.is_private === false" class="rounded-full py-1 px-2 bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
<span>Public</span>
</div>
<div v-else-if="room.is_private === 'true'" class="rounded-full py-1 px-2 bg-red-100 text-red-800 dark:bg-red-800 dark:text-red-100">
<span>Private</span>
</div>
<div v-else-if="room.is_private === 'false'" class="rounded-full py-1 px-2 bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
<span>Public</span>
</div>
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-center">
<a class="text-md font-medium text-gray-900 dark:text-gray-50">99</a>
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-md font-medium">
<div class="flex rounded-full py-2 px-4 bg-indigo-700 hover:bg-indigo-900">
<a href="#" #click="joinRoom(room)"
class="text-white">Enter</a>
</div>
</td>
</tr>
</tbody>
</table>
<div class="bg-gray-800 dark:bg-gray-900">
<div class="flex justify-end px-4 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
<span class=" px-2 pt-2 text-xs leading-5 font-semibold rounded-full">
<a href="#">
<div class="flex rounded-full py-1 px-2 bg-green-700 text-green-100 hover:bg-green-800">
<PlusIcon class="h-5 w-5"/><span class="text-sm font-bold pl-0.5">Create Room</span>
</div>
</a>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</TransitionChild>
</div>
</Dialog>
</TransitionRoot>
</template>
<script>
import {Dialog, DialogOverlay, DialogTitle, TransitionChild, TransitionRoot} from '#headlessui/vue'
import {ExclamationIcon, XIcon, PlusIcon} from '#heroicons/vue/outline'
import {types as RoomTypes} from "../../../Store/modules/rooms/rooms.types";
export default {
components: {
Dialog,
DialogOverlay,
DialogTitle,
TransitionChild,
TransitionRoot,
ExclamationIcon,
XIcon,
PlusIcon,
},
props: ['rooms', 'selectedRoomId'],
emits: ['onSelectRoom', 'onLeaveRoom', 'onClose'],
methods: {
joinRoom(room) {
this.$store.dispatch(RoomTypes.JOIN_ROOM, room);
this.selectedRoomId = this.room;
this.$emit('onClose');
}
},
props: {
isOpen: Boolean,
usersCount: Boolean
},
}
</script>
Main.vue
SNIPPET OF CODE
<section aria-labelledby="primary-heading"
class="dark:bg-gray-900 min-w-0 flex-1 h-full flex flex-col overflow-hidden lg:order-last">
<room-tabs :selectedRoomId="currentRoom.id" :rooms="joinedRooms"
#onSelectRoom="currentRoom = $event" #onLeaveRoom="leaveRoom($event)"/>
<message-container :messages="messages"
class="h-full pb-2 mb-2 pt-0 mt-0 shadow-md overflow-y-auto"/>
<input-box
:room="currentRoom"
v-on:messagesent="getMessages"
class="dark:bg-gray-800 px-6 pb-6 pt-4 dark:border-t-2 dark:border-gray-600 bottom-0 sticky"
/>
</section>
I know its inside methods: joinRoom that needs to change and I know its wrong where this.selectedRoomId is - I just dont know what I need to change/fix to make it turn the selected room into the active room when you click join.
Any help would be very much appreciated!
I would use mapState to effectively watch the value in the store that is being updated by this.$store.dispatch(RoomTypes.JOIN_ROOM, room);
So in a component that needs to know this value:
computed: {
...mapState(['STORE_NAME', 'STORE_VALUE']),
},
and then you should be able to use this.STORE_VALUE as a dynamically updated value

Saved date does not show up in the form

I'm using laravel livewire and I've created a page that you can select a date for when you want the post
to publish. When I create a new post and save the date then it saves fine in the database, but if I try
to edit the post and change the date the date that I saved in the database isn't showing in the form.
Here is my code.
My EditPost.php
<?php
namespace App\Http\Livewire;
use App\Models\Post;
use Livewire\Component;
class EditPost extends Component
{
public $name;
public $publishDate;
public Post $post;
public function mount(Post $post)
{
$this->name = $post->name;
$this->publishDate = $post->publish_date;
}
public function render()
{
return view('livewire.edit-post');
}
}
and this is my edit.blade.php
<div>
<div class="mt-10 sm:mt-0">
<div class="md:grid md:grid-cols-3 md:gap-6">
<div class="md:col-span-1">
<div class="px-4 sm:px-0">
<h3 class="text-lg font-medium leading-6 text-gray-900">Edit Post</h3>
</div>
</div>
<div class="mt-5 md:mt-0 md:col-span-2">
<div class="form">
<div class="shadow overflow-hidden sm:rounded-md">
<div class="px-4 py-5 bg-white sm:p-6">
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6 sm:col-span-3">
<label for="name" class="block text-sm font-medium leading-5 text-gray-700">Name</label>
<input id="name" wire:model="name" class="#error('name') border border-red-500 #enderror mt-1 form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5">
#error('name')
<small>
<div class="text-red-500">{{ $message }}</div>
</small>
#enderror
</div>
<div class="col-span-6 sm:col-span-4">
<label for="publish_date" class="block text-sm font-medium leading-5 text-gray-700">Publish Date</label>
<input id="publish_date" wire:model="publishDate" type="date" class="mt-1 form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5">
</div>
</div>
</div>
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
<button wire:click="editPost" class="py-2 px-4 border border-transparent text-sm leading-5 font-medium rounded-md text-white bg-indigo-600 shadow-sm hover:bg-indigo-500 focus:outline-none focus:shadow-outline-blue active:bg-indigo-600 transition duration-150 ease-in-out">
Save
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

Using a modal to delete a user

I'm trying to create a modal that when you click delete it will delete a record, but first I need to be able to have
that modal pop up.
I know that the reason is because of this line $('#delete_{{ $user->id }}').click(function(){ but I'm not sure how to add the user id without having to add the <script>...</script> to the foreach loop
Or do I need to do that?
Here is my code
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
Name
</th>
<th class="px-6 py-3 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider text-right">
Add User
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
#foreach($users as $user)
<tr>
<td class="px-6 py-4 whitespace-no-wrap">
<div class="flex items-center">
<div class="ml-4">
<div class="text-sm leading-5 font-medium text-gray-900">
{{ $user->name }}
</div>
<div class="text-sm leading-5 text-gray-500">
{{ $user->email }}
</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-no-wrap text-right text-sm leading-5 font-medium">
<button id="delete_{{ $user->id }}" class="bg-red-400 hover:bg-red-300 text-red-800 font-bold py-2 px-4 rounded inline-flex items-center">
Delete
</button>
</td>
</tr>
#endforeach
</tbody>
</table>
<div class="modal-display-none">
<div class="fixed z-10 inset-0 overflow-y-auto">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity">
<div class="absolute inset-0 bg-gray-500 opacity-75"></div>
</div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen"></span>​
<div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline">
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
<svg class="h-6 w-6 text-red-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
</div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-headline">
Delete User
</h3>
<div class="mt-2">
<p class="text-sm leading-5 text-gray-500">
Are you sure you want to delete this user? <br>
This action cannot be undone.
</p>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<span class="flex w-full rounded-md shadow-sm sm:ml-3 sm:w-auto">
<form action="{{ route('users.delete', ['user' => $user->id]) }}" method="POST">
#method('DELETE')
#csrf
<button type="button"
class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 bg-red-600 text-base leading-6 font-medium text-white shadow-sm hover:bg-red-500 focus:outline-none focus:border-red-700 focus:shadow-outline-red transition ease-in-out duration-150 sm:text-sm sm:leading-5"
id="confirm_delete"
>
Delete
</button>
</form>
</span>
<span class="mt-3 flex w-full rounded-md shadow-sm sm:mt-0 sm:w-auto">
<button type="button" id="close" class="inline-flex justify-center w-full rounded-md border border-gray-300 px-4 py-2 bg-white text-base leading-6 font-medium text-gray-700 shadow-sm hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue transition ease-in-out duration-150 sm:text-sm sm:leading-5">
Cancel
</button>
</span>
</div>
</div>
</div>
</div>
</div>
<style>
.modal-display-none{
display: none;
}
.modal-display{
display: block;
}
</style>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(document).ready(function(){
$('#delete_{{ $user->id }}').click(function(){
console.log('delete button');
$('.modal-display-none').removeClass('modal-display-none').addClass('modal-display');
});
$('#confirm_delete').click(function(){
$('.modal-display').removeClass('modal-display').addClass('modal-display-none');
});
$('#close').click(function(){
$('.modal-display').removeClass('modal-display').addClass('modal-display-none');
});
});
</script>
replace your syntax (inside foreach)
<button id="delete_{{ $user->id }}" class="bg-red-400 hover:bg-red-300 text-red-800 font-bold py-2 px-4 rounded inline-flex items-center">Delete</button>
replace with this syntax bellow, it will show an alert to confirm the Delete action
{!! Form::open(['route' => ['users.delete', $user->id], 'method' => 'delete']) !!}
{!! Form::button('<i class="fa fa-trash"></i>', [
'type' => 'submit',
'class' => 'bg-red-400 hover:bg-red-300 text-red-800 font-bold py-2 px-4 rounded inline-flex items-center',
'onclick' => "return confirm('Are you sure want to delete this item?')"
]) !!}
{!! Form::close() !!}

Resources