Crud operation with same modal Livewire - laravel

I'm using livewire for a new project so I want my crud operation with modal, in that case, I want to use one modal who responsible for creating and updating like vuejs. I try to do like this but this not work
In my blade
<form class="form" wire:submit.prevent="$editMode ? update : store">
In my component
public $editMode = false;
public function store() {
$this->editMode = false;
// code here
}
public function update() {
$this->editMode = true;
// code here
}
Livewire version: 2.x,
Can I achieve this Or do I have to use two modal for this? Thanks in advance

Your Livewire attributes cannot parse PHP, so you need to echo it out using blade. This will then re-render the component with the new submit method when you update the $editMode property in your Livewire component.
<form class="form" wire:submit.prevent="{{ $editMode ? 'update' : 'store' }}">
<!-- The rest of the form -->
</form>

Related

Fire an event from Laravel controller and listen on Livewire component

I'm trying to figure if i could emit an event from a Laravel regular controller and define a listener on a Livewire component. There's my journey so far:
I've generated the event:
php artisan make:event NewOrder
then, on the Controller method placeNewOrder i'm triggering the event like this:
event(new NewOrder())
On the Livewire component i define a varible $showNewOrderNotification and the listener:
public $showNewOrderNotification = false
protected $listeners = ['NewOrder' => 'notifyNewOrder'];
and setting the method notifyNewOrder
public function notifyNewOrder()
{
$this->showNewOrderNotification = true;
}
the livewire view is only showing an alert when the $showNewOrderNotification variable is true:
#if($showNewOrderNotification)
<div class="alert alert-danger text-uppercase">
New Orders !!!
</div>
#endif
This should be pretty straight forward but for some reason the listener is not getting the event.
I appreciate all the help.
user1 = order processor
user2 = customer
Scenario 1:
If user2 places a new order and you're trying to update user1's interface, you'll need to look into broadcasting to get your livewire component to pickup the event for user1.
https://laravel.com/docs/8.x/broadcasting
https://laravel-livewire.com/docs/2.x/laravel-echo
Scenario 2:
If user2 places a new order and you're trying to update user2's interface, it would probably be best to just convert the controller to an entire livewire component and avoid the controller all together. It can be done just storing session variables and checking for those variables using wire:init in your livewire blade view, but much easier to just do it all in a livewire component to begin with.

Laravel Livewire, form submit: do something first then submit the form

I have a livewire form which I intent to submit to an external url. However, before submitting, I want to programmatically add some hidden inputs which the user should not be able to edit then finally submit the form:
<form action="some-external-url" wire:submit.prevent="processForm" method="post">
<x-inputs.text-input wire:model="amount" name="amount" />
<x-inputs.button title="Submit" />
</form>
Something similar to this jQuery code:
$('form').submit( function(ev){
ev.preventDefault();
//fetch and add some additional fields to the form
// finally submit the form
$(this).unbind('submit').submit()
});
How best can I achieve this using livewire. Please note that I dont intent to use guzzle to submit this form.
If you want in your component you can set the properties, you need and then in your mount method, you initialise the value for those properties.
see forms in livewire
class ComponentName extends Component
{
public $hidden_val;
public function mount()
{
$this->hidden_val = "my_hidden_val";
}
}
Then pass it with livewire
<input type="hidden" wire:model="hidden_val">
But I also think as #ClémentBaconnier and would suggest to pass to external link the data of form using Http Client provided by laravel in your controller or event within your livewire component.
Http::asForm()->post('some-external-url', ['form_data' => /*your form data*/]);
Follow it here

Is it possible to use HTML form in Zend Framework instead of ZendForm?

Is it possible to use HTML form in Zend Framework instead of ZendForm ? In particular to a phtml file?
If so how is the <form action "abc.php"> going to work when form is submitted. Should I define abc.php in models?
Just a few weeks knowledge only on Zend Framework. Any helpful guidance.
Thanx in Advance.
Yes, you can use html form instead of zend form in phtml files.
In the form tag you can specify the route that you set in module.config.php of your module.
For example if you set this route in the module "user":
'route' => '/user[/:action][/:id]'
In the phtml file you can add the form tag in this way:
<form action="user/add" method="POST">
And in the UserController you can retreive data in the addAction.
public function addAction()
{
$request = $this->getRequest();
if ($request->isPost()) {
$formData = $request->getPost();
// do stuff
}
}

