Weird Livewire + Turbolinks behavior - laravel

I'm building an admin panel in TALL (Laravel 7) + Turbolinks. One section only includes a Livewire component that shows a paginated table of Product elements and a search field (the only "strange" thing that I'm doing before this is injecting a Market model instance to the request in a middleware).
The problem arises when I go to /products route where is the livewire component included nothing works... The records of the first page are fine, but pagination links are dead and search field does nothing, no console errors, no livewire errors, it's like javascript is not working at all, and here's the strangest thing: if I reload the page, the Market data I loaded in middleware is added to the query string and everything starts working as intended.
Middleware:
public function handle($request, Closure $next) {
$market = Market::findOrFail(session('selected_market'));
$request->request->add(['market' => $market]);
return $next($request);
}
Livewire Component:
class ProductsTable extends Component{
use WithPagination;
public $search = '';
protected $queryString = [
'search' => ['except' => ''],
'page' => ['except' => 1],
];
public function render(){
$products = Product::where('market_id', request('market')->id)
->when($this->search !== '', function($query) {
$query->where('name', 'like', "%{$this->search}%");
$query->orWhere('brand', 'like', "%{$this->search}%");
})->paginate(15);
return view('livewire.products-table', ['products' => $products]);
}
}
Livewire Component View:
<input wire:model.debounce.500ms="search" type="search" name="search" id="search">
<table>
#forelse($products as $product)
<tr onclick="Turbolinks.visit('{{ route('product', $product->id) }}')">
<td>{{ $product->name }}</td>
...
</tr>
#empty
<tr><td>Nothing to show for {{ $search }}</td></tr>
#endforelse
</table>
{{ $products->links() }}
I'm really confused and tired with this, I have no clue what is going on and similar questions haven't been answered clearly.
Thanks

The solution was as simple as adding this to your scripts:
document.addEventListener("turbolinks:load", function(event) {
window.livewire.restart();
});

Related

Passing Results from 2 Queries in a Single Route in Laravel 5

I am trying to get posts from all users, plus tasks from only the current user. All passed into a single page with a single function and route. It returns an error page instead.
Controller
public function getDashboard()
{
$user = Auth::user();
$userId = $user->id;
$posts = Post::orderBy('created_at', 'desc')->get();
$tasks = Task::where('employee_id', $userId )->get();
return view('dashboard', compact('posts', 'tasks'));
}
Route
Route::get('/dashboard', [
'uses' => 'PostController#getDashboard',
'as' => 'dashboard',
])->middleware('auth');
Blade/View
<div>
#foreach($tasks as $task)
<p data-taskId="{{ $task->id }}">{{ $task->task_body }}</p>
#endforeach
</div>
Looks like possibly a syntax issue, as compact should work fine. Try this in your controller:
return view('dashboard', compact('posts', 'tasks'));
Then in your view, make sure to use the variables and not the class name, and as Karl Hill said, it's used within (), not {{}}:
#foreach($posts as $post)
{{$post->nameOrWhatever}}
#endforeach
#foreach($tasks as $task)
{{$task->nameOrWhatever}}
#endforeach

Missing required parameters for in a Update Form Laravel 5.2

I've been working on a webapp recently in laravel and i wanted to have a eddit function within tthe application. but im getting this error Missing required parameters for [Route: producten.update] [URI: producten/{producten}], and i dont know what i've done wrong.
This is the Routes im using:
Route::resource('producten', 'ProductenController', ['only' => ['index', 'store', 'update', 'delete', 'edit', 'destroy', 'create']]);
This is the controller function im using for showing the edit page and updating.
The Edit function
public function edit(Request $request, Product $product)
{
// $product = Product::FindorFail($id);
// Product is a table with all products, with sellprice and buy price
// fabriek = table that has a foreign key attached to the product table
return view('producten.edit', [
'model' => $product,
'fabrieks' => Fabriek::lists('Id')
]);
}
The Update Function:
public function update(Request $request, Product $product)
{
$product->update($request->all());
return redirect(Route('producten.index'));
}
and this is the view i use for it.
{{Form::model($model, ['method' => 'PATCH', 'action' => 'ProductenController#update', $model ]) }}
{{ Form::label('naam:')}}
{{ Form::text('naam') }} <br>
{{ Form::label('inkoopPrijs:')}}
{{ Form::text('inkoopPrijs') }} <br>
{{ Form::label('verkoopPrijs:') }}
{{ Form::text('verkoopPrijs') }} <br>
{{Form::label('Fabrieken', 'Fabrieken Id:') }}
{{ Form::select('Fabrieken_Id', $fabrieks)}} <br>
{{ Form::submit('edit')}}
{{ Form::close() }}
if there is anything else that i need to add to the question just let me know and i'll add it
Missing thing is the id you are not getting id there in your edit function
your edit function should as i am assuming that you are just showing the form from this method where user can edit
public function edit($id)
{
$product = Product::FindorFail($id);
//Product is a table with all products, with sellprice and buy price
//fabriek = table that has a foreign key attached to the product table
return view('producten.edit', [
'model' => $product,
'fabrieks' => Fabriek::lists('Id')
]);
}
your update method should seem like this
public function update(Request $request, $id)
{
$product->update($request->all());
return redirect(Route('producten.index'));
}
your routes should like this no need for only
Route::resource('/producten', 'productionController');
edit route will be as
<a href="{{ route('production.edit', $model->id) }}">
Try this hope it will help

