Array management and preview with Laravel Livewire - php

When using an input file to load images with Livewire I found that if the user clicks to load multiple images it works correctly, but if he clicks on the same input a second time, the previews with Livewire are replaced by the selected images. second time. To solve this add an array that loads the images as follows:
My input file
<input wire:change="cargaImagenes" wire:model="imagen" type="file" name="imagen" accept="image/*" class="form-control-file" multiple>
Event Charge
public function cargaImagenes()
{
foreach ($this->imagen as $ima) {
array_push($this->imagenes, $ima);
}
}
The problem is that I do the previews of the images with Livewire in the following way:
#if ($imagenes)
<small>previsualización:</small>
<div class="form-inline">
#foreach($imagenes as $img)
<div wire:key="{{$loop->index}}">
<div class="m-2 img-thumbnail">
<img class="my-2 rounded img-fluid contenedor-img" src="{{ $img->temporaryUrl() }}">
<button class="btn btn-outline-danger" wire:click="eliminarImagen({{ $loop->index }})">
</button>
</div>
</div>
#endforeach
<br>
</div>
#endif
And the problem is that they don't show the first time I select images, it shows when I add more.
For the preview I use the $images property of the array
array_push($this->imagenes, $ima);
Can you give me a suggestion of what I could do to display all the images in the array.

This should work.
Remove wire:change completely.
<input wire:model="imagen" type="file" name="imagen" accept="image/*" class="form-control-file" multiple>
Hook on the updatedImagen() event method:
public function updatedImagen()
{
foreach ($this->imagen as $ima) {
$this->imagenes[] = $ima;
}
}

Related

laravel livewire files always gets uploaded in the last item of an array

I am trying to build a facebook clone on livewire, and i wanted to assign each comment section its own model so that's why i created an empty array in my class,
public $new_comments = array();
then for each post i tried to assign to its comment section 2 models (one for the comment body and the second one for the picture) based on the post id
<form class="form-group" wire:submit.prevent="test">
<input name="message" required class="form-control" placeholder="Write a comment..." wire:model="new_comments.{{ $post->id }}.body"></input>
<label for="comment_image" style="cursor: pointer"><i class="flaticon-photo-camera"></i></label>
<input type="submit"></input>
<input id="comment_image" type="file" wire:model="new_comments.{{ $post->id }}.image" class="d-none" accept="image/png, image/gif, image/jpeg">
</form>
#if ($new_comments[$post->id]['image'] ?? false)
<div class="d-flex justify-content-center">
<img src="{{ $new_comments[$post->id]['image']->temporaryUrl() }}" class="w-50">
</div>
#endif
but when i try uploading an image in the post number 1 for example, it always gets added in the last item of the array and i don't know why!
in this case i uploaded the image in the first post but magically its in the last item of the array
(you can notice that the other model is working perfectly fine!)
Can anyone help me with this problem? Thank you.

multiple value from dropdown in livewire

