Laravel livewire checkbox options not being checked - php

I tried many ways of populating old checked values in edit page of livewire.
Method 1 :
public $role_id, $name, $new_permissions = [];
public function mount($id)
{
/
$old_permissions = \App\Models\UserRolePermission::where('user_role_id', $this->role_id)->pluck('permission_id')->toArray();
// here new_permissions is my wire:model name in view for the checkbox input
// so I tried to initialize the new_permissions array by old_permissions array
$this->new_permissions = $old_permissions;
$this->role_id = $id;
}
Method 2 :
Manually fetched the permissions in the view and checked in_array for the old_permissions to be checked:
#php
$old_permissions = \App\Models\UserRolePermission::where('user_role_id', $this->role_id)->pluck('permission_id')->toArray();
#endphp
<div class="col-md-12">
<div class="form-group">
<label class="display-block text-semibold">Select Permissions</label>
#foreach($permissions as $item)
<label class="checkbox-inline">
<input type="checkbox" wire:model="new_permissions" class="" value="{{ $item->id }}" {{ in_array($item->id, $old_permissions) ? "checked" : "" }}>
{{ $item->name }} </label>
#endforeach
</div>
</div>
In the 2nd method, my code in view source was correct, the old ones had checked in input field and the new ones didnt, but in the view the checkboxes didn't appear to be checked.

Livewire use string value instead of numeric.
To fix it convert all integers in your $old_permissions array to strings like
$old_permissions = \App\Models\UserRolePermission::where('user_role_id', $this->role_id)->pluck('permission_id')->->map(function ($permission_id) {
return strval($permission_id);
})->toArray();
Here is my solution
In View
<div class="bg-white dark:bg-primary-900 rounded-md shadow mt-2 py-3 px-2">
<h3 class="mb-2 text-gray-900 dark:text-gray-100 text-xl">Permissions</h3>
<div class="grid grid-cols-12 gap-4">
#foreach ($permissions as $permission)
<div class="col-span-6 sm:col-span-4 md:col-span-3 flex items-center space-x-2">
<input wire:model="selectedPermissions" type="checkbox" value="{{ $permission->id }}"
class="w-4 h-4 transition text-primary duration-300 rounded focus:ring-2 focus:ring-offset-0 focus:outline-none focus:ring-primary-200 dark:focus:ring-primary-700">
<label class="text-sm font-semibold text-gray-500 dark:text-gray-100">
{{ ucwords($permission->display_name) }}
</label>
</div>
#endforeach
</div>
</div>
In Livewire Component Class
public $role;
public $permissions;
public $selectedPermissions = [];
protected $listeners = ['eidtRole'];
public function mount()
{
$this->permissions = Permission::get();
}
public function eidtRole(Role $role)
{
$this->role = $role;
$this->selectedPermissions = $this->rolePermissions = $role->permissions()->pluck('id')->map(function ($id) {
return strval($id);
})->toArray();
}

Related

How I can store Checklist in Cardview

Hi i have a card that contains fields such as task details and estimated hours
When i try to write checklist name and click on create to store it in the card i am not able to do that
view.blade.php
<div class="checklist" id="checklist">
<form id="form-checklist" class="collapse pb-2" data-action="{{route('checklist.store',[$task->project_id,$task->id])}}">
<div class="card border shadow-none">
<div class="px-3 py-2 row align-items-center">
<div class="col-10">
<input type="text" name="name" required class="form-control" placeholder="{{__('Checklist Name')}}"/>
</div>
</div>
</div>
</form>
#foreach($task->checklist as $checklist)
<div class="card border shadow-none checklist-member">
<div class="px-3 py-2 row align-items-center">
<div class="col">
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" id="check-item-{{ $checklist->id }}" #if($checklist->status) checked #endif data-url="{{route('checklist.update',[$task->project_id,$checklist->id])}}">
<label class="form-check-label h6 text-sm" for="check-item-{{ $checklist->id }}">{{ $checklist->name }}</label>
</div>
</div>
</div>
</div>
#endforeach
</div>
</div>
</div>
project.task.controller
public function checklistStore(Request $request, $projectID, $taskID)
{
if(\Auth::user()->can('view project task'))
{
$request->validate(
['name' => 'required']
);
$post = [];
$post['name'] = $request->name;
$post['task_id'] = $taskID;
$post['user_type'] = 'User';
$post['created_by'] = \Auth::user()->id;
$post['status'] = 0;
$checkList = TaskChecklist::create($post);
$user = $checkList->user;
}
}

