im trying to implement a view like sphinx documentation where you can click on next and previous to navigate between pages. not sure if im using the custom paginator on array right, i cant get page navigation links to display on a view page. this is the code:
public function paginate($array, $perPage, $pageStart=1) {
$offset = ($pageStart * $perPage) - $perPage;
return new Paginator(array_slice($array, $offset, $perPage, true), $perPage, $pageStart);
}
view()->composer('layouts.book', function($view)
{
//some other code
$pages = [];
foreach($book->textsection_pages as $textsection) {
$pages[] = $textsection->alias;
}
foreach($book->task_pages as $task) {
$pages[] = $task->alias;
}
foreach($book->tutor_pages as $tutor) {
$pages[] = $tutor->alias;
}
foreach($book->eval_pages as $eval) {
$pages[] = $eval->alias;
}
$chapters = $book->chapters()->orderBy('weight', 'asc')->get();
$paginated = $this->paginate($pages, 1);
$view->with(['chapters' => $chapters, 'book' => $book, 'paginated' => $paginated]);
});
and in the view i called {!! $paginated->render() !!}, but no navigation link was displayed.
Here is how I handle custom Pagination in my application (Laravel 5.1). I create a partial view resources/views/partials/pagination.blade.php
#if ($paginator->lastPage() > 1)
<ul id="pagination">
<li>
#if ($paginator->currentPage() > 1)
<a class="prev" href="{{ $paginator->url($paginator->currentPage()-1) }}">Previous</a>
#else
<span class="disabled">Previous</span>
#endif
</li>
<li>
#if ($paginator->currentPage() !== $paginator->lastPage())
<a class="next" href="{{ $paginator->url($paginator->currentPage()+1) }}" >Next</a>
#else
<span class="disabled">Next</span>
#endif
</li>
</ul>
#endif
In my controller, I pass the usual $model->paginate(10) method. Then finally in my view where I want to use the Paginator, resources/views/list.blade.php I do this:
#foreach ($objects as $object)
// Here we list the object properties
#endforeach
#include("partials.pagination", ['paginator' => $objects])
Related
public function seguimientos()
{
// $tracks = Tracking::with(array('order' => function($query)
// {
// $query->where('user_id',Auth::user()->id );
//
// }))->get();
if(!Auth::user()) return abort(404);
if(!Auth::user()->type == 'admin' || !Auth::user()->type == 'empresa') return abort(404);
// $trackings = Tracking::all();
$trackings = Tracking::with('order')->get()->paginate(15);
$myCompany = Auth::user()->company;
$statuses = ['Pago exitoso', 'Espera de envio','Pedido en Camino','Pedido Entregado'];
return view('store.order.admin.seguimiento')->with(['trackings'=>$trackings,'statuses'=>$statuses,'myCompany'=>$myCompany]);
}
I try to pag, but I can't get it to work
blade.php
<div style="margin-top: -44px;" class="page">
<ul class="list-group">
#foreach($trackings as $tracking)
#if($tracking->order->user->company == $myCompany )
<li class="list-group-item"> <b>Orden N°:</b> {{ $tracking->order->id }} <b>Detalles</b></li>
</ul>
#endif
#endforeach
{{ $trackings->$links() }}
<hr>
</div>
error: Method Illuminate\Database\Eloquent\Collection::paginate does not exist.
in: $trackings = Tracking::with('order')->get()->paginate(15);
help pls
You can't use paginate after get so you want to change your code like below.
$trackings = Tracking::with('order')->paginate(15);
I have model Category with relation products:
public function products()
{
return $this->hasMany(Product::class);
}
In MainController I have code:
$products = Category::with('products')->whereNull('parent_id')->paginate(15);
Method paginate only paginate categories, but How I can paginate products?
It's not a good idea to use pagination inside another pagination, but if you want to do this, you should create manual pagination for products of each category:
use Illuminate\Pagination\LengthAwarePaginator as Paginator;
use Illuminate\Http\Request;
$categories = Category::with('products')->whereNull('parent_id')->paginate(15);
foreach ($categories as $category) {
$count = $category->products->count(); // total count of products in this category
$limit = 10; // count of products per page in child pagination
$page = $request->input('category'.$category->id.'page', 1); // current page of this category's pagination
$offset = ($page * $limit) - $limit; // offset for array_slice()
$itemsForCurrentPage = array_slice($category->products->toArray(), $offset, $limit, true);
$paginator = new Paginator($itemsForCurrentPage, $count, $limit, $page, [
'path' => $request->url(),
'query' => $request->query(),
]);
$paginator->setPageName('category'.$category->id.'page');
$category->paginator = $paginator;
}
return view('categories.index', ['categories' => $categories]);
And then in your categories\index.blade.php:
<ul>
#foreach ($categories as $category)
<li>
<h3>{{ $category->title }}</h3>
#if ($category->paginator)
<ul>
#foreach ($category->paginator->items() as $product)
<li>{{ $product['title'] }}</li>
#endforeach
</ul>
{{ $category->paginator->links() }}
#endif
</li>
#endforeach
</ul>
{{ $categories->links() }}
I hope this helps, but I say it again, it's not a good idea to use pagination inside another pagination.
I'm trying to learn Laravel while writing some common features. Now what I'm trying to make is when I click on main category link to open new page and display all sub-categories assigned to this category. Sounds pretty simple but I can't display them.
This is what I have in my Category Model
public function parent()
{
return $this->belongsTo('App\Category', 'parent_id');
}
public function children()
{
return $this->hasMany('App\Category', 'parent_id');
}
And in controller
public function categoryListing( $category_id )
{
$categories = Category::with('children')->get();
$category = Category::find($category_id);
if($category->parent_id == 0) {
$ids = Category::select('id')->where('parent_id', '!=',0)->get();
$array = array();
foreach ($ids as $id) {
$array[] = (int) $id->id;
}
} else {
$items = Item::where('category_id' ,$category_id)->paginate(5);
}
return view('category_list', compact('categories','items'));
}
The idea here is to display Main Category and all sub-categories (childs) of this main category.
And this is the loop on the page
#foreach($categories as $category)
<a href="{!!route('list',array($category->id))!!}">
<span><strong>{!!$category->title!!}</strong> ({!! $category->itemCount!!})</span>
</a>
<ul class="list-group">
#foreach($category as $subcategory)
{!!$subcategory->title!!}
<span class="badge badge-primary badge-pill">{!! $subcategory->itemCount !!}</span>
</li>
#endforeach
</ul>
#endforeach
Current error is
Trying to get property of non-object
on the inside foreach.
Just try this is 'cleaner'.. if it works, start adding your links and other content so you will know what does not work.
#foreach($categories as $category)
<span><strong>{!!$category->title!!}</strong></span>
<ul class="list-group">
#foreach($category as $subcategory)
<li>{!!$subcategory->title!!}</li>
#endforeach
</ul>
#endforeach
Make sure the variables you try to print exist in each object.
You can try to dd($categories); in your controller before the return view('category_list', compact('categories','items')); statement to see whats inside $categories
I am fairly new to laravel (L5 specifically) and I am making my own version of a todo app rather than following one of the tutorials out there. I've learned quite a bit so far but the way I have this piece of code currently laid out in my blade template makes me think their might be a simpler way of doing this.
My TodosController#index fn is
public function index()
{
$todos = Todo::get();
return view('todos', compact('todos'));
}
App\Todo extends an Eloquent model which makes data handling very easy!
My route is:
Route::bind('todos', function($slug)
{
return App\Todo::whereSlug($slug)->first();
});
So my page simply displays an unorded list of "todos". I want to have two separate lists. One that is for completed todos and one for incomplete. My blade template looks like this so far and looks a bit messy. Also I am looping over the results twice which is where I think I can improve on.
<h3>Incomplete</h3>
<ul>
#foreach ($todos as $todo)
#if ($todo->completed == 'No')
<li>
{{ $todo->title }}
</li>
#endif
#endforeach
</ul>
<h3>Complete</h3>
<ul>
#foreach ($todos as $todo)
#if ($todo->completed == 'Yes')
<li>
{{ $todo->title }}
</li>
#endif
#endforeach
</ul>
Any suggestions to simplify that blade template?
DRY your code out. You could streamline it by moving the actual item mark-up to a partial template since it’s repeated in both the complete and incomplete lists:
<h3>Incomplete</h3>
<ul>
#foreach ($todos as $todo)
#if ($todo->completed == 'No')
#include('partials.items.todo')
#endif
#endforeach
</ul>
<h3>Complete</h3>
<ul>
#foreach ($todos as $todo)
#if ($todo->completed == 'Yes')
#include('partials.items.todo')
#endif
#endforeach
</ul>
And partials.items.todo would look like this:
<li>
{{ $todo->title }}
</li>
I would also re-factor your loops. Instead of looping over the same list twice, you could split them in your controller:
public function index()
{
$todos = Todo::where('user_id', '=', Auth::id())->get();
$complete = $todos->filter(function ($item) {
return $item->completed = 'Yes';
});
$incomplete = $todos->filter(function ($item) {
return $item->completed = 'No';
});
return view('todos', compact('complete', 'incomplete'));
}
Looking at your Todo model, I’d also make your completed column in the database a boolean field instead of a column containing “Yes” or “No” strings. You could then cast that column value to a proper boolean (since MySQL doesn’t have a native boolean field type):
class Todo extends Model
{
protected $casts = [
'completed' => 'boolean',
];
public function isComplete()
{
return $this->completed;
}
}
And then re-factor your controller action to use this instead:
public function index()
{
$todos = Todo::where('user_id', '=', Auth::id())->get();
$complete = $todos->filter(function ($item) {
return $item->isComplete() === true;
});
$incomplete = $todos->filter(function ($item) {
return $item->isComplete() === false;
});
return view('todos', compact('complete', 'incomplete'));
}
You could even move those collection filters to a custom TodoCollection class:
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
class TodoCollection extends EloquentCollection
{
public function complete()
{
return $this->filter(function ($item) {
return $item->isComplete() === true;
});
}
public function incomplete()
{
return $this->filter(function ($item) {
return $item->isComplete() === false;
});
}
}
Sorry for the lengthy reply, but should give you food for though on how to re-factor your code.
Only a bit simplified but...
You can try in your controller:
public function index()
{
$completed = Todo::where('completed','Yes')->get();
$incompleted = Todo::where('completed','No')->get();
return view('todos', compact('completed', 'incompleted'));
}
in Your template:
<h3>Incomplete</h3>
<ul>
#foreach ($incompleted as $todo)
<li>
{{ $todo->title }}
</li>
#endforeach
</ul>
<h3>Complete</h3>
<ul>
#foreach ($completed as $todo)
<li>
{{ $todo->title }}
</li>
#endforeach
</ul>
Another approach using a subtemplate like this:
//_list_todos.blade.php
#foreach ($todos as $todo)
<li>
{{ $todo->title }}
</li>
#endforeach
And your main template like this:
<h3>Incomplete</h3>
<ul>
#include('_list_todos',['todos'=>$incompleted] )
</ul>
<h3>Complete</h3>
<ul>
#include('_list_todos',['todos'=>$completed] )
</ul>
The advantege to use a subtemplate like the last one is you can reuse the code, and simplify your main templates.
I am new to laravel blade and I want to have an automatic active navigation bar,
so I have this code
<li>{{ HTML::clever_link("index", 'Home' ) }}</li>
<li><a class="glow" href='breeder'>Breeder's Profile</a></li>
<li><a class="glow" href='gallery'>Gallery</a></li>
<li><a class="glow" href='contact'>Contact Us</a></li>
I used the clever link as I research to do what i want, but it remove the link class "glow" now I want to add the glow class to the li with the clever link, I tried this
<li>{{ HTML::clever_link("index", 'Home', class="glow" ) }}</li>
but it just gives me error. Thanks
You can simply add an argument to your HTML Macro: (Obviously I don't know how your macro looks like so this is just an example)
HTML::macro('clever_link', function($link, $label, $class = ''){
return ''.$label.'';
});
Usage:
{{ HTML::clever_link("index", 'Home', 'glow') }}
Or something a bit more flexible:
HTML::macro('clever_link', function($link, $label, $attributes = array()){
return '<a href="'.$link.'" '.HTML::attributes($attributes).'>'.$label.'</a>';
});
Usage:
{{ HTML::clever_link("index", 'Home', array('class' => 'glow')) }}
(The HTML::attributes() method allows you to convert an array into an HTML attributes string)
// for navigation menu highlight
HTML::macro('clever_link', function($route, $text, $icon) {
if( Request::path() == $route ) {
$active = "class = 'active'";
}
else {
$active = '';
}
return "<a href = '{url($route)}' $active> <i class = '{$icon}'></i>{$text}</a>";
});
</pre>
Usage:
Make your menu as:
{{ HTML::clever_link("/", 'Home', 'icon-home-2') }}
{{ HTML::clever_link("/aboutus", 'About Us', 'icon-dollor') }}
in your menu's link
OR use
https://github.com/pyaesone17/active-state