I am working on a laravel project, where I get data from an API then I want to display it on pages. I want the return to be spread out across 4 pages, each page with 10 results each. What I have so far, seems like it should work, but I am missing one piece, so any advice and help would be appreciated. So this is how it is suppose to work with code:
1) The users types in a book title in a search box.
<form method=POST action='/search'>
#csrf
<input type="text" name="search_term"/>
<input type="submit" value="Search"/>
</form>
2) there input is then sent to my controller, which queries the google books api.
class search extends Controller {
public function search(){
$current_page = LengthAwarePaginator::resolveCurrentPage();
echo $current_page;
$term = request('search_term');
$term = str_replace(' ', '_', $term);
$client = new \Google_Client();
$service = new \Google_Service_Books($client);
$params = array('maxResults'=>40);
$results = $service->volumes->listVolumes($term,$params);
$book_collection = collect($results);
$current_book_page = $book_collection->slice(($current_page-1)*10,10)->all();
$books_to_show = new LengthAwarePaginator($current_book_page,count($book_collection),10,$current_page);
return view('library.search')->with(compact('books_to_show'));
}
}
3) the results are then displayed on my blade
#extends('home')
#section('content')
#foreach($books_to_show as $entries)
<div class="row">
<div class="col-sm-auto">
<img class="w-50 img-thumbnail" src={{$entries['volumeInfo']['imageLinks']['smallThumbnail']}}/>
</div>
<div class="col-sm">
{{$entries['volumeInfo']['title']}}<br/>
#if($entries['volumeInfo']['authors']!=null)
by:
#foreach($entries['volumeInfo']['authors'] as $authors)
{{$authors}}
#endforeach
#endif
</div>
</div>
#endforeach
{{$books_to_show->links()}}
#endsection
This all works fine and as expected. I get 10 results on the view, and then I have a bar at the bottom which give shows me 4 different pages to choose from.
When I first type in a search term such as "William Shakespeare" My page url is:
localhost:8000/search
But, when I click on any of the pages my url becomes:
http://localhost:8000/?page=2
I understand that the ?page=* is how the pagination determines which page you are viewing, and that should be sent back to the controller. But, I am missing something on sending it back to the controller I think.
Still kind of fresh to this, so any advice is more then greatly appreciated.
LengthAwarePaginator accepts a 5th parameter in its constructor: an array of options.
the path option
$books_to_show = new LengthAwarePaginator($current_book_page, count($book_collection), 10, $current_page, [
// This will fix the path of the pagination links
'path' => LengthAwarePaginator::resolveCurrentPath()
]);
By the way, on a totally different matter, Laravel makes your life easier by slicing the collection for you, check it out:
$current_book_page = $book_collection->forPage($current_page, 10);
Hope it helps :)
Related
in my show method in laravel i have a form that i want to submit and show the result on the same page so here is my show method first of all :
public function show(Property $property)
{
$property = Property::with('propertycalendars')->where('id', $property->id)->first();
foreach ($property->propertycalendars as $prop) {
$end_reserve = $prop->reserve_end;
}
// HERE NEW RELATION
$pdate = Property::with('dates')->get();
return view('users.properties.show', compact('property','pdate','end_reserve'));
}
and in the view of my show which for example is the url of a uniq property like below just as an example :
http://localhost:8000/properties/1
now i have a form to submit to search the Date table and bring me the dates so here is what i have wrote for the search function :
public function search (Request $request,$property_id){
//Send an empty variable to the view, unless the if logic below changes, then it'll send a proper variable to the view.
$results = null;
//Runs only if the search has something in it.
if (!empty($request->property_id)) {
$start_date = $request->start_date;
$search_date = Date::all()->where('date',$start_date);
}
return view('admin.properties.show')->with('search_date', $search_date);
}
and
thats my route :
Route::get('/properties/{{property_id}}','PropertyController#search');
and finally my form to submit the search :
<form action="/properties/search" method="get">
{{csrf_field()}}
<div class="row">
<div class="col-lg-5">
<input type="hidden" value="{{$property->id}}" name="property_id">
<input name="start_date" class="form-control m-input start_date" autocomplete="off"> </div>
<div class="col-lg-5">
<input name="finish_date" class="form-control m-input start_date" autocomplete="off"> </div>
<div class="col-lg-2">
<input type="submit" value="seach" class="btn btn-primary btn-block" autocomplete="off">
</div>
</div>
</form>
but now when i submit the form it returns a 404 not found with a link like below :
http://localhost:8000/properties/search?_token=R8ncSBjeZANMHlWMcbC6o5mYJZfwWgdfTwuviFo1&property_id=1&start_date=1398%2F1%2F12&title=
In your controller, change to the following:
public function search (Request $request){
//Send an empty variable to the view, unless the if logic below changes, then it'll send a proper variable to the view.
$results = null;
//Runs only if the search has something in it.
if (!empty($request->title)) {
$results = Property::all()->where('some search here')->get();
}
return view('admin.article.index')->with('results', $results);
}
This will send any (and all) results that your query finds to the view. Now in your view, you'll need to ensure there are actual results, or you'll get an error, so for example:
#if ($results)
//There are results, loop through them
#foeach($results as $item)
{{$item->title}}
#endforeach
#else
//There are no results, show the form maybe?
#endif
Without knowing your table structure, I can't give the exact way to loop through your results, but this should get you started.
Edit: Since OP's question nature changed a fair bit from the original question:
In order to achieve the new flow, you'd need to pass in a URL param in the route, and change it to be a get, since you're no longer posting it from a form:
Route::get('/properties/{search}','PropertyController#search');
This tells Laravel you've got something coming from a website.com/properties/xxxxx request - the xxxxx would contain the search key you'd then pass to your controller to lookup. The {search} portion in the route can be whatever name you want, just ensure the controller's second param matches it.
If you wanted to allow for a posting from your search form, you can (in addition) add the following to your routes:
Route::post('/properties','PropertyController#search');
Then in your controller, fetch whatever came from the form via the Request facade.
Then in your controller, you'd check if this is valid:
public function search (Request $request, $search){
//Send an empty variable to the view, unless the if logic below changes, then it'll send a proper variable to the view.
$results = null;
//Runs only if the second URL param has a value
if (!empty($search)) {
$results = Property::all()->where('some search here')->get();
}
return view('admin.article.index')->with('results', $results);
}
I'm confused or been to much in the sun, I have the following situation
when editing a product
http://app.dev/shops/1/products/2/edit
I added the /shops/1 in the URL because I need to know for what Shop I'm editing the Product.
Now in the Controller I need to know what Shop and Product we're talking about here.
I'm using the following hidden input field to send the product_id to the update Controller
<input type="hidden" name="product" value="{{ $product->id }}">
But how do I get the shop_id to the Update Controller. What's the best way to go about this?
Thank you!
route file
Route::get('/shops/{shopid}/products/{productid}' , 'testController#gettest');
In controller
Input::get('shops');
Input::get('products');
and also check this
Route::get('/', function(){
echo Input::get('shops');
echo Input::get('products');
});
laravel way
{{ Request::segment(3) }}
will give you the id and you can pass it either in hidden input or as you want
PHP way
$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$shop = explode('/', $actual_link);
$shop_id = $shop[1/2/3 or 4];
//depending in which position the shop id is coming, you can check it by printing $shop
So you have a route similar to this
Route::post('/shops/{shop_id}/products/{product_id}/edit' , 'TestController#edit');
And in your controller you can simply use. Now you have both ids and can do what you want.
public function edit($shop_id, $product_id) {
//do what you want
}
below is my route code
Route::any("rgMain/SystemManage/Account" , function()
{
$c1 = "rg.SystemManage.AccountManage.Account.Account_Factor";
$c2 = "rg.SystemManage.AccountManage.Account.Account_Result";
return View::make("rgMain",array(
'rgFactor' => $c1 ,
'rgContent' => $c2
));
this is my controller code:
return Redirect::to('rgMain/SystemManage/Account')->with('message2', $output);
when do something done in webpage Account , submit param to controller ,
after vaild , controller would return Redirect::to route ,and carry message2
back to Account , but i could'nt work
I am not sure this problem is or not about my structure
this my main struct , it could load different use webpage in here
<div>
<div>
</div>
<div>
#include('rg.rgNotice')
</div>
<div>
#include('rg.rgTitle')
</div>
<div>
#include('rg.rgMenu', ['rg_Menu' => 'default'])
</div>
<div>
#include($rgFactor, ['rg_Factor' => 'default'])
</div>
<div>
#include($rgContent, ['rg_Result' => 'default'])
</div>
in rgMain.blade.php , try use input.get('message2'); and $message2 , but
still couldn't work .
When using with() with a Redirect, it actually flashes the data to the session so rather than trying to pull it from the input, try Session::get('message2')
Please note that this data would only be available during this request.
Redirects using with flashes data to session
You are able to retrieve the data with:
{{ old('message2') }}
I'm having some trouble implementing pagination in Laravel 5. Though probably not what you would think.
I can get everything to work but can't understand how to get it to pull the correct information on the second page.
Here is what I have:
Routes:
Route::resource('find-a-wp-theme', 'searchController');
Controller:
public function store(){
$themes['themes'] = Fulls::where("tags", "like", "%".$_POST['theme']."%")->orwhere("tags", "like", "%".$_POST['free']."%")->orwhere("title", "like", "%".$_POST['free']."%")->paginate(12);
return view('find-a-wp-theme', $themes);
}
View:
#if($themes)
#foreach($themes as $theme)
{{$theme['title']}}<br />
<img style="width:250px;" src="{{$theme['image']}}"><br />
#endforeach
{!! $themes->render() !!}
#endif
Up till here everything works just fine. My problem is that when I click the paginating button it takes me to mypage?page=2 which actually takes me to the resource index() and I can't understand how to implement this correctly.
Any help would be much appreciated!
Look at append in the docs. http://laravel.com/docs/5.0/pagination
If your trying to pass variables in your URL you need to use appends().
<?php echo $users->appends(['sort' => 'votes'])->render(); ?>
I followed a tutorial on Tutsplus about creating an ecommerce website using Laravel. The problem I'm having right now is when trying to route to a subfolder. In the tutorial, the instructor included a feature where you can view products by ID. And this is how he did it:
// StoreController.php
public function getView($id) {
return View::make('store.view')->with('store', Store::find($id));
}
This piece of code seems to be passing an id from the stores table. I think when a product is clicked, that's when the id is passed
// Routes.php
Route::controller('store', 'StoreController');
Also some of the templates:
// store\index.blade.php
<h2>Stores</h2>
<hr>
<div id="stores row">
#foreach($stores as $store)
<div class="stores col-md-3">
<a href="/store/products/view/{{ $store->id }}">
{{ HTML::image($store->image, $store->title, array('class' => 'feature', 'width'=>'240', 'height' => '127')) }}
</a>
<h3>{{ $store->title }}</h3>
<p>{{ $store->description }}</p>
</div>
#endforeach
</div><!-- end product -->
So.. How it goes is when I click on a product, it leads me to domain:8000/store/view/6 where 6 is the id.
This works fine but what I want to know is how do I route through a subfolder? Let's say I want it to be like this: store/view/products/6 considering that I have a folder called products and my view.blade.php is inside that like this: store/products/view.
In my StoreController class, I tried changing this
public function getView($id) {
return View::make('store.view')->with('store', Store::find($id));
}
to this
public function getView($id) {
return View::make('store.product.view')->with('store', Store::find($id));
}
but it does not seem to work giving me nothing but a Controller Method Not Found Error.
First, the view name View::make('store.product.view') has nothing to do with the URL.
You have to change the route:
Route::controller('store/view', 'StoreController');
And then adjust the name of your method in the controller because it should be the same as the segment of the URL after store/view
public function getProducts($id) {
return View::make('store.product.view')->with('store', Store::find($id));
}
I strongly recommend you read the Laravel docs on the topic