Ad

Custom Pagination In OctoberCMS

- 1 answer

I have a code to do query from form:

Painting::where('type',input("type"))->where('material',input("material"))->whereHas('artist', function($q)
{
     $q->where('artist_slug', '=', $this->param('slug'));
})->paginate(15);

How can I do custom pagination with page numbers list? Or maybe dinamicaly loading

Ad

Answer

Check out the RainLab Blog Plugin it has a good example, also see here .

But here is a more complete example if you want to add URL friendly paginations paintings/2 where 2 is the page number and/or handle URL parameters paintings/2?type=something&material=something

In your Painting Model add a scope for listing paintings on the front-end :

public function scopeListPaintings($query, $options)
    {
        extract(array_merge([
            'page'               =>  1,
            'perPage'            =>  30,
            'material'           =>  null,
            'type'               =>  null,
            'artistSlug'         =>  null,
        ], $options));


        if( !empty($artistSlug) ){
            $query->whereHas('artist', function($q)
            {
                $q->where('artist_slug', $artistSlug );
            });
        }

        if( !empty($material) ){
            $query->where( 'material' , $material)
        }

        if( !empty($type) ){
            $query->where( 'type' , $type)
        }


        return $query->paginate( $perPage, $page );

    }

Then in your Painting Component Define the properties and call the previous scope ;

    public $paintings ;

    public $pageNumber;

    public $perPage; 

    public $urlParams;

    public function defineProperties()
    {
        return [
            'pageNumber' => [
                'title'       => 'Page #',
                'description' => 'Paintings Page #',
                'type'        => 'string',
                'default'     => '{{ :page }}',
            ],
            'perPage' => [
                'title'       => 'Paintings per page',
                'type'        => 'string',
                'default'     => '30',
            ]

            .. ect make sure to add it to your page markup
        ];

    }

    private function propertyOrParam($name, $default = null)
    {
        $value = $this->property($name, $default);
        if (substr($value, 0, 1) == ':')
            return $this->param($value, $default);

        return $value;
    }

    public function getPaintings()
    {
        /** Pagination */
        $this->pageNumber    = $this->propertyOrParam('pageNumber') ;
        $this->perPage       = $this->propertyOrParam('perPage'); 

        /** Url Params if exist */ 
        $params = Request::query()
        $this->page['urlParams']   =  $this->urlParams  =  !empty( $params ) ? http_build_query( $params ) : null ;

        return (new Painting)->ListPaintings([
                'page'          => $this->pageNumber, 
                'perPage'       => $this->perPage,
                'type'          => input('type'),
                'material'      => input('material'),
                'artistSlug'    => $this->propertyOrParam('slug')
            ]);
    }

    public function onRun()
    {

        $this->page['paintings'] = $this->paintings   = $this->getPaintings() ;

        // Redirect to Last page if page # not found in request
        if ($this->pageNumber >  $this->paintings->lastPage() && $this->pageNumber > 1){
            return Redirect::to($this->currentPageUrl([ $this->paramName('pageNumber') =>  $this->paintings->lastPage().$this->urlParams ]));
        }

    }

Then your can create a global partial in your theme to handle paginations - You can reuse it all over your site - add the following snippet ( Borrowed from the Forum Plugin ) ;

Pagination.htm

    {% set paginationEnabled =
    records.currentPage > 1 or
    records.lastPage > 1 or
    records.lastPage > records.currentPage
    %}

    {% if paginationEnabled %}
    {# How many pages to display around the current page #}
    {% set n = 2 %}

    {% set currentPageZeroBased = records.currentPage-1 %}

    {% set pageLinks = [] %}
    {% set pageSet = [] %}

    {% set startOffset = max(currentPageZeroBased - n, 0) %}
    {% if (startOffset + 2*n+1) > (records.lastPage-1) %}
    {% set startOffset = max(records.lastPage - 2*n - 1, 0) %}
    {% endif %}

    {% for page in 1..records.lastPage %}
    {% set pageLinks = pageLinks|merge([page]) %}
    {% endfor %}

    {% set activeBlock = pageLinks|slice(startOffset, 2*n + 1) %}

    {% if startOffset > 0 %}
    {% set pageSet = pageSet|merge([1]) %}

    {% if startOffset > 1 %}
    {% set pageSet = pageSet|merge(['...']) %}
    {% endif %}
    {% endif %}

    {% set pageSet = pageSet|merge(activeBlock) %}

    {% set diffToEnd = (records.lastPage-1) - (startOffset + 2*n+1) + 1 %}

    {% if diffToEnd > 0 %}
    {% if diffToEnd > 1 %}
    {% set pageSet = pageSet|merge(['...']) %}
    {% endif %}

    {% set pageSet = pageSet|merge([records.lastPage]) %}
    {% endif %}


    <div>
        <div>
           <div>

               <div>
                   <span>Records&nbsp;&nbsp;<b>{{records.firstItem|trim}}&nbsp;-&nbsp;{{records.lastItem|trim}}</b>&nbsp;Of&nbsp;{{ records.total|number_format(0, '.', ',')}}</span>
                   <span>Page {{ records.currentPage }} of {{ records.lastPage }}</span>
               </div>

           </div>
        </div>
        <div>
            <ul>

                {% if records.currentPage > 1 %}
                <li>
                    <a target="_blank" rel="nofollow noreferrer" href="{{ this.page.baseFileName|page( { page : (records.currentPage-1) ~ urlParams }) }}" title="Previous"><i class="fa fa-angle-left"></i></a>
       }} of {{ records.lastPage }}</span>
               </div>

           </div>
        </div>
        <div>
            <ul>

                {% if records.currentPage > 1 %}
                <li>
                    <a target="_blank" rel="nofollow noreferrer" target="_blank" rel="nofollow noreferrer" href="{{ this.page.baseFileName|page( { page : (records.currentPage-1) ~ urlParams }) }}" title="Previous"><i class="fa fa-angle-left"></i></a>
                </li>
                {% endif %}

                {% for page in pageSet %}
                {% if page == '...' %}
                <li>
                    <a target="_blank" rel="nofollow noreferrer" target="_blank" rel="nofollow noreferrer" href="javascript:void(0)" type="button" class="disabled">{{ page }}</a>
                </li>
                {% else %}
                <li class="{{ page == records.currentPage ? 'active' }}">
                    <a target="_blank" rel="nofollow noreferrer" target="_blank" rel="nofollow noreferrer" href="{{ this.page.baseFileName|page({ page : page ~ urlParams })  }}">{{ page }}</a>
                </li>
                {% endif %}
                {% endfor %}

                {% if records.lastPage > records.currentPage %}
                <li>
                    <a target="_blank" rel="nofollow noreferrer" target="_blank" rel="nofollow noreferrer" href="{{ this.page.baseFileName|page({ page : (records.currentPage+1) ~ urlParams }) }}" title="Next"><i class="fa fa-angle-right"></i></a>
                </li>
                {% endif %}
            </ul>
        </div>
    </div>


    {% endif %}

Then in your page or component ;

{% for painting in paintings %}
 ....
{% endfor %}

// Add the pagination

{% partial "pagination" records=paintings  %}
Ad
source: stackoverflow.com
Ad