How to pass Model as parameters to the Wire (Livewire Laravel) - laravel

In the button, I can't pass Model product as parameters to the Wire (Livewire Laravel).
I have two function initiateEdit first in model stockin and the other in model product.
in this code only call the function that found in the stockin model but i want the function in the product model.
how to call the function for the specific model ?
<button
class="flex items-center p-2 text-sm font-medium leading-5 text-center text-white transition-colors duration-150 bg-gray-600 border border-transparent rounded-lg active:bg-gray-600 hover:bg-gray-700 focus:outline-none focus:shadow-outline-gray"
wire:click="$emit('initiateEdit', {{ $product['id'] }} )"
title="{{ __('Edit') }}">
<x-heroicon-o-pencil class="w-5 h-5" />
{{ $slot ?? '' }}
</button>
public function initiateEdit($id)
{
dd($id);
$this->selectedModel = $this->model::find($id);
}

Related

Laravel cannot find a Controller Method

Method App\Http\Controllers\CommunityController::show does not exist
My route
Route::get('/community/{id}', [CommunityController::class, 'community'])
->name('profile.community');
Controller
public function community($id)
{
$communityProfile = Community::find($id);
/* $join = CommunityUser::join('communities', 'communities.user_id', '=', 'community_users.user_id')->get(); */
return view('user.comprofile', compact('communityProfile', 'join'));
}
View community
#for ($i = 0; $i < 3; $i++)
<a href=" {{ route('profile.community', $communities[$i]->id) }} ">
<div class="w-full p-6 overflow-hidden bg-white border hover:bg-gray-50 border-gray-200 rounded-lg shadow-md dark:bg-gray-800 dark:border-gray-700">
<h5 class="mb-2 text-2xl font-semibold tracking-tight text-gray-900 dark:text-white">{{$communities[$i]->community}}</h5>
<p class="mb-3 font-normal text-gray-500 dark:text-gray-400 flex gap-3">
<x-iconsax-out-location class="text-[#F15E4A] w-5"/> {{$communities[$i]->address}}, {{$communities[$i]->city}}
</p>
<div class="flex gap-2">
<a href="#" class="inline-flex items-center font-semibold text-[#F15E4A] hover:underline cursor-default">
{{ $communities[$i]->type }}
</a>
#if ($communities[$i]->user_id === Auth::user()->id)
<span class="text-sm text-gray-500 pt-1">{{__('Created by: ')}}</span>
{{Auth::user()->name}}
#else
<span class="text-sm text-gray-500 pt-1">{{__('Created by: ')}}</span>
{{ $communities[$i]->name }}
#endif
</div>
</div>
</a>
#endfor
I am trying to view the community created by users but it gives me "cannot find a Controller Method ".
This can have several causes. Therefore, here is a small checklist:
The controller path is missing from your route:
use App\Http\Controllers\CommunityController; // this line
Route::get('/community/{id}', [CommunityController::class, 'community'])->name('profile.community');
Your CommunityController class name is misspelled
The namespace of the CommunityController is wrong
And then just to be sure, run: php artisan route:clear.

Laravel set class if radio button selected

I have these radio buttons:
It's a separate Laravel blade component.
#props(['active'])
#php
$classes = ($active ?? false)
? 'group relative border bg-white py-3 px-4 flex items-center justify-center text-black text-sm font-semibold uppercase focus:outline-none sm:flex-1 shadow-sm cursor-pointer transition duration-150 ease-in-out'
: 'group relative border py-3 px-4 flex items-center justify-center text-gray-300 text-sm font-semibold uppercase focus:outline-none sm:flex-1 shadow-sm cursor-pointer duration-150 ease-in-out';
#endphp
<label {{ $attributes->merge(['class' => $classes]) }}>
<input type="radio" name="size" value="{{ $slot }}" class="sr-only">
<span> {{ $slot }} </span>
<span class="absolute -inset-px pointer-events-none" aria-hidden="true"></span>
</label>
I call it on a different page like so:
<x-product-size>XS</x-product-size>
How do I change the variable if it's selected? I can only find solutions on changing it depending on the route by doing something like this:
<x-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')">
{{ __('Dashboard') }}
</x-nav-link>
You can use JS for this purpose.
add an id to your radio input for example radioID.
<input type="radio" id="radioID" name="size" value="{{ $slot }}" class="sr-only">
and:
<script>
$(document).ready(function () {
$('#radioID').on('change', function () {
var selected = this.value;
if(selected == "XS") // or a variable
var slot = "some data";
{
$("#spanID").append(' + slot + ');
}
});
});
</script>
If you want to add active to a div, span or something other you can do it like this using their CLASS or ID:
$('.someclass').first().addClass('active');
$('#someid').first().addClass('active');