Laravel: Add to favourites button is duplicating because of foreach loop

For a project, I've created a method where people can add products they want to buy to a wishlist. All items in the catalog are stored and each article has a hearticon that is clickable. Once it's clicked, it's added to my database.
However, when an article is added to favourites, the icon turns red but the original transparant icon is still there. So articles whom are added to favourites all have a filled and a transparant icon, which is not how it should be done.
Here is my code:
My View:
<div class="flex flex-col justify-evenly items-center lg:flex-row flex-wrap justify-between gap-y-20 gap-x-2 lg:p-20 lg:w-12/12">
#foreach ($articles as $article)
<div class="w-8/12 lg:w-3/12 flex flex-col justify-between xl:h-100">
<form action="{{route('wishlist.store', $article->id)}}" id="wish_form" method="post">
{{csrf_field()}}
<input name="user_id" type="hidden" value="{{Auth::user()->id}}" />
<input name="article_id" type="hidden" value="{{$article->id}}" />
<button type="submit" class=""><img src="{{ 'icons/0heart.png' }}" alt="" width="25" onclick="this.form.submit()" id="emptyHeart"></button>
#foreach ($wishlists as $wishlist)
#if ($wishlist->article_id === $article->id )
<button type="submit"><img src="{{ 'icons/1heart.png' }}" alt="" width="25" onclick="this.form.submit()" id="checked"></button>
#endif
#endforeach
</form>
<div class="h-2/3 xl:h-1/3 flex justify-center items-center">
{{-- <img src="{{$article->image}}" alt="" class="h-40"> --}}
</div>
<div class="h-20 mt-2">
<h4 class="text-md text-center flex"><strong>{{ $article->title }}</strong></h4>
</div>
<div class="flex flex-row flex-wrap justify-between items-center mt-4">
<p class="p-2">{{$article->prijs}}</p>
<p>Beschikbaar via {{$article->website->title}}</p>
</div>
</div>
#endforeach
</div>
My controller:
class FilterController extends Controller
{
public function catalogus(Request $r)
{
$articles = Article::all();
$categories = Category::all();
$websites = Website::all();
$wishlists = Wishlist::all()->where('user_id',auth()->user()->id);
$list = Wishlist::all()->where('article_id', $articles->id);
dd($list);
return view('catalogus', compact('articles', 'categories', 'websites', 'wishlists', 'list'));
}
}
My model:
class Wishlist extends Model
{
protected $table = "wishlists";
protected $fillable = [
'user_id',
'article_id',
'confirmed',
'available'
];
protected $casts = [
];
public function user()
{
return $this->belongsTo(User::class);
}
public function article()
{
return $this->belongsTo(Article::class);
}
You can use contains() collection method
<form action="{{route('wishlist.store', $article->id)}}" id="wish_form" method="post">
{{csrf_field()}}
<input name="user_id" type="hidden" value="{{Auth::user()->id}}"/>
<input name="article_id" type="hidden" value="{{$article->id}}"/>
#if ($wishlists->contains('article_id', $article->id))
<button type="submit">
<img src="{{ 'icons/1heart.png' }}" alt="" width="25"
onclick="this.form.submit()" id="checked">
</button>
#else
<button type="submit" class="">
<img src="{{ 'icons/0heart.png' }}" alt="" width="25"
onclick="this.form.submit()" id="emptyHeart" />
</button>
#endif
</form>

Livewire retrieve Data from a relation manyToMany

in my blog project using livewire, i have a relationship manyToMany between tables posts & tags using a pivot table call post_tag
when i want to edit a post , in the modal i get all the data from posts table using -> wire:model.defer="post.body" ( we're using the Post model)
for the tags, i'm using a foreach to cycling through all the tags but how to get the tags associates to the post ?
Models
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $guarded = ['id', 'created_at', 'updated_at'];
public function user()
{
return $this->belongsTo(User::class);
}
public function category()
{
return $this->belongsTo(Category::class);
}
public function tags()
{
return $this->belongsToMany(Tag::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
use HasFactory;
protected $guarded = ['id', 'created_at', 'updated_at'];
public function posts()
{
return $this->belongsToMany(Post::class);
}
}
Migration post_tag table
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('post_tag', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('post_id');
$table->unsignedBigInteger('tag_id');
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('post_tag');
}
};
class
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Post;
use App\Models\Category;
use App\Models\Tag;
use Livewire\WithPagination;
use Livewire\WithFileUploads;
class EditHideForm extends Component
{
use WithPagination;
use WithFileUploads;
public $open = false;
public $post, $image, $identificador;
public $taggs;
protected $rules = [
'post.name' => 'required|max:100',
'post.slug' => 'required',
'post.body' => 'required',
'post.status' => 'required',
'post.user_id' => 'required',
'post.category_id' => 'required',
'post.image' => 'required',
'tagss' => 'required'
];
public function mount(Post $post)
{
$this->post = $post;
$this->tagss = $post->tags->toArray();
$this->identificador = rand();
}
public function save()
{
$this->validate();
$this->post->save();
/* codigo para borrar la foto Aqui */
$this->post->tags()->sync($this->tagss);
$this->reset(['open']);
$this->emitTo('show-post', 'render');
}
public function render()
{
$categories = Category::all();
$tags = Tag::all();
return view('livewire.edit-hide-form', compact('categories', 'tags'));
}
}
View
<div class="mb-2">
#auth
#if (auth()->user()->id === $post->user->id)
<x-jet-button wire:click="$set('open', true)">
Editar
</x-jet-button>
<x-jet-danger-button>
Eliminar
</x-jet-danger-button>
#endif
#endauth
</div>
<x-jet-dialog-modal wire:model="open" id="commentModal">
<x-slot name="title">
<h1 class="text-2xl mb-4">Edita tu post</h1>
</x-slot>
<x-slot name="content">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="container bg-white border-b border-gray-200 shadow-lg mx-auto justify-center px-4 py-2 ">
<section id="contact-us">
<div wire:loading wire:target='image'
class="bg-red-100 border border-red-400 text-xl font-normal max-w-full flex-initial">
<div class="py-2">
<p class="ml-2">Cargando la imagen</p>
<div class="text-sm font-base">
<p class="ml-2">Espero unos instantes mientras termine el proceso...</p>
</div>
</div>
</div>
#if ($image)
<img class="mb-4" src="{{ $image->temporaryUrl() }}" alt="">
#else
<img src="{{ Storage::url($post->image) }}" alt="">
#endif
<input class="hidden" wire:model="id_user" type="text" id="id" name="user_id" value={{
Auth::user()->id }}" />
<div>
<x-jet-label for="name" value="{{ __('Título') }}" />
<x-jet-input id="slug-source" class="block mt-1 mb-2 w-full" wire:model.defer="post.name"
type="text" name="name" required autofocus autocomplete="name" />
<x-jet-input-error for="name" />
<x-jet-label for="slug" value="{{ __('Slug') }}" />
<x-jet-input id="slug-target" class="block mt-1 w-full" wire:model.defer="post.slug"
type="text" name="slug" :value="old('slug')" required autofocus autocomplete="slug" />
<x-jet-input-error for="slug" />
</div>
<!-- body -->
<div>
<x-jet-label for="body" class="mt-4 text-base" value="{{ __('Contenido del post') }}" />
<textarea wire:model.defer="post.body" id="editor" rows="8" name="body"></textarea>
</div>
<x-jet-input-error for="body" />
<div class="mt-2 center justify-center mx-auto">
<!-- Image -->
<x-jet-label for="url" value="{{ __('Imagen') }}" />
<input type="file" id="image" name="image" class="mb-2" wire:model.defer="post.image" />
<x-jet-input-error for="image" />
</div>
<div>
<!-- Drop Down-->
<x-jet-label for="categories" value="{{ __('Categoría') }}" />
<select name="category_id" class="block font-medium text-sm text-gray-700" id="categories"
wire:model.defer="post.category_id">
<option selected disabled>opciones </option>
#foreach($categories as $category)
<option value="{{ $category->id }}">{{ $category->name }}</option>
#endforeach
</select>
</div>
<br>
<div>
<x-jet-label for="tags" value="{{ __('Etiquetas') }}" />
#foreach ($tags as $tag)
<label for="tagss"
class="relative flex-inline items-center isolate p-2 mr-4 mb-2 rounded-2xl">
<input wire:model.defer="tagss" value={{ $tag->id }} type="checkbox" class="relative
peer z-20 text-blue-600 rounded-md focus:ring-0" />
<span class="ml-1 relative z-20">{{ $tag->name }}</span>
</label>
#endforeach
</div>
<br>
<x-jet-label for="status" value="{{ __('Status') }}" />
<div class="flex">
<div class="inline-block rounded-lg">
Borrador <input type="radio" value=1 wire:model.defer="post.status" id="borrador" />
</div>
<div class="inline-block rounded-lg ml-4">
Publicado <input type="radio" value=2 wire:model.defer="post.status" name="publicado"
id="publicado" />
</div>
</div>
</section>
</div>
</div>
</x-slot>
<x-slot name='footer'>
<x-jet-secondary-button wire:click="$set('open', false)">
Cancelar
</x-jet-secondary-button>
<x-jet-danger-button wire:click="save">
Actualizar
</x-jet-danger-button>
</x-slot>
</x-jet-dialog-modal>
#push('js')
<script src="https://cdn.ckeditor.com/ckeditor5/34.0.0/classic/ckeditor.js"></script>
<script>
ClassicEditor
.create( document.querySelector( '#editor' ) )
.then(function(editor){
editor.model.document.on('change:data', () => {
#this.set('body', editor.getData());
})
})
.catch( error => {
console.error( error );
} );
</script>
#endpush
</div>
I would appreciate any help or advice, thanks
Charles, I wrote a POC (Proof of concept) for this problem and just found that it's related to a typo, haha.
You have the public property taggs and then you're assigning $this->tagss, that's why livewire wasn't rendering the checkboxes correctly.
I would recommend you to switch to a more verbose property like tagsSelected instead of taggs (or tagss).

how to display many to many relationship data in laravel livewire?

Good night all. I have a problem when I want to display many to many relationship data, namely postal data based on tags with livewire. Previously I tried in laravel can appear.
Now I want to display post data by tag with livewire but still can't.
the following is the code that I have made.
web.php
Route::get('tag/{tag:slug}',[FrontController::class, 'tag'])->name('tag');
FrontController.php
public function tag(Tag $tag)
{
$categories = Category::all();
$general = General::find(1);
$locale = App::currentLocale();
$search = request("search");
$posts = $tag->posts()->where([
['status','PUBLISH'],
['lang',$locale],
])->latest()->paginate(12);
if ($this->search !== null) {
$posts = $tag->posts()->where([
['title','like', '%' . $search . '%'],
['lang',$locale],
['status','PUBLISH'],
])->latest()->paginate(12);
}
// dd($posts);
$tags = Tag::all();
$top = Post::where('status','PUBLISH')->orderBy('views','desc')->limit(5)->get();
return view ('front.tag',compact('categories','general','locale','posts','tags','top'));
}
tag.blade.php
#extends('layouts.front')
#section('content')
<main id="main">
<section class="post-category">
<div class="container-fluid">
<div class="row mt-3">
<div class="col-lg-3 col-md-12 col-sm-12 d-none d-lg-block">
<div class="sticky-top" style="top: 90px;">
<div class="card mb-3 rounded-3">
<div class="card-body">
<a href="#" target="_blank" rel="noreferrer">
<img src="{{ asset('front/img/ads.png') }}" alt="..." height="300" width="279" class="card-img-top" />
</a>
</div>
</div>
<div class="d-flex flex-column mb-3 bg-light shadow bg-body rounded">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
{{ __('sentence.category') }}
</div>
<ul class="list-group list-group-flush">
#foreach ($categories as $category)
<li class="list-group-item d-flex justify-content-between align-items-center">
{{ $category->name }}
</li>
#endforeach
</ul>
</div>
<div class="d-flex flex-column bg-light bg-body shadow-lg rounded-3">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
Tags
</div>
<div class="p-3 overflow-auto" style="max-height: 42vh">
<div class="nav tag-cloud">
#foreach ($tags as $tag)
{{ $tag->name }}
#endforeach
</div>
</div>
</div>
</div>
</div>
<livewire:tag-index>
<div class="col-lg-3 col-md-12 col-sm-12">
<div class="sticky-top" style="top: 90px;">
<div class="card rounded-3 shadow-lg mb-3">
<div class="card-body">
<img src="{{ asset('front/img/ads1.png') }}" height="117" width="279" class="card-img-top" alt="...">
</div>
</div>
<div class="bg-light shadow bg-body rounded-3 mb-3">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
{{ __('sentence.top_article') }}
</div>
<ul class="list-group list-group-flush mb-2">
#foreach ($top as $top)
<li class="list-group-item">
{{ $top->title }}
<div class="d-flex justify-content-between mt-3">
<small class="text-muted">{{ Carbon\Carbon::parse($top->created_at)->format("d F, Y") }}</small>
<small class="text-muted">{{ $top->views }} views </small>
</div>
</li>
#endforeach
</ul>
</div>
<div class="d-flex flex-column mb-3 bg-light shadow bg-body rounded d-lg-none d-xl-none">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
{{ __('sentence.category') }}
</div>
<ul class="list-group list-group-flush">
#foreach ($categories as $category)
<li class="list-group-item d-flex justify-content-between align-items-center">
{{ $category->name }}
</li>
#endforeach
</ul>
</div>
<div class="d-flex flex-column bg-light bg-body shadow-lg rounded-3 d-lg-none d-xl-none">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
{{ __('sentence.tag') }}
</div>
<div class="p-3 overflow-auto" style="max-height: 42vh">
<div class="nav tag-cloud">
#foreach ($tags as $tag)
{{ $tag->name }}
#endforeach
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
#endsection
#push('scripts')
#livewireScripts
<script type="text/javascript">
window.onscroll = function (ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
window.livewire.emit('tag-index');
}
};
</script>
<script>
document.getElementById('load-more').onclick = function() {
window.livewire.emit('tag-index');
};
</script>
#endpush
livewire\TagIndex.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\{Tag, Post};
use Illuminate\Support\Facades\App;
class TagIndex extends Component
{
public $limitPerPage = 10;
public $search;
protected $listeners = [
'tag-index' => 'TagIndex'
];
protected $updatesQueryString = [
['search' => ['except' => '']],
];
public function TagIndex()
{
$this->limitPerPage = $this->limitPerPage + 6;
}
public function render(Tag $tag)
{
$locale = App::currentLocale();
$posts = $tag->posts()->where([
['status','PUBLISH'],
['lang',$locale],
])->latest()->paginate($this->limitPerPage);
if ($this->search !== null) {
$posts = $tag->posts()->where([
['title','like', '%' . $this->search . '%'],
['status','PUBLISH'],
['lang',$locale],
])->latest()->paginate($this->limitPerPage);
}
$this->emit('postStore');
return view('livewire.tag-index', ['posts' => $posts]);
}
}
livewire\tag-index.blade.php
<div class="col-lg-6 col-md-12 col-sm-12">
<div id="section-title" class="section-title p-1 pt-3">
<h2 class="text-center fw-bold">{{ trans('sentence.recent_posts')}}</h2>
</div>
<div class="form-group has-search mb-3">
<span class="bi bi-search form-control-feedback"></span>
<input type="text" wire:model="search" class="form-control" placeholder="{{ __('sentence.search_form') }}">
</div>
#foreach ($posts as $data)
<div class="card bg-light shadow bg-body rounded-3 mb-2">
<div class="card-header bg-primary text-white d-flex justify-content-between">
<small>by {{$data->admin->name}}</small>
<small>{{ Carbon\Carbon::parse($data->created_at)->format("d F, Y") }}</small>
</div>
<div class="card-body">
<h2 class="card-title">
{{ $data->title }}
</h2>
<div class="card-footer bg-body d-flex justify-content-between align-items-center pb-0 px-0">
<div class="d-flex my-1">
#foreach ($data->tags as $tag)
{{ $tag->name }}
#endforeach
</div>
</div>
</div>
</div>
#endforeach
#if ($posts->count() == 0)
<div class="alert alert-danger" role="alert">
Data not found!
</div>
#endif
#if($posts->count() >= 10)
<div class="text-center d-md-none d-lg-none d-xl-none">
<button id="load-more" class="btn btn-primary my-3">
Load More
</button>
</div>
#endif
</div>
what is the correct way or code to display many to many relationship data with livewire? in this case, I want to display post data by tag. thank you
There is a lot of additional stuff going on in your question so I have put together a simplified example for you. You will need to do the remainder of the work to get it into your project.
I don't know how you're displaying your tag labels or anything, so I have gone with checkboxes as it seems the most sensible. These could be styled to be hidden so they more closely resemble the tag labels on SO but again, I will leave the bike shedding to you.
I created a Livewire component called Tags with an associated blade view.
tags.blade.php
<div>
{{-- loop over each of the tags --}}
#foreach ($this->tags as $tag)
{{-- wire:key is important here as Livewire requires it for effective DOM diffing! --}}
<div wire:key="tag-{{ $tag->id }}" class="block px-4 py-2">
{{--
this is where we bind the checkboxes
to a property on the Livewire component
--}}
<input wire:model="selectedTags" type="checkbox" id="tag-{{ $tag->id }}" name="{{ $tag->title }}" value="{{ $tag->id }}">
<label for="{{ $tag->title }}">{{ $tag->title }}</label>
</div>
#endforeach
{{-- loop over each of the posts --}}
#foreach ($this->posts as $post)
{{-- again, don't overlook wire:key! --}}
<div wire:key="post-{{ $post->id }}" class="block px-4 py-2">
<h4 class="text-sm">{{ $post->title }}</h4>
</div>
#endforeach
</div>
The above should be mostly self explanatory, the only bit that might not be is wire:model="selectedTags". A public property called selectedTags is defined on the Tags component (as you'll see in a moment) and what this does is allow us to manage elements in that array when one of the checkboxes is selected. So for example when someone checks the checkbox for tag with id of 12, the selectedTags array has an element added with the value of 12.
Tags.php
class Tags extends Component
{
// array of selected tags (checked checkboxes)
public $selectedTags = [];
// get just the id and title of each tag
public function getTagsProperty()
{
return Tag::select('id', 'title')->get();
}
public function getPostsProperty()
{
$tags = array_filter($this->selectedTags);
// if no tags are selected, return all posts
// you might decide to return nothing, up to you
if (!$tags) {
return Post::all();
}
// if there are some selected tags
// query the database for posts with the selectedTags
// this is an `OR` operation on tags
// if you want `AND` you'll need to change it
return Post::whereHas('tags', function ($query) use ($tags) {
$query->whereIn('tags.id', $tags);
})->get();
}
public function render()
{
return view('livewire.tags');
}
}
Again the above should be self explanatory as there is nothing out of the ordinary going on.
The getPostsProperty() and getTagsProperty() functions define computed properties which are optional, you could just use normal properties if you wish. However, if you're referencing $tags and $posts multiple times in your component views, a computed property is more performant as it doesn't make a call to the backend component each time.
SOLVED
thanks #Peppermintology for helping my two issues and now this issue is solved with below code.
FrontController.php
public function tag(Tag $tag)
{
$categories = Category::all();
$general = General::find(1);
$locale = App::currentLocale();
$tag_id = $tag->id;
$search = request("search");
$posts = $tag->posts()->where([
['status','PUBLISH'],
['lang',$locale],
])->latest()->paginate(12);
if ($this->search !== null) {
$posts = $tag->posts()->where([
['title','like', '%' . $search . '%'],
['lang',$locale],
['status','PUBLISH'],
])->latest()->paginate(12);
}
$tags = Tag::all();
$top = Post::where('status','PUBLISH')->orderBy('views','desc')->limit(5)->get();
return view ('front.tag',compact('categories','general','locale','posts','tags','tag_id','top'));
}
livewire\TagIndex.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\{Tag, Post};
use Illuminate\Support\Facades\App;
class TagIndex extends Component
{
public $limitPerPage = 10;
public $search, $tagId;
protected $listeners = [
'tag-index' => 'TagIndex'
];
protected $updatesQueryString = [
['search' => ['except' => '']],
];
public function TagIndex()
{
$this->limitPerPage = $this->limitPerPage + 6;
}
public function render()
{
$locale = App::currentLocale();
$tag_id = $this->tagId;
$tag = Tag::find($tag_id);
$posts = $tag->posts()->where([
['status','PUBLISH'],
['lang',$locale],
])->latest()->paginate($this->limitPerPage);
if ($this->search !== null) {
$posts = $tag->posts()->where([
['title','like', '%' . $this->search . '%'],
['status','PUBLISH'],
['lang',$locale],
])->latest()->paginate($this->limitPerPage);
}
$this->emit('postStore');
// dd($posts);
return view('livewire.tag-index', ['posts' => $posts, 'tag' => $tag]);
}
}

Larvel Update and Destroy route not working [duplicate]

This question already has answers here:
How to make a delete request with Laravel
(2 answers)
Closed 2 years ago.
The accept button has the route route('members.update', $member->id)
The deny button has the route route('members.destroy', $member->id)
These are the cards:
#foreach ($members as $member)
<div class="my-1 px-1 w-full md:w-1/2 lg:my-4 lg:px-4 lg:w-1/3">
<article class="bg-white overflow-hidden rounded-lg shadow-lg">
<div class="flex items-center justify-between leading-tight p-2 md:p-4 w-max">
<div class="w-1/2">
<small class="text-gray-600">Full name:</small>
<h1 class="text-lg pr-2"> {{ $member->firstname }} {{ $member->lastname }} </h1>
</div>
<div class="w-1/2">
<small class="text-gray-600">Birthdate:</small>
<h1 class="text-lg">{{ date('d-m-Y', strtotime($member->birthdate)) }}</h1>
</div>
</div>
<div class="flex items-center justify-between leading-tight p-2 md:p-4">
<div class="w-1/2">
<small class="text-gray-600">Student id:</small>
<h1 class="text-lg pr-2">{{ $member->studentid }}</h1>
</div>
<div class="w-1/2">
<small class="text-gray-600">Discord:</small>
<h1 class="text-lg">{{ $member->discordname }}{{ $member->discordtag }}</h1>
</div>
</div>
<footer class="flex items-center leading-tight p-2 md:p-4 justify-start">
<form method="PATCH" action="{{ route('members.update', $member->id) }}">
#method('PATCH')
<button class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded mr-2">Accept</button>
#csrf
</form>
<form method="DELETE" action="{{ route('members.destroy', $member->id) }}">
#method('DELETE')
<button class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">Deny</button>
#csrf
</form>
</footer>
</article>
</div>
#endforeach
And this is my controller:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Member;
use Illuminate\Http\Request;
class MemberController extends Controller {
public function index() {
$members = Member::where(['status' => false])->get();
return view('dashboard')->with(['members' => $members]);
}
public function show($id) {
$members = Member::where(['id' => $id])->get();
return view('dashboard')->with(['members' => $members]);
}
public function store(Request $request) {
$validatedData = $request->validate([
'firstname' => 'required|max:255|alpha|min:2',
'lastname' => 'required|max:255|alpha|min:2',
'studentid' => 'required|integer|alpha_num',
'birthdate' => 'required|date',
'discordname' => 'required|max:255',
'discordtag' => 'required|max:255|size:5'
]);
$member = new Member;
$member->firstname = $request->firstname;
$member->lastname = $request->lastname;
$member->studentid = $request->studentid;
$member->birthdate = $request->birthdate;
$member->discordname = $request->discordname;
$member->discordtag = $request->discordtag;
$member->status = false;
$member->save();
return \redirect()->route('index');
}
public function update($id) {
die;
$member = Member::find($id);
$member->status = 1;
$member->save();
return \redirect()->route('dashboard');
}
/**
* TODO - SEND EMAIL ON DELETE
*
* #return void
*/
public function destroy($id) {
DB::delete('delete members where id = ?', [$id]);
}
public function accepted($id) {
update($id);
}
}
My routes:
When i click the accept or deny button it sends me to this link: http://hit.localhost.nl/members/3?_method=PATCH&_token=0g5odDLEKCicceDOf4EuPMGIB1X95cwWHGMxMqcR
And runs the show() function instead of the update or destroy functions. What am i doing wrong here?
method="PATCH" and method="DELETE" don't exist, just get, post and dialog. Change both of those to method="post".

Categories