Laravel: Looping through dynamic route parameter in blade template - php

I want to loop through named route with additional parameter, a series of IDs in this case, in the blade template. I have highlighted the line where I want to do this in the code with stars. My purpose is to access the next page when the 'next' button is clicked. The next page looks exactly like the page before, except for a different question card. At present, the page doesn't change on click of the button.
This is the defined route:
Route::get('/quiz/{id}', [QuestionController::class, 'show'])->name("question.show");
and this is the html blade template to generate the view.
`#foreach ($questions as $question)
<div class="col-12 col-md-6 my-2 offset-md-3">
<div class="card shadow p-3 mb-5 border bg-warning rounded border">
<h5 class="card-header"> {{ $question->category }} </h5>
<div class="card-body">
<h6 class="card-subtitle mb-2 text-muted">{{ $question->text }}</h6>
#foreach($question->options as $option)
<br>
<input type='radio' name="{{ $question->id }}" value="{{ $option->id }}">
{{ $option->text}} <br>
#endforeach
</div>
**<a href = "{{route('question.show',['id' => $question])}}" class="btn btn-light btn-sm offset-2 offset-md-10" role="button">
Next**
</a>
</div>
</div>
#endforeach`

You can do this by using an index with your foreach loop.
Change this: #foreach ($questions as $question)
to this: #foreach ($questions as $index=>$question)
Then in your anchor tag do something like this:
<a href="{{route('question.show',['id' => $questions[$index + 1]])}}"
class="btn btn-light btn-sm offset-2 offset-md-10" role="button">
Make sure to surround the button with an if statement to catch the last question.
#if( $index + 1 < count($questions) )
edit: missing bracket

Related

Is there any way to pass object as a parameter in laravel livewire?

I have an array of product and i am trying to pass a single item as a parameter for quick view, but I can't. anyone have any sollution? thanks in advance.
#foreach ($products as $product)
#php
$product = (object) $product;
#endphp
<div class="col-md-3 mb-4">
<div class="product-item product-item-border custom-product-item">
<a class="product-item-thumb" href="shop-single-product.html">
#if (count($product->related_images) > 0)
<img src="{{ $product->related_images[0]['image'] }}" width="233" height="245" alt="Image-HasTech">
#endif
</a>
<div class="product-item-action">
<button type="button" class="product-action-btn action-btn-wishlist" data-bs-toggle="modal" data-bs-target="#action-WishlistModal">
<i class="icon-heart"></i>
</button>
<button type="button" class="product-action-btn action-btn-compare" data-bs-toggle="modal" data-bs-target="#action-CompareModal">
<i class="icon-shuffle"></i>
</button>
<button type="button" wire:click="quickView({{ $product }})" class="product-action-btn action-btn-quick-view">
<i class="icon-magnifier"></i>
</button>
</div>
<div class="product-bottom">
<div class="product-item-info text-center pb-6">
<h5 class="product-item-title mb-2">{{ $product->product_name }}</h5>
{{-- <div class="product-item-price mb-0">{{ $product->default_price }}<span class="price-old">{{ $product->default_price }}</span></div> --}}
</div>
<div class="d-flex justify-content-between">
<div class="ms-4 product-item-price mb-4">{{ $product->default_price }}</div>
<button type="button" wire:click="addToCart({!! $product->id !!})" class="info-btn-cart me-4 mb-4"><i class="icon-handbag"></i></button>
</div>
</div>
</div>
</div>
#endforeach
<div class="col-12">
<div class="text-center">
<div wire:click="nextPage" type="button" class="btn btn-primary">Load more</div>
</div>
</div>
and in my controller I am trying to do something like this:
public function quickView($product)
{
$this->view_product = $product;
}
I tried to pass the object but I am getting error such:
htmlspecialchars() expects parameter 1 to be string, object given
The error happens because in blade {{ }} will automatically escape the output. And this function only escapes strings.
Instead what you can do is
wire:click="quickView( {{ $product->id }} )
And within your livewire component
public function quickView($product_id)
{
// I assume $products is collection
$this->view_product = $this->products->where('id', $product_id)->first();
}
EDIT:
If you do not want to add "extra query" inside quickView()
I suggest you change how $products collection is collected
$this->products = $existing_query->get()->keyBy('id');
This will resulting array list of object product.
After that within quickView() do the following
public function quickView($product_id)
{
$this->view_product = $this->products[$product_id];
}
Extra note: please do add some kind of check or validation in case product with selected id is not found
It may be a little too late but I got to solve something similar by type hinting the object class. From the docs
So maybe you can do something like this:
public function quickView(Product $product)
{
$this->view_product = $product;
}

