Laravel Livewire radio input not returning its value on the component view - laravel

hello I'm new to livewire, I created a component for the radio buttons and I'm trying to show the selected radio value on the component view but its always giving null no matter what is the checked radio its always null
The Component View
#foreach ($brands as $brand)
<div class="template-checkbo">
<input wire:model="brandsVal" name="brandsVal" type="radio" value="{{ $brand->id }}">
<label class="main-label">
{{ $brand->name }}
</label>
</div>
#endforeach
#dump($brandsVal)
The Component Class
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class BrandSidebar extends Component
{
public $brands;
public $brandsVal;
public function render()
{
return view('livewire.brand-sidebar');
}
}

I found the solution after opening the console and seeing a Warning not an error
Livewire: Multiple root elements detected. This is not supported.
Apparently The view component must have one root element other wise the whole functionality wont work according to this doc:
https://laravel-livewire.com/docs/2.x/troubleshooting#root-element-issues

I think the issue is with this here
wire:model="brandsVal"
The issue with the current implementation is that all of the radio buttons have the same name attribute "brandsVal" and the same wire:model value "brandsVal", so when one of the buttons is selected, all of the buttons will have the same value.
in your component class,
try this instead
//from public $brandsVal;
public $brandsVal = []; //sets the brandsVal property to an array.
Now generate the input elements in your blade file like this
#foreach ($brands as $brand)
<div class="template-checkbo">
<input wire:model="brandsVal.{{ $brand->id }}" type="radio" value="{{ $brand->id }}">
<label class="main-label">
{{ $brand->id }}
</label>
</div>
#endforeach
Secondly, are you passing anything here? public $brands;
Lastly, make sure to wrap your livewire blade file into just one html element.

Related

Laravel Livewire form, if validation fails, pivots don't work

I have a form made with Livewire in Laravel.
This is the Livewire controller
namespace App\Http\Livewire;
use Livewire\Component;
use App\Rules\Mobile;
class Form extends Component
{
public $mobile;
public $required;
public $fields;
public $showDropdown = true;
public function mount()
{
foreach($this->fields as $field){
$this->required[$field->name] = ($field->pivot->is_required == '1') ? 'required' : 'nullable';
}
}
public function submit()
{
$validatedData = $this->validate([
'mobile' => [$this->required['mobile'] ?? 'nullable', new Mobile()]
]);
}
}
This is the Livewire view
<div>
<div x-data="{ open: #entangle('showDropdown').defer, required: #js($required) }">
<span x-show="open" wire:loading.remove>
<form wire:submit.prevent="submit" style="display: flex; flex-direction: column;">
<div class="fields">
#foreach($fields as $field)
<div class="form-{{$field->name}}">
#if($field->name == 'mobile')
<input name="{{$field->name}}" type="tel" wire:model.defer="{{ $field->name }}" placeholder="{{ __($field->pivot->placeholder ?? $field->name) }}">
#endif
#error($field->name) <span class="error">{{ ucfirst($message) }}</span> #enderror
</div>
#endforeach
</div>
<button class="btn btn-primary">Send</button>
</form>
</span>
</div>
</div>
Problem is here placeholder="{{ __($field->pivot->placeholder ?? $field->name) }}"
When the form is first loaded $field->pivot->placeholder is set, but after I submit the form and the validation fails, it's not set anymore and $field->name is used instead of $field->pivot->placeholder
Have checked this way:
<input name="{{$field->name}}" type="tel" wire:model.defer="{{ $field->name }}" placeholder="{{ __($field->pivot->placeholder ?? $field->name) }}">
{{ var_dump(isset($field->pivot->placeholder)) }}
When the form is first loaded it prints bool(true) under the field, after I send the form it says bool(false)
How can I get over this? Why the pivot does not work after validation fails?
//Edit: Did a workaround, but I would still like to know why it happens
What I did is I used another property $placeholders
In the Livewire controller have added public $placeholders;, in the mount() have added $this->placeholders[$field->name] = $field->pivot->placeholder ?? $field->name;, and then used it in the view like placeholder="{{ __($placeholders[$field->name] ?? $field->name) }}"
I don't know much about livewire , but I know that mount() only called on the initial page load meaning it will only run when you refresh the whole page or visit the page. Instead of only using mount() you should also use hydrate() which will run every subsequent request after the page load.
mount() - Initial Page Load
hydrate() - Every subsequent request
You can implement the hydrate() like how you implement the mount()

Livewire uncaught (in promise) DOMException with select

I have a dropdown in my component that seems to be causing an error in Livewire.
Uncaught (in promise) DOMException: Failed to execute 'setAttribute'
on 'Element': '?' is not a valid attribute name.
I added the wire:key code based on what I read in the docs under the troubleshooting section, but it didn't seem to help. It updates the value on save just like it should, but when it refreshes the dom with the new data, it's not working.
Here's the offending element:
<div class="mb-3 col-md-4 ">
<label for="state" class="form-label">State</label>
<select wire:model.defer="location.state" class="form-select"
id="state" name="state">
#foreach ($states as $state)
<option
name="{{ $state->name }}"
id="{{ $state->code }}"
wire:key="{{ $state->id }}"
value="{{ $state->code }}"
#if (isset($location->state)
&& $location->state === $state->code) ? selected #endif
>{{ $state->name }}
</option>
#endforeach
</select>
</div>
You have a typo here,
#if (isset($location->state) && $location->state === $state->code)
? selected
#endif
Where it tries to apply ? as an attribute on the element, but ? is not a valid attribute. Just remove the ?.
That said, you cannot use the selected property on <select> elements in Livewire to set the selected value. You need to set the value of your wire:model in your component. This means that you have to remove the #if(..) selected #endif from your Blade entirely, and instead set the value in your component,
public function mount() {
$this->location['state'] = $state->code;
}