laravel 5.2 pagination pretty url

I am Using Laravel 5.2
Is There a Way To Get a Pagination Pretty URL in Laravel 5.2?
http://localhost:8000/backend/admin_user?page=10&page=1
And What I Would Like To Get,How generate Link Pretty Url:
http://localhost:8000/backend/admin_user/10/1
So you can try something like that:
Route::get('test/{page}', function ($page) {
return User::paginate(2, ['*'], 'page', $page);
});
You can achieve this with three simple steps.
Register the route:
Note the question mark, this makes the size and page values optional;
Route::get('backend/admin_user/{size?}/{page?}', ['uses' => 'BackendController#adminUser']);
Implement this function in your controller:
Note the default values, $size = 10, $page = 1. This makes sure that you don't get an error if you navigate to the url without the pagination.
<?php namespace App\Http\Controllers;
use App\Models\AdminUser;
use Illuminate\Pagination\LengthAwarePaginator;
class BackendController
{
public function adminUser($size = 10, $page = 1)
{
$collection = AdminUser::all();
$users = new LengthAwarePaginator($collection, $collection->count(), $size);
$users->resolveCurrentPage($page);
return view(backend.admin_user);
}
}
Use in your view like this:
<div class="container">
#foreach ($users as $user)
{{ $user->name }}
#endforeach
</div>
{{ $users->links() }}

Redirect back to same page (with variables) on form submit in Laravel 5