expand / toggle div with display none from foreach with $ id

I have this:
#foreach($portfolios as $portfolio)
<div id="item-portfolio-expand{{$portfolio->id}}" class="item-portfolio-expand expand">
<div class="container">
<div class="row">
<div class="col-md-8">
col-md-8
</div>
<div class="col-md-4">
{{ __('Name')}}: {{ $portfolio->name }}
</div>
</div>
</div>
</div>
#endforeach
And this:
#foreach ($portfolios as $portfolio)
<div class="portfolio-item {{ $portfolio->tag }} " data-category="transition">
<img src="{{ $portfolio->image_show }}">
<a href="#item-portfolio-expand{{$portfolio->id}}" data-toggle="collapse" data-target="#item-portfolio-expand{{$portfolio->id}}" data-parent="#item-portfolio-expand{{$portfolio->id}}">
<div class="portfolio-item-overlay">
<p class="name-item-overlay">{{ $portfolio->name }}</p>
</div>
</a>
</div>
#endforeach
And when I press the in the first foreach, I want to toggle the second foreach at <div id = "item-portfolio-expand {{$ portfolio-> id}}" class = "item- portfolio-expand expand "> I just don't succeed at anything, I use bootstrap and jquery in the project. .item-portfolio-expand has display: none;
And at the same time when one is open and another is selected, to close the one already open and to appear the one selected with toggle.

Laravel 5.4 Displaying editing options in modal from view?

I have succesfully created an application within Laravel which allows users to edit posts for a item. The current method is by redirecting user to different page where they are able to make changes. However to increase the user expirence I was planning to add 'modal' within the page. Meaning that editing posts will happen within the same page. This method for me partly works. In a aspect that the last or the latest post is only editable post. If I click on any of the posts it makes me only make changes to the latest post. Any help, suggestions or examples are trully appreciated.
Below I have attached my show.blade.php which shows the item infromation and posts.
<ul class="list-group">
#foreach ($car->reviews as $review)
<li class="list-group-item">
<strong>
Created by: {{ $review->user->name}} {{ $review->created_at->diffForHumans() }}:
<br>
Updated by: {{ $review->user->name}} {{ $review->updated_at->diffForHumans() }}:
</strong>
<a href="/reviews/{{ $review->id }}/edit" data-toggle="modal" data-target="#myModal1" >{{ $review->reviewbody }}</a>
<a style="float:right;" href="/reviews/{{$review->id}}/delete">Delete</a>
#endforeach
The Modal
<div class="container">
<!-- Trigger the modal with a button -->
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal1">TEST</button>
<!-- Modal -->
<div class="modal fade" id="myModal1" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<div class="review-edit">
<div class="review-edit-block">
{{ $review->reviewbody }}
<form action="/reviews/{{$review->id}}" method="POST">
{{ csrf_field() }}
{{ method_field('patch') }}
<div class="form-group">
<textarea style="position:relative;left:10%;width:375px;"name="reviewbody" class="form-control">{{ $review->reviewbody }}</textarea>
</div>
<div>
<button type="submit" class="btn btn-primary">Update Review</button>
</form>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
If the modal is included after the foreach loop, the variable $review will still be set to the value of the last item in the array.
An option is to use Javascript to handle the clicked link, set the specific data into the modal fields and then make the modal visible.
Example

Make a function containing blade syntax