I have a dropdown and text input in a form. Form creates a course and I want to select classroom for course from dropdown and write its capacity to text input. But a course may have mutiple classrooms. How can I keep these classrooms and their capacity and show them in a table under the form?Like this:
Here's my code that keeps only one classroom and capacity
<div class="sm:col-start-1 sm:col-end-3 col-span-3 ">
<x-select x-on:change="isShowing = $event.target.value" name="classroom_id" label="{!! __('Classroom') !!}" wire:model="classroom_id"
id="classroom_id"
:options="$this->classrooms"/>
<x-jet-input-error for="classroom_id" class="mt-2" />
</div>
<div class="col-span-2 sm:col-span-1 " x-show="isShowing">
<label class="tf-form-label" for="capacity">
{{ __('Capacity') }}
</label>
<input wire:model.debounce.250ms="capacity" type="text" name="capacity" id="capacity" class="tf-input" />
<x-jet-input-error for="capacity" class="mt-2" />
</div>
$this->form->save();// firstly course saved
$classroom = new Classroom();
$classroom->course_id = $this->form->id;
$classroom->classroom_id = $this->classroom_id;
$classroom->capacity = $this->capacity;
$classroom->save();
Add the following codes in your component.
Component
public $classroom_id, $capacity;
$course = Course::create($validatedCourseData); // firstly course saved
// $this->classroom_id is array, because we set "multiple" in blade file
$course->classrooms()->attach($this->classroom_id);
Blade
Please add multiple in in your select box code.
<div class="sm:col-start-1 sm:col-end-3 col-span-3 ">
<x-select x-on:change="isShowing = $event.target.value" name="classroom_id" label="{!! __('Classroom') !!}" wire:model="classroom_id"
id="classroom_id"
:options="$this->classrooms" multiple/>
<x-jet-input-error for="classroom_id" class="mt-2" />
</div>
<div class="col-span-2 sm:col-span-1 " x-show="isShowing">
<label class="tf-form-label" for="capacity">
{{ __('Capacity') }}
</label>
<input wire:model.debounce.250ms="capacity" type="text" name="capacity" id="capacity" class="tf-input" />
<x-jet-input-error for="capacity" class="mt-2" />
</div>

Display a link if an item has a PDF in laravel

I am trying to get an item to display a link to PDF if that item has a PDF associated with it. I am not sure how the if statement would be formatted. I am using Laravel for this.
Here is the code that I have in the controller for the item:
//PDF Upload
if($request->hasFile('spec_sheet')) {
//Get file name and extension
$filenameWithExt = $request->file('spec_sheet')->getClientOriginalName();
//Get just file name
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
//Get Ext
$extension = $request->file('spec_sheet')->getClientOriginalExtension();
//Store file name
$fileNameOfPdfToStore = $filename. '.' .$extension;
//Upload
$path = $request->file('spec_sheet')->storeAs('public/mcelroy-specs', $fileNameOfPdfToStore);
}
$rental = new Rental;
$rental->title = $request->title;
$rental->name = $request->name;
$rental->description = $request->description;
$rental->product_image = $fileNameToStore;
$rental->spec_sheet = $fileNameOfPdfToStore;
$rental->save();
In the view I have this:
#foreach($rentals as $rental)
<article class="cards-item">
<figure class="card product">
<div class="card-images">
<img src="/storage/rentals/{{$rental->product_image}}" alt="" >
</div>
<figcaption class="card-content">
<h1 class="card-title">{{ $rental->title }}</h1>
<h2 class="card-title product_title">{{ $rental->name }}</h2>
<p class="card-text" style="text-align:left;">{{ $rental->description }}
#if(!empty($spec_sheet))
Download Spec Sheet
#endif
</p>
<form action="{{ route('cart.store') }} " method="POST">
{{ csrf_field() }}
<input type="hidden" name="id" value="{{ $rental->id }}">
<input type="hidden" name="title" value="{{ $rental->title }}">
{{-- <input type="hidden" name="pickupDate" value="{{ $rental->pickupDate }}">
<input type="hidden" name="returnDate" value="returnDate"> --}}
<div class="buttons">
<div class="back">
<button class="primary button" type="submit">Add to Cart</button>
</div>
</div>
</form>
</figcaption>
</figure>
</article>
#endforeach
Seems like you are looking for the right way to do something in Laravel, but there is no right way.
Given
#if(!empty($spec_sheet))
Download Spec Sheet
#endif
I would make two changes, 1) shouldn't $spec_sheet be $rental->spec_sheet? and 2) swap out the #if(!empty(...)) with #unless(empty()) as I feel that including a ! will make it harder to understand when you come back to this in a few weeks.
So I am suggesting you use this which should be just fine, since there's no right way to do this in Laravel.
#unless(empty($rental->spec_sheet))
Download Spec Sheet
#endunless
Your code above will not work if there is no PDF attached, as the variable $fileNameOfPdfToStore will not exist and a hard error will be thrown. But assuming you fix that issue and store an empty string for the file name or perhaps NULL instead of the file path, then you could create a new attribute in the Rental model that looks like this:
public function getHasSpecSheetAttribute() {
return $this->spec_sheet==null? false:true;
}
Then in your view you would do this:
#if($rental->hasSpecSheet)
Download Spec Sheet
#endif
In order to fix the PDF upload code, just put an else statement and put this inside of it:
$fileNameOfPdfToStore = null;
#if(strlen({$rental->spec_sheet) > 0))
Download Spec Sheet
#endif
use string length to determine if there was file name uploaded or not