Laravel Livewire: Input select, default option selected

I am trying to fetch country codes from my database and trying to get the default value via IP address. It works just as I want for a second but then I don't know what happens but it refreshes itself and scrolls to the first option instead of the selected option.
Livewire Controller Component
use App\Models\CountryCodes;
use Livewire\Component;
use Location;
class TestCountry extends Component
{
public $iso;
public $country_codes;
public $country_code;
public function mount()
{
$iso=Location::get('ip');
$this->iso=$iso->countryCode;
}
public function render()
{
return view('livewire.test-country',[
$this->country_codes = CountryCodes::select('nicename','iso','phonecode')->get()->toArray()
]);
}
}
Livewire Blade Component
<select wire:model.lazy="country_code" name="country_code" id="country_code" class="form-control" required>
#foreach($country_codes as $country_code)
<option value="{!! $country_code['iso'] !!}"
wire:key="{{$country_code['iso']}}"
{{ $country_code['iso'] == $iso ? 'selected' : ''}}>
{!! $country_code['iso'] !!} +{!! $country_code['phonecode'] !!}
</option>
#endforeach
</select>
This code does select my default option but it changes and moves to the first option automatically. Am I doing something wrong here?
I believe what is happening is, $iso is set correctly, but the select is bound to the $country_code property, not $iso, so briefly, the check you have works, but because $country_code doesn't have a value, the selected option is lost when the state is updated by Livewire.
TLDR: Livewire is checking whatever is in the wire:model attribute, so the class property must be set for it to work.
I would try something like this:
public function mount()
{
$iso = Location::get('ip');
$this->iso = $iso->countryCode;
// set $country_code to $iso
$this->country_code = $this->iso;
}
I believe Livewire will intelligently select the state, so I think the selected check can be removed:
<select wire:model.lazy="country_code" name="country_code" id="country_code" class="form-control" required>
#foreach($country_codes as $country_code)
<option
value="{!! $country_code['iso'] !!}"
wire:key="{{$country_code['iso']}}"
>
{!! $country_code['iso'] !!} +{!! $country_code['phonecode'] !!}
</option>
#endforeach
</select>
Also, any reason for using {!! !!} tags in the view rather than just {{ }}?

Issues with radio button in laravel

i want to set the radio button in the form using controller
( note: no database included).
And i even have no idea how to set the radio
button in the form using controller .
{this is my radio button}
<div class="row">
<div class="col-25">
<label for="gender">Gender</label>
</div>
<div class="col-75">
<input type="radio" name="gender" value="male" > Male
<input type="radio" name="gender" value="female"> Female
</div>
</div>
this is my controller :
class NewController extends Controller
{
public function index(Request $request)
{
$fullname='sagar basnet';
$subject='this is my test form';
return view('newfile/forms')
->withFullname($fullname)
->withSubject($subject);
}
I am going make a best effort to answer your question as their is no sample code provided.
I am assuming that you want to set the state of a radio button in the UI based on conditions that occur within your controller logic.
In your controller..
$radioVal = false;
if ($condition) {
$radioVal = 'checked';
}
return view('your.view', [
'radioVal' = $radioVal;
]);
The condition is the condition that determines whether or not your radio is checked (e.g. apples = fruit)...
In your view...
<input type="radio" {{ $radioVal or 'checked' }} />
The "or" keyword in blade offers you a ternary shorthand alternative.
You will need to give your radio button a name obviously...

Laravel 5.5 - Passing form's Data to Controller then Passing Data from Controller to the same View

I give up ! 2days i'm looking for solution for my problem.
All I need is pass FORM Data to Controller, then just show it on the same View.
Easy, right ? But i can not find any solution and Laravel's Manual does not explain that clearly...
So this is my View with the form :
form.blade.php
<form action="{{ action('FormController#ReceiveDataForm') }}" method="post">
<input type="text" name="name" placeholder="Enter your name">
<input type="text" name="surname" placeholder="Enter your surname">
<input type="submit" value="Send">
</form>
<div class="ShowDataHere">
{{-- Here i want to show this Data from FORM above, but with using Controller. --}}
</div >
My Controller receiving data:
FormController.php
namespace App\Http\Controllers;
use Input;
use Illuminate\Http\Request;
class FormController extends Controller
public function Form()
{
return view('test.form');
}
public function ReceiveDataForm()
{
Input::post('name');
Input::post('surname');
}
And my question is how to pass this Data to the same View and show it on
user's screen ?
Please note that Data must be basically pushed to the Controller, just then passing to the View via Routing.
All solution i found in Internet does not work for me, what guys am i doing wrong ?
If you do not know proper answer, please direct me where to find it or similar.
Thank You !
You can do
public function ReceiveDataForm(Request $request)
{
//Input::post('name');
//Input::post('surname');
return view('test.form');
}
Import the Request class by adding use Illuminate\Http\Request; in your controller.
In your view
<div class="ShowDataHere">
#if(!empty(request()->all()))
{{ request()->name }}
#endif
</div >
In your web.php file, make sure you have
Route::post('/test', 'FormController#ReceiveDataForm');

Resources