I have this blade in my view. Right now, I have 6 blocks of them in my view because I'm not sure how to refactor it.
<div class="row filemanager">
<div class="col-sm-12">
#foreach ($devices as $device)
#if( $device->vlan_id == 100 AND $device->device_activity == 'ACTIVE' )
<div class="col-xs-6 col-sm-4 col-md-2 text-center">
<div class="thmb">
<div class="btn-group fm-group" style="display: none;">
<button type="button" class="btn btn-default dropdown-toggle fm-toggle" data-toggle="dropdown">
<span class="caret"></span>
</button>
<ul class="dropdown-menu fm-menu" role="menu">
<li id="device-menu">
<a class="changeDeviceNameBtn" href="#"><i class="fa fa-pencil"></i> Change Device Name </a>
</li>
</ul>
</div>
<div class="thmb-prev">
<a href="/{{$cpe_mac}}/device/{{$device->device_mac}}">
#if(isset($device->device_name))
{{-- Show base on device name --}}
<img src="/images/photos/devices/{{img($device->device_name)}}.jpg" class="draggable img-responsive" alt="">
#else
{{-- No Device Name Set --}}
#if($device->hostname != '')
{{-- Show base on hostname --}}
<img src="/images/photos/devices/{{img($device->hostname)}}.jpg" class="draggable img-responsive" alt="">
#else
{{-- Show default --}}
<img src="/images/photos/devices/no-img.jpg" class="draggable img-responsive" alt="">
#endif
#endif
</a>
</div>
<h5 class="fm-title device_name">
<a href="/{{$cpe_mac}}/device/{{$device->device_mac}}">
#if($device->hostname == '')
No Devicename
#else
{{ $device->hostname}}
#endif
</a>
</h5>
<h5 class="text-muted device_ip">{{$device->ip_address}}</h5>
<h5 class="text-muted device_mac">{{$device->device_mac}}</h5>
<?php
$status = ucfirst(strtolower($device->device_activity));
if ($status == 'Active'){
$color = '#1CAF9A';
}else{
$color = '#D9534F';
}
?>
<h5>{{ $status }}
<i class="fa fa-circle" style="color:{{$color}}; margin-left: 7px;"></i>
</h5>
</div>
</div>
#endif
#endforeach
</div>
</div>
I want to make a function containing that blade, and only replace my
$device->vlan_id, and my $device->device_activity.
Example,
public static deviceRow(100,ACTIVE){
... my blade ...
}
Now, I just that function 6 times, rather than duplicate that block of code 6 times.
Is it even possible ?
Any hints / suggestions on this will be much appreciated !
You can make a partial with your blade and send a variable as a parameter:
In your parent view do something like this:
#foreach($somelist as $item)
#include('view.partial', ['name' => $item->name])
#endforeach
And in a file called partial.blade.php, do something like this:
{{ $device->$name }}
It's the main idea. Tell me if it helps...
You could create a new view and send some parameters with it while including:
#include('my.view', ['device' => $myDevice, 'activity' => 'ACTIVE'])
The keys of the array will be available as variables in your view.
The variable $myDevice would be available as $device in the view my.view

How to cut the content in laravel5?

I need to cut the characters that show description with the same quantity of letter in all foreach.
Could anyone helps me?
#foreach ($subastas as $subasta)
#if(($subasta->data_inici <= $data)&&($subasta->data_final>$data))
<a href="item/{{$subasta->id}}"><div class="col-sm-4">
<div class="product-image-wrapper">
<div class="single-products">
<div class="productinfo text-center">
<div class="nombre">{{$subasta->nombre}}</div>
#foreach ($subasta->images as $word => $meaning)
#if($word==0)
<img src="{{ asset($meaning->ruta) }}" style="width="242px" height="164px""/>
#endif
#endforeach
<h2><span class="clock" data-countdown="{{ $subasta->data_final}}"></span></h2>
<p>{{$subasta->descripcion}}</p>
<p>{{$subasta->cant_actual}}</p>
<a class="pujar btn btn-warning" id="{{$subasta->id}}">Pujar</a>
</div>
</div>
</div>
</div></a>
#endif
#endforeach
I think and image is better than explain .
Do you mean you want to limit the number of characters in a string?
This can be done in laravel by a string helper:
$value = str_limit('The PHP framework for web artisans.', 7);
So in your example:
<p>{{ str_limit($subasta->descripcion, 20) }}</p>
When whoever inputs the description of the product, can you not use max-length within the HTML element to set the limit prior to being saved?
<input type="text" maxlength="250" />

Categories