checkbox values not being received in laravel controller

I have this bit of code in my form edit.blade.php :
#php
$imagepath="images/Service/".$services->name."/";
$images=glob($imagepath.'*.*');
#endphp
<div class="row">
#foreach($images as $image)
#php
$count++;
#endphp
<div class="col-md-5">
<img src="{{URL::asset($image)}}" style="height: 150px;object-fit: contain;">
</div>
<div class="col-md-1">
<input form="services" type="checkbox" name="deleteimagelink[]" value="{{($image)}}" >
</div>
#endforeach
</div>
This is for passing the path of those images meant to be deleted.
And I have this snippet in my controller:
print_r($request->input('deleteimagelink'));
$deletables=$request->input('deleteimagelink');
foreach ($deletables as $deletable)
{
print_r($deletable);
unlink($deletable);
}
I have this problem that nothing is being received in the $request->input('deleteimagelink') parameter.
Please guide me if I'm doing anything wrong.
If nothing seems weird, can you please guide me how to deal with these checkbox situations in laravel.
I consulted related answers from internet but nothing seems to work.
<form class="form-group" method="post" action="/destroy" enctype="multipart/form-data">
#csrf
<input type="checkbox" name="deleteimagelink[]" value="1" >
<input type="checkbox" name="deleteimagelink[]" value="2" >
<button class="btn btn-primary" type="submit">Actualizar</button
</form>
Controller
public function destroy(Request $request)
{
return $request;
}
{"_token":"BetJnyujXvJnpkkwDU31kYO7lVz5OqflMQDoCLQy","deleteimagelink":["1","2"]}
This Works for me!
I had included the code above outside the <form></form> tag in order to justify to my view. Interestingly, it didn't work even though that I had included form="services" as a parameter in my input field{services is the form name here}. I had worked something like this before and it had worked pretty good that time. I managed to get the <form></form> tags outside the whole of my form elements and it is working fine now.
Thank you everybody who tried to help.

how to view images that stored as array in laravel?

user upload multiple image and it stored in array form. how to display those images in laravel blade file?
when i tried i got this error.
htmlspecialchars() expects parameter 1 to be string, array given (View: C:\Users\user\laravel2\newfyp\resources\views\postqs\show.blade.php)
show blade :
<img src="/image/{{ $postqs['image'] }}"
style="width:150px; height:150px;"> </td>
model:
protected $casts = [
'image'=>'array', ];
protected $fillable = ['image'];
create blade
<div class="form-group">
<label class="control-label col-sm-2" >image test:
</label>
<form action="upload" id="upload" enctype="multipart/form-data">
<input type="file" name="image[]" id="image" multiple><br />
</form>
<div id="message"></div>
Try :
#foreach($postqs['image'] as $imagePath)
<img src="/image/{{ $imagePath }}"
style="width:150px; height:150px;">
#endforeach
</td>
protected $fillable = [''image'];
Is that a typo with the double quote?
If the images are in an array simply loop over the array and create an img for each.
Have you tried something like the following in your view file:
#foreach ($postqs['image'] as $image)
<img src="asset({{ $image }})" />
#endforeach
First of all you should correct this line:
protected $fillable = [''image']; // ['image'] and not [''image']
htmlspecialchars(): I always get this error when the variable is null.
A simple solution would be wrap your html with:
#if($yourVar)
#endif
You can also dump your variable to show how the structure is.
Good luck.

Categories