Automatically set value of select input field with dynamic input with Livewire - laravel-livewire

I want to set by default a value for select tag each time i click the button "Ajouter paiement" however when i add selected="selected" livewire does not recognize it.
how can i pass the value 1 to livewire each time i click the button by default?
here's the code:
<div class="form-group">
<select id="" class="form-control" wire:model="status_paiement.{{ $key }}" oninvalid="this.setCustomValidity('Ce champ est obligatoire')" onchange="this.setCustomValidity('')" required>
<option value="1" selected="selected">regler</option>
<option value="0" >encours</option>
</select>
#error('status_paiement.'.$value) {{ $message }}#enderror
</div>
</div>```

I have the same problem. I will try to explain what I did to solve this problem.
Separate your form to another livewire component
foreach($payments as $payment){
#livewire('payments.update-form',['payment' => $payment,'key'=>$payment['id']]) //pass a key to uniquely identify this component
}
<?php
namespace App\Http\Livewire\Payments;
use Livewire\Component;
class paymentsUpdateForm extends Component
{
public $payment= [];
public $status = 'pending';
public function mount($payment){
$this->payment= $payment; //This will set the current payment
$this->status = $payment['status']; //This will set the default status of the current payment
}
public function render()
{
return view('livewire.payments.update-form');
}
}
This is what livewire/payments/update-form looks like
...
<select wire:model="status">
<option value="1">regler</option>
<option value="0">encours</option>
</select>
...
Each iteration will create a new Laravel component with the given payments and key. Inside the mount function of the Laravel component, assigns payment using the given data from the parent component and set the default payment status on the current payment. Hope you understand my explanation and this will help you. Cheers!

Related

Can't access variable after radio select. Livewire

New to Laravel / Livewire.
I have a component that outputs a radio group, It renders fine.
When I select one of the radio controls I get an error, "Attempt to read property "id" on array"
Here I pass an array of options from my blade file
#livewire('test-options', ['options' => $option])
Component
class TestOptions extends Component {
public $selected;
public $options;
public function mount($options)
{
$this->options = $options;
}
public function render()
{
return view('livewire.test-options', [
'options' => $this->options
]);
}
component blade
<div>
#foreach($options['items'] as $option_items)
<div class="custom-control custom-radio">
<input
wire:model="selected"
class="custom-control-input"
type="radio"
id="rdio_{{$option_items['0']->id}}_{{$options['option']->id}}">
<label class="custom-control-label" for="rdio_{{$option_items['0']->id}}_{{$options['option']->id}}">{{$option_items['0']->title}}</label>
</div>
#endforeach
The issue is, when you select a radio, Livewire is refreshing the component. However, the $options array is not being passed again. mount() will only run when the component is first rendered.
You are already passing the options into the component, the $optons variable does not need to be mounted as it is already loaded and set here:
#livewire('test-options', ['options' => $option])
Change your code to:
class TestOptions extends Component {
public $selected;
public $options;
public function render()
{
return view('livewire.test-options', [
'options' => $this->options
]);
}
If you're also trying to get a value from the radio input, you'll need to add a value:
<input
wire:model="selected"
class="custom-control-input"
type="radio"
value="yourvaluehere"
id="rdio_{{$option_items['0']->id}}_{{$options['option']->id}}">
From the docs:
In Livewire components, you use mount() instead of a class constructor __construct() like you may be used to. NB: mount() is only ever called when the component is first mounted and will not be called again even when the component is refreshed or rerendered.
Read more here: Receiving Parameters

Livewire checkbox preselected not working

I have collection of permission_types which i can access in my view. I am looping the permission_types to show each one in check box. all the checkboxes are binded to permission_resource, which is defined as a public property array. I want all the checkboxes to be preselected for which i used checked attribute but it won't work, as soon as i remove the wire:model attribute from input all the checkboxes are preselected. which narrows down the problem to wire:model binding.
What i am trying to achieve:
All i want to do is preselect the checkboxes binded to public property $permission_resource. Can anyone please help me out. I really cannot figure out what am i doing wrong here. Appreciate any effort to solve this problem in advance.
Relevent Component Code:
public $permission_types;
public $permission_resource = [];
public function render()
{
$this->permission_types = PermissionType::all();
// dd($this->permission_types->toArray());
return view('livewire.permissions.create-permission-component')
->extends('layouts.app')
->section('content');
}
Relevant View Code:
<div class="row">
#foreach($this->permission_types as $permissionType)
<div class="col-md-3">
<input wire:model="permission_resource" type="checkbox" class="filled-in chk-col-green form-control" id="{{$permissionType['name']}}" value="{{ $permissionType['name'] }}" checked />
<label for="{{ $permissionType['name'] }}" class="p-r-30">{{ ucfirst($permissionType['name']) }} Resource</label>
</div>
#endforeach
</div>
Permission Types Dump
What i have tried so far:
so far i have tried following but none of it worked for me.
1: defining public $permission_resource; instead of public $permission_resource = [];
2: wire:model="permission_resource.{{$permissionType["id"]}}"
3: wire:model="permission_resource.{{$permissionType["name"]}}"
4: wire:model.defer="permission_resource.{{$permissionType["id"]}}"
5: wire:model.defer="permission_resource.{{$permissionType["name"]}}"
6: name="permission_resource.{{$permissionType["id"]}}"
You are binding all the inputs to the same (array) variable, what you want to do is bind each to an element in that array, not to the array itself.
So you would need to prepopulate that array, and then bind each input using $loop->index.
Not sure if you have a good reason for populating permission_types in the render method, better in mount if it is not highly dynamic (likely to change from render to render).
Populating permission_resource in mount might look like this:
public function mount() {
$this->permission_types = PermissionType::all();
$this->permission_resource = $this->permission_types->pluck('name');
}
Then in the blade, bind to elements of the array, and don't set checked yourself, wire:model will always override this anyway, checking your checkbox if the thing you have bound to is truthy, and unchecking if bound var is falsey (this is why everything is unchecked for you with the wire:model binding them to the array, because empty($array) == false, if you just fix the casing of permission_type in the blade you will find the checkbox all come on when you check one, because they are all bound to the same thing).
<input wire:model="permission_resource.{{$loop->index}}" type="checkbox" class="filled-in chk-col-green form-control" id="{{$permission_type['name']}}" value="{{$permission_type['name']}}" />
PS: That will at least get to what you wanted, depending on what you are ultimately trying to do with permission_resource, it may not be a very good/useful representation for the purpose.
try this
public $permission = [];
protected $rules = [
...
'permission' => 'required|array',
];
public function create()
{
if ($this->validate()) {
$data = [
'name' => $this->name,
....
];
$model = Model::create($data);
if (!empty($this->permission)) {
$permissionId = PermissionType::whereIn('id', $this->permission)->pluck('id');
$model->permission()->attach($permissionId); // add name relation instead 'permission' , of create 'attach' of update 'sync'
}
}
}
public function render()
{
return view('livewire.permissions.create-permission-component', [
'permissions' => PermissionType::select('id', 'name')->get()
])
->extends('layouts.app')
->section('content');
}
in View
<div class="row">
#foreach($permissions as $permission)
<div class="col-md-3">
<input wire:model.defer="permission" wire:key="permission{{$permission->id}}" type="checkbox" value="{{$permission->id}}" class="filled-in chk-col-green form-control" />
<label for="{{ $permission->name }}" class="p-r-30">{{ ucfirst($permission->name) }} Resource</label>
</div>
#endforeach
</div>

Using ember computed property(filter) to filter model and using ember-models-table 2 for displaying in table format. It gives no record to show

Trying to display user details using ember-models-table addon. Also wanted to filter the data using a isActive field .Am using ember computed property for that (filter). First time when the page is loading am getting the correct result.But when i try to filter , i could see value for currentfilter is passed correctly but am not getting any results. The table says no records to show.
My .hbs code:
<div class="form-group">
<label for="show">Show:</label>
<select class="form-control" id="show" onchange={{action "filterUpdated" value="target.value"}}>
<option value="null">All</option>
<option value="true">Active</option>
<option value="false">Inactive</option>
</select>
</div>
{{models-table
data=filteredPeople
columns=columns
showColumnsDropdown=false
useNumericPagination=true
filteringIgnoreCase=true
showPageSize=true
}}
My controllers code:
users: alias('model'),
currentFilter: null,
filteredPeople: filter('users', function(user) {
if(this.get('currentFilter') === null) {
return true;
} else {
return user.isActive === this.get('currentFilter');
}
}).property('users', 'currentFilter'),
actions: {
filterUpdated: function (value) {
alert(value);
if (value=== null) {
this.set('currentFilter', null);
}
else {
this.set('currentFilter', value);
}
}
Please help.
After checking , i just noted it was a silly mistake, the filterUpdated method returns string and isActive field needs a boolean value.
I just included the follwing line to change it to boolean.
var isActiveS = (this.get('currentFilter') == 'true');
It worked.

How to get the element reference "this" in EmberJS events?

I want to access the target element in the called method in onchange. I have the following code:
Template
<select class="form-control" data-abc="1" onchange={{action 'someMethod' value="target.value"}} >
<option value="">Select</option>
.
.
.
</select>
Component
export default Ember.Component.extend({
actions: {
someMethod(value) {
jQuery(this).data("abc"); // <-- Want to access element here
}
}
});
But, this doesn't work.
When you use value="target.value", someMethod will receive only the value alone and it will not receive default event object.
onchange={{action 'someMethod'}}
your component code would be,
export default Ember.Component.extend({
actions: {
someMethod(event) {
//its event object, you can access event.target to get element or event.target.value to get the value.
}
}
})
I got the answer:
<select class="form-control" data-abc="1" onchange={{action 'someMethod' value="target"}} >
<option value="">Select</option>
.
.
.
</select>
As can be seen in above code, we can pass the target instead of target.value. Then wrap target in jQuery to access desired data attribute.

How to clear the typeahead input after a result is selected?

I'm using the ng-bootstrap typeahead component to search a customer database. When the user selects a customer from the typeahead results list, I navigate to a customer details page. I've got this working, but I want to clear the input field after navigation has taken place. I've tried setting the model to null or an empty string in the selectItem event logic, but this isn't working:
customer-search-typeahead.component.html
<template #resultTemplate let-r="result" let-t="term">
<div>
<div>
{{r.resource.name[0].given}} {{r.resource.name[0].family}}
</div>
<div>
{{r.resource.birthDate | date: 'dd/MM/yyyy'}}
</div>
</div>
</template>
<input type="text" class="form-control" [resultTemplate]="resultTemplate" (selectItem)="onSelect($event)"
[(ngModel)]="model" placeholder="Start typing a customer name..." [ngbTypeahead]="search"/>
customer-search-typeahead.component.ts
#Component({
selector: 'customer-search-typeahead',
template: require('./customer-search-typeahead.component.html'),
styles: [`.form-control { width: 300px; }`]
})
export class CustomerSearchTypeaheadComponent {
model: any;
searching: boolean;
constructor(private customerService: CustomerService, private router: Router) {}
onSelect($event) {
this.router.navigate(['/customers', $event.item.resource.id]);
this.model = null;
};
search = (text$: Observable<string>) =>
//omitted for brevity
}
The typeahead input looks like this after a selection has been made:
Solution
customer-search-typeahead.component.html
<input type="text" class="form-control" #input [ngbTypeahead]="search" (selectItem)="onSelect($event); input.value='' ">
customer-search-typeahead.component.ts
onSelect($event, input) {
$event.preventDefault();
this.router.navigate(['/customers', $event.item.resource.id]);
};
The issue you witnessing arises from the fact that the NgModel directive is updating model binding asynchronously and the actual model is updated after the onSelect method gets executed. So your model update gets overridden by the NgModel functionality.
Fortunately we (ng-bootstrap authors) got all the flex points in place to cover your use-case :-) There are a couple of things that you could do.
Firstly the $event object passed to the onSelect method has the preventDefault() method and you can call it to veto item selection (and as a result writing back to the model and input field update).
$event.preventDefault() will make sure that the model is not updated and the input field is not updated with the selected item. But text entered by a user will still be part of the input so if you want to clear up this as well you can directly update the input's value property.
Here is code demonstrating all those techniques together:
onSelect($event, input) {
$event.preventDefault();
this.selected.push($event.item);
input.value = '';
}
where input argument is a reference to the input DOM element:
<input type="text" class="form-control" #input
[ngbTypeahead]="search" (selectItem)="onSelect($event, input)">
Finally here is a plunker showing all this in practice: http://plnkr.co/edit/kD5AmZyYEhJO0QQISgbM?p=preview
The above one is template ref value solution.
This is for ngModel solution.
Html code:
<input type="text" class="form-control" [resultTemplate]="resultTemplate" (selectItem)="onSelect($event)"
[(ngModel)]="model" placeholder="Start typing a customer name..." [ngbTypeahead]="search"/>
Component code:
onSelect($event) {
$event.preventDefault();
this.model = null;
this.router.navigate(['/customers', $event.item.resource.id]);
};
$event.preventDefault();
for ngModel value change empty