Bind Livewire component to parent array

I have the following structure:
A parent component:
class SiteEditComponent extends Component
{
protected $listeners = ['upClicked', 'downClicked', 'childUpdated'];
public $childBlocks = [];
public function render()
{
return view('livewire.site-edit-component', ['childBlocks' => $this->childBlocks]);
}
}
Which renders that way:
<div>
<button wire:click="addBlock" type="button" class=" mb-3 inline-flex items-center px-2.5 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Block hinzufügen</button>
#foreach($childBlocks as $key => $childBlockContent)
<livewire:templates.text-block-component wire:model.debounce="childBlocks.key" :block="$childBlockContent" :wire:key="$key">
#endforeach
</div>
And the child component(s):
class TextBlockComponent extends Component
{
public $block;
protected $rules = [
'block.title' => ''
];
public function render()
{
return view('livewire.text-block-component', [
'block' => $this->block
]);
}
Which renders that way (simplified):
<div>
<div class="bg-white shadow sm:rounded-lg mb-3">
<div class="px-4 py-5 sm:p-6">
<div
class=" w-1/3 border border-gray-300 rounded-md px-3 py-2 shadow-sm focus-within:ring-1 focus-within:ring-indigo-600 focus-within:border-indigo-600">
<label for="name" class="block text-xs font-medium text-gray-900">Titel</label>
<input wire:model.debounce="block.title" type="text" name="title" id="name"
class="block w-full border-0 p-0 text-gray-900 placeholder-gray-500 focus:ring-0 sm:text-sm"
placeholder="Blocküberschrift">
</div>
</div>
</div>
</div>
In fact both components represent a Laravel model. A site can have multiple blocks.
What would be the right way to keep track of the child components in the parent component?
I want to implement a save button which should collect all items of $childBlocks, save the Site and attach the childBlocks to it. I tried to model it by using wire:model.debounce="childBlocks.key" but the binding doesn't seem to work.
I wanted to create an associative array in which every block is identified by a randomly generated key which holds the block data.

How to prevent using a parameter when before clicked in Livewire

This code is a part of the View file connected with the Livewire component.
How to prevent using a parameter when before a button clicked?
View
...
#foreach ($babies as $baby)
...
<div
class="flex justify-between w-11-12 py-1 mb-1 ml-2 leading-6 text-sm font-medium ext-left text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-blue-800 focus:outline-none">
<button wire:click="setAte({{ $baby, $ate = 0 }})"
class="flex w-1-3 mr-1 px-2 text-xs font-medium text-center text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-pink-800 focus:ring-ring-600 {{ $baby['ate'] == 0 ? "bg-blue-500" : "bg-red-500" }}">
S</button>
<button wire:click="setAte({{ $baby, $ate = 1 }})"
class="flex w-1-3 mr-1 px-2 text-xs font-medium text-center text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-pink-800 focus:ring-pink-600 {{ $baby['ate'] == 1 ? "bg-blue-500" : "bg-red-500"}}">
M</button>
<button wire:click="setAte({{ $baby, $ate = 2}})"
class="flex w-1-3 px-2 text-xs font-medium text-center text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-pink-800 focus:ring-pink-600 {{ $baby['ate'] == 2 ? "bg-blue-500" : "bg-red-500" }}">
L</button>
<div>{{ $baby['ate'] }}</div> {{-- <---check code --}}
</div>
#endforeach
...
Component
public function setAte($baby, $ate)
{
$baby['ate'] = $ate;
$selectedBaby = Baby::find($baby['id']);
$selectedBaby->save();
}
Error
Illuminate\Contracts\Container\BindingResolutionException
Unable to resolve dependency [Parameter #1 [ $ate ]] in class App\Http\Livewire\Classroom\BabyStatus
Solution 1
//Component
public $baby;
protected $rules = [
'baby.ate' => 'required|int|min:0|max:2'
];
public function updateAte($ate)
{
$this->baby->ate = $ate;
$this->baby->save();
}
//View
<button wire:model="baby" wire:click="updateAte(0)"
class="flex w-1-3 mr-1 px-2 text-xs font-medium text-center text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-pink-800 focus:ring-ring-600 {{ $baby['ate'] == 0 ? "bg-blue-500" : "bg-red-500"}}">S</button>
<button wire:model="baby" wire:click="updateAte(1)"
class="flex w-1-3 mr-1 px-2 text-xs font-medium text-center text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-pink-800 focus:ring-pink-600 {{ $baby['ate'] == 1 ? "bg-blue-500" : "bg-red-500"}}">M</button>
<button wire:model="baby" wire:click="updateAte(2)"
class="flex w-1-3 px-2 text-xs font-medium text-center text-white uppercase transition rounded shadow ripple hover:shadow-lg hover:bg-pink-800 focus:ring-pink-600 {{ $baby['ate'] == 2 ? "bg-blue-500" : "bg-red-500" }}">L</button>
That's all, thank you #Unflux.
I would be inclined to refactor what you have and make each baby a separate livewire component.
App\Http\Livewire\Baby.php
class Baby extends Component
{
// your instance of a baby
public $baby;
// required to allow updating of the baby properties
protected $rules = [
'baby.ate' => 'required|int|min:0|max:2'
];
public function render()
{
return view('livewire.baby');
}
// you can set the value of properties here if you want
public function mount()
{
// for example:
//$this->baby->ate = -100;
}
// when the value of ate is updated from the view
// update the baby model
public function updatedBaby()
{
$this->baby->save();
}
}
resoures\views\livewire\baby.blade.php
<div class="p-4 m-4">
<h4>Baby Component - ate: {{ $baby->ate }}</h4>
<div class="flex justify-between p-4 m-4">
<button wire:click="$set('baby.ate', 0)"
class="text-white px-2 rounded {{ $baby->ate === 0 ? "bg-blue-500" : "bg-red-500" }}">S
</button>
<button wire:click="$set('baby.ate', 1)"
class="text-white px-2 rounded {{ $baby->ate === 1 ? "bg-blue-500" : "bg-red-500" }}">M
</button>
<button wire:click="$set('baby.ate', 2)"
class="text-white px-2 rounded {{ $baby->ate === 2 ? "bg-blue-500" : "bg-red-500" }}">L
</button>
</div>
</div>
Note: The use of === in the above. Prevents null or similar values being incorrectly determined as equal to 0.
Then in your view:
#foreach($babies as $baby)
#livewire("baby", ["baby" => $baby]) // render your single baby component
#endforeach

Getting value to show up using livewire

I'm using laravel and livewire and I'm trying to create an edit page. What I'm trying to do is get the value to show up in the textbox.
So for example my edit page has product info that I'm trying to edit, but my product name isn't displaying in the textbox.
Here is my code
My ProductEdit.php
<?php
namespace Modules\Products\Http\Livewire;
use App\Models\Product;
use Livewire\Component;
class ProductsEdit extends Component
{
public $name;
public $product;
public function render()
{
return view('products::livewire.edit-products', [
'name' => $this->product->name
]);
}
public function updateProduct()
{
dd($this->name);
}
}
My edit-products.blade.php
<div class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
id="product_name"
type="text"
name="product_name"
value="{{ $product->name }}"
wire:model="name"
>
</div>
<button wire:click="updateProduct" class="bg-green-400 hover:bg-green-300 text-green-800 font-bold py-2 px-4 rounded inline-flex items-center">Save</button>

Resources