On my page events.index, I first display a list of events for the logged on user.
On my index page I have a form with option/select to let the user select and display the events of another user. When he submits that form, I would like my index function (controller) to use the $user_id value (from the form) and display the events.index page again, but for events of that selected user.
I'm not sure what would be the best approach:
Set a session variable to keep the user_id value? Not sure how to do that with a form.
Submit the form with a get method (and get an ugly ?user_id=1 URL)
Change my index route to accept the post method (although I already have that post/events route taken (by Route::post('events', 'EventsController#store'))
Not sure what would be a clean way to do this:
My route for events/index:
Route::get('events', [
'as' => 'event.index',
'uses' => 'EventsController#index'
]);
Events Controller
public function index()
{
// How to get the $user_id value from form?
if (empty($user_id))
{
$user_id = \Auth::user()->id;
}
$events = Event::where('events.user_id','=','$user_id');
$users = User::all();
return view('events.index')->with(['events' => $events])->with(['users' => $users]);
}
View for index
{!! Form::open(['route' => 'events.index', 'method' => 'get']) !!}
<select id="user_id" name="user_id">
#foreach($users as $user)
<option value="{{$user->id}}">{{$user->name}}</option>
#endforeach
</select>
{!! Form::submit('Show events for this user') !!}
{!! Form::close() !!}
#foreach($events as $event)
...
#endforeach
You can get the user_id from a Request object, you just need to inject it in the index method:
public function index(Request $request)
{
$user_id = $request->get('user_id') ?: Auth::id();
$events = Event::where('events.user_id','=','$user_id')->get();
$users = User::all();
return view('events.index')->with(['events' => $events])->with(['users' => $users]);
}

search form using laravel shows 'Call to a member function getNumCommentsStr() on a non-object'

i have made a search bar using laravel, but it did not succeed. it shows the error as said below. And it seems that something wrong with my post object. But i do not know where.
source code as follows, thanks for helping.
//the searchController for seach code
public function search(){
$keyword = Input::get('keyword');
if(empty($keyword)){
return Redirect::route('/');
//->with('message',array('type' => 'alert', 'content' => '不能为空'))
}
$posts = Post::where('content', 'like', '%'.$keyword.'%')->orderBy('created_at', 'desc')->paginate(10);
$tags = Tag::where('count','>','0')->orderBy('count','desc')->orderBy('updated_at', 'desc')->take(20)->get();
return Redirect::route('searchResults')->with('posts', $posts->toArray())->with('tags',$tags);
}
public function searchResults(){
return View::make('frontend.search.search',['posts' => Session::get('posts'),'tags' => Session::get('tags')]);
}
//search bar route
Route::get('/searchResults', array(
'uses' => 'SearchController#searchResults',
'as' => 'searchResults'
));
Route::post('/search', array(
'before' => 'csrf',
'uses' => 'SearchController#search',
'as' => 'search'
));
//search from
{{ Form::open(array('url'=>'/search','method' => 'post','class'=>''))}}
{{ Form::token()}}
<label for="docSearch">
<i class="fa fa-search"></i>
</label>
<div class="searchInput">
{{Form::text('keyword', '', array('class'=>'docsSearch', 'placeholder'=>'搜索论坛动态...'))}}
{{ Form::submit('提交',array('class'=>''))}}
{{Form::close()}}
//now i just wanna to get it like this:
#if(!$posts)
{{'<section class="oneQuestion">sorry,no content...</section>'}}
#else
#foreach($posts as $post)
<section class="oneQuestion">
<div class="askResult">
<!-- <i class="fa fa-question notSolved"></i>
<i class="fa fa-check solved" style="display:none;"></i> -->
#if($post->getNumCommentsStr() == 0)
<a href="{{URL::route('viewPost', array('id' => $post->id))}}#reviews" class="notSolved"><span class="post_comment_Num">{{$post->getNumCommentsStr()}}</span>
<span> 回答</span>
</a>
#else
<a href="{{URL::route('viewPost', array('id' => $post->id))}}#reviews" class="solved"><span class="post_comment_Num">{{$post->getNumCommentsStr()}}</span>
<span> 回答</span>
</a>
#endif
</div><!--
--><div class="titlePart">
<span>
{{$post->user->username}}
{{$post->created_at->diffForHumans()}}
</span>
<a href="{{ URL::route('viewPost', $post->id)}}">
{{-- {{ substr($post->content,0,200) }}... --}}
{{$post->title}}
</a>
<div class="tagWrapper">
#foreach ($post->tags as $tag)
<span class="askTag" title="">{{$tag->name}} </span>
#endforeach
</div>
</div>
</section>
#endforeach
#endif
<div class="forumLink">
{{$posts->links()}}
</div>
//it showed me an error:
**Call to a member function getNumCommentsStr() on a non-object**
and my getNumCommentsStr like:
public function getNumCommentsStr()
{
$num = $this->reviews()->count();
// if($num == 1){
// return "1";
// }
return $num;
}
code seems a lot but i wanna to make it clear so you can find any errors. Thanks again.
Edit 2
Thanks for NightMICU's suggest and I change
Redirect::route('searchResults')->with('posts', $posts->toArray())->with('tags',$tags);
to the following:
Redirect::route('searchResults')->with('posts')->with('tags',$tags);
THE result is without any alert any more, it just shows: sorry, no content...
And did not show any search result, any problem? Thanks
EDIT TWO
//delete the searchResult method, all in one search method so that i can return the view in right in the search method.
public function search(){
$keyword = Input::get('keyword');
if(empty($keyword)){
return Redirect::route('developer');
//->with('message',array('type' => 'alert', 'content' => '不能为空'))
}
$posts = Post::where('content', 'like', '%'.$keyword.'%')->orderBy('created_at', 'desc')->paginate(10);
$tags = Tag::where('count','>','0')->orderBy('count','desc')->orderBy('updated_at', 'desc')->take(20)->get();
return View::make('frontend.search.search',['posts' => $posts,'tags' => $tags]);
}
EDIT 3
there are two questions exsiting here.
ONE is that when i change to that ,it can output the result but all the result the database has. Not the keyword results.
Two is that when there are extra page, once i open the link http://localhost/html5lav/public/search?page=2, it just show an error:
No query results for model [Post].
The initial issue most likely has to do with the unusual way you are displaying the search results; by passing the Eloquent collections via session to another method, only to display the View. You were also converting the Post Eloquent collection to a regular array with ->toArray(), pagination requires a collection rather than an array.
The solution for that part:
public function search(){
$keyword = Input::get('keyword');
if(empty($keyword)){
return Redirect::route('/');
//->with('message',array('type' => 'alert', 'content' => '不能为空'))
}
$posts = Post::where('content', 'like', '%'.$keyword.'%')->orderBy('created_at', 'desc')->paginate(10);
$tags = Tag::where('count','>','0')->orderBy('count','desc')->orderBy('updated_at', 'desc')->take(20)->get();
return View::make('frontend.search.search')->with('posts', $posts)->with('tags', $tags);
}
After taking care of the initial issue, you reported that the pagination links are not working as expected - you click on Page 2 and do not have any Post results. If the route for the page where the user inputs a search term is also /search, there is a conflict. Instead, change the route that the search form posts to, perhaps /searchResults (which then loads the results using the search method). You may also want to consider using a GET rather than POST request, allowing users to bookmark their search results or share a link.
Regarding the issue of displaying all of the entries from the posts table, you need to review MySQL raw queries in Laravel. Swing by the documentation and look them up.

Resources