Laravel Livewire javascript code after model is load

I have one Laravel Livewire model open as bellow code
public function confirmItemAdd()
{
$this->resetValidation();
$this->confirmingItemAdd = true;
}
and my model window code in blade is
<x-jet-dialog-modal wire:model="confirmingItemAdd">
I have one select2 in model and want to set value of select2 on variable name $s2v
After search I findout that
$('.select2').val(s2v).trigger('change');
how can I set value of select2 on load on model?
Thanks
You can trigger a browser event from the livewire component and listen for that event and change the select2 value accordingly (assuming the select2 part is wire:ignored).
public $s2v = 'Test value';
public function confirmItemAdd()
{
$this->resetValidation();
$this->confirmingItemAdd = true;
$this->dispatchBrowserEvent('change-select2', $this->s2v);
}
in your layout file or with the stack in layout file you can listen for this event and trigger the change for the select2 as below,
<script>
$(window).on('change-select2', (e) => {
$('.select2').val(e.detail).trigger('change');
});
</script>
Note e.detail is the $s2v value passed from the livewire component.
And what validation error is giving to you? you are reseting the validation error before the dispatchBrowserEvent...seem that even by JS you are changing the select2 value the property doesn't
EDITED
Ok, first a have a particular issue with select2 rendering after each refresh and find this solution. In the component a have this:
public function hydrate()
{
$this->emit('select2');
}
and in blade parent or script section
<script>
$(document).ready(function() {
window.initSelectCompanyDrop=()=>{
$('#selectCompany').select2({
placeholder: '{{ __('locale.Select a Company') }}',
allowClear: true});
}
initSelectCompanyDrop();
$('#selectCompany').on('change', function (e) {
livewire.emit('selectedCompanyItem', e.target.value)
});
window.livewire.on('select2',()=>{
initSelectCompanyDrop();
});
});
</script>
If your issue with error bag persist, so you have to look into the kind of validation you're doing. In other case, I define global $message for a validation message but only works for $this->validate. Once I need redefine the validation, using Validator::make I have to create a new var $message for that inside the method

Better Way to use Laravel old and Vue.js

Im working using vue.js 2.0 and Laravel 5.4 I would like to know if exits a better way to send data Controllers -> views without lost the value, overwrite by the v-model
Because after charge vue.js this take the value in data that is define in this way
data: {
ciudad:'',
}
If I try to do something like that
<input class="form-control" id="ciudad" name="ciudad" type="text" v-model="documento.ciudad" value="{{ $documento->ciudad }}" >
I lost the value sending by the controller
Vue really expects you to init data from the view model which then updates the view, however, you want to use data in the view to update the underlying model data.
I think the easiest approach to this is to write a directive that inits the value from the HTML, so you don't need to directly access the DOM:
Vue.directive('init', {
bind: function(el, binding, vnode) {
vnode.context[binding.arg] = binding.value;
}
});
It's a little abstract so it's worth looking at Directive Hook Arguments section of the docs.
This can then be used like:
<input v-model="ciudad" v-init:ciudad="'{{ old('ciudad') }}'">
Here's the JSFiddle: https://jsfiddle.net/v5djagta/
The easy way to do this for me was in this way:
Laravel Controller
$documento = ReduJornada::where("id_documento",$id)->first();
return view('documentos.redujornada')->with(compact('documento'));
Laravel View
<input class="form-control" id="ciudad" v-model="documento.ciudad" value="{{ old('ciudad', isset($documento->ciudad) ? $documento->ciudad : null) }}" >
Vue.js
data: {
ibanIsInvalid : false,
documento: {
ciudad: $('#ciudad').val(),
}
In this way I can use the same view to create and edit an object, using the same form, even use laravel validation without lost the data after refresh.
If you know a better way to do that please tell me... Thanks
You have to define your value first, for example :
$oldValue = $request->old('value');
and then pass it to vue component, define props and use it in v-model
<script>
export default {
props: {
$oldValue : String,
}
};
</script>
<template>
<input class="form-control" id="ciudad" name="ciudad" type="text" v-model="oldValue">
</template>

Resources