Making-Websites-With-October-CMS icon indicating copy to clipboard operation
Making-Websites-With-October-CMS copied to clipboard

Creating Ajax pagination with default October Pagination

Open ivandoric opened this issue 7 years ago • 12 comments

Rolands Zeltins wrote this piece of code to make Ajax pagination (https://www.youtube.com/watch?v=uCsvcRsPEe4) not be dropdown, but standard pagination you get with October. Hope it helps somebody.

//Submit data on form change
    $('.main-section').on('change', 'input, select', function(){
        var $form = $(this).closest('form');
        $form.request();
    });

//Pagination part
    $('.main-section').on('click', '.pagination > li > a', function (event) {
    var page = $(this).text();
    event.preventDefault();
    if ($(this).attr('href') != '#') {
        $("html, body").animate({scrollTop: 0}, "fast");
        $.request('onFilterAudios', {
            data: {page: page},
            update: {'movie/movies': '#movieList'}
        });
    }
});

And inside partial witch should be reloaded put in

{{ audios.render|raw }}

It will render bootstrap pagination

Hope it will help someone!

ivandoric avatar Aug 09 '17 08:08 ivandoric

Hello Ivan, than you for your work on the October CMS series. I’ve been trying to implement the code above but I’m stuck.

The pagination links render but nothing happens when I click the on a page number/ next link.

However, when I paginate vía the select box the active page changes on the pagination links. What am i missing? Does pagination need its own Ajax handler or can I use onfiltermovies model?

Thanks again for all your work!

ghost avatar Jun 10 '18 17:06 ghost

I don't know. I never tested that code, it was sent to me by the viewer of the channel.

ivandoric avatar Jun 11 '18 07:06 ivandoric

The problem comes with the pagination template and the way the links are created. I updated mine to look something like this:

Script:

//Pagination part
            $('#paginatePosts').on('click', '.pagination > li > a', function (event) {
                
               // reference the href attribute of the list item anchor tag
                var page = $(this).attr('href');

                event.preventDefault();
                if ($(this).attr('href') != '#') {
                    $("html, body").animate({scrollTop: 0}, "slow");
                    $.request('onFilterPosts', {
                        data: {page: page},

                        // here i separated the movie list and pagination partial
                        update: {'movie/movies': '#movieList', 'movie/paginate':'#moviesPagination'}
                    });
                }
            });

Pagination partial: I removed the actual page numbers from my pagination, and just include a Previous/Next button. Notice that the href attribute is set using twig to the currentPage+/-1

{% if movies.lastPage > 1 %}
<div class="row justify-content-center">
    <nav aria-label="pagination example">
        <ul class="pagination pagination-lg pg-blue">
            {% if movies.currentPage > 1 %}
            <!--Arrow left-->
            <li class="page-item">
                <a class="page-link" href="{{movies.currentPage-1}}" aria-label="Previous">
                    <span aria-hidden="true">&laquo; Previous</span>
                    <span class="sr-only">Previous</span>
                </a>
            </li>
            {% endif %}

            <!--Arrow right-->
            {% if movies.lastPage > movies.currentPage %}
            <li class="page-item">
                <a class="page-link" href="{{movies.currentPage+1}}" aria-label="Next">
                    <span aria-hidden="true">Next &raquo;</span>
                    <span class="sr-only">Next</span>
                </a>
            </li>
            {% endif %}
        </ul>
    </nav>
</div>
{% endif %}

Hope this helps. I'm using this example on another project, and implementing my own filter. I am having problems with paginated filtered results. For instance, when I apply the filter and there is more then one page, when I move to the second page, the filter does not apply.

LarryBarker avatar Aug 15 '18 18:08 LarryBarker

The pagination links render but nothing happens when I click the on a page number/ next link.

However, when I paginate vía the select box the active page changes on the pagination links. What am i missing? Does pagination need its own Ajax handler or can I use onfiltermovies model?

I am was having a similar issue here, except when I click on the bootstrap page it always returns to the first page.

Instead I used a different approach:

function getURLParameter(url, name) {
        return (RegExp(name + '=' + '(.+?)(&|$)').exec(url)||[,null])[1];
    }
    
    $('#insert-pagination-id').on('click', '.pagination > li > a', function () {
    var url = $(this).attr('href');
    var page_no = getURLParameter(url, 'page');
 
        $('#insert-drop-down-id').val(page_no); 
        $(this).removeAttr("href");

        var $form = $(this).closest('form');
        $form.request();
   
     });

Hope this helps someone

Krank3n avatar May 02 '19 04:05 Krank3n

//Submit data on form change
    $('.main-section').on('change', 'input, select', function(){
        var $form = $(this).closest('form');
        $form.request();
    });

//Pagination part
    $('.main-section').on('click', '.pagination > li > a', function (event) {
    var page = $(this).text();
    event.preventDefault();
    if ($(this).attr('href') != '#') {
        $("html, body").animate({scrollTop: 0}, "fast");
        $.request('onFilterAudios', {
            data: {page: page},
            update: {'movie/movies': '#movieList'}
        });
    }
});

I don't understand where this code is placed. The model, controller, page, or partial? Does it need to be wrapped in a script tag? Is ".main-section" the id of a the list section that will change onClick?

Thank you

cg0012 avatar Dec 15 '19 06:12 cg0012

//Submit data on form change
    $('.main-section').on('change', 'input, select', function(){
        var $form = $(this).closest('form');
        $form.request();
    });

//Pagination part
    $('.main-section').on('click', '.pagination > li > a', function (event) {
    var page = $(this).text();
    event.preventDefault();
    if ($(this).attr('href') != '#') {
        $("html, body").animate({scrollTop: 0}, "fast");
        $.request('onFilterAudios', {
            data: {page: page},
            update: {'movie/movies': '#movieList'}
        });
    }
});

I don't understand where this code is placed. The model, controller, page, or partial? Does it need to be wrapped in a script tag? Is ".main-section" the id of a the list section that will change onClick?

Thank you

To test it out, You can put it on your page or partial with the pagination and form depending on how you set it up. Yes, It will need to be wrapped in a script tag. From what I remember, the .main-section is the class or (should probably use the ID instead) of the form that changes the list section.

This took me a long time to work out how to get this working well. If you would like an alternative tutorial on it, with some similar and different features, let me know and I can make one.

Krank3n avatar Dec 15 '19 14:12 Krank3n

Awesome. Unfortunately, I've already exhausted plenty of trials on different placement of code (and destroyed too many hours. But its "fun" right?? :/)

if you can and are willing to just copy your code with notes on placement, I can most likely digest it back into my query. Or whatever you had in mind for alternative tutorial. This would be greatly appreciated

THANK YOU VERY MUCH FRIEND

cg0012 avatar Dec 15 '19 15:12 cg0012

I'll try and make a cool video tutorial on this, this week if I get the chance.

I don't think my code will help you now because it was heavily altered. Also, since using it, I decided to use an infinite scroll option. You can have a quick look anyway:


{{ form_ajax('onFilterResorts', { update: { 'resorts/resorts': '#content', 'resorts/paginate': '#resort-pagination' } }) }}
        <div id="ResortsFilter" class="resorts-filter ui form">
            <div id="resort-pagination" class="resort-pagination">
            <div class="resort-paginate" data-request="onFilterResorts" name="Filter[page]">
            <label >Page</label>
            <select id="rd" class="ui fluid dropdown resort-paginate" data-request="onFilterResorts" name="Filter[page]">
                {% for i in 1..pages %}
                    {%  if i == page %}
                        <option value="{{page}}" selected>{{ page }}</option>
                    {% else %}
                        <option value="{{i}}">{{ i }}</option>
                    {% endif %}
                {% endfor %}
            </select>


            {{ resorts.render|raw }}
 
             </div>
            </div>
        </div>
{{ form_close() }} 

<script>
$('#pagination').on('click', '.pagination a', function (event) {
    event.preventDefault();
    if ($(this).attr('href') != '#') {    
        $("html, body").animate({scrollTop: 0}, "fast");
        $.request('onFilterResorts', {
        data: {page: page, sortDirection: sortDirection, sortField: sortField},
        update: {'resorts/resorts' : '#content', 'paginate' : '#pagination'}
        });
    }
});
</script>

Krank3n avatar Dec 17 '19 03:12 Krank3n

$('.main-section').on('click', '.ui.pagination > li > a', function (event) {
        event.preventDefault();
        var page = $(this).attr('href');
        
        if ($(this).attr('href') != '#') {
            $("html, body").animate({scrollTop: 0}, "fast");
            $.request('onFilterCustomers', {
                data: { page: page },
                update: { 'admin/customers/customers' : '#customerList'}
            });
            console.log(page);
        }
    });

It seems like it should be working, but for some reason, the request isn't happening. Could somebody help me out? It's not setting the page number, and it's not updating the partial.

kasperbb avatar Apr 07 '20 07:04 kasperbb

I'll try and make a cool video tutorial on this, this week if I get the chance.

I don't think my code will help you now because it was heavily altered. Also, since using it, I decided to use an infinite scroll option. You can have a quick look anyway:


{{ form_ajax('onFilterResorts', { update: { 'resorts/resorts': '#content', 'resorts/paginate': '#resort-pagination' } }) }}
        <div id="ResortsFilter" class="resorts-filter ui form">
            <div id="resort-pagination" class="resort-pagination">
            <div class="resort-paginate" data-request="onFilterResorts" name="Filter[page]">
            <label >Page</label>
            <select id="rd" class="ui fluid dropdown resort-paginate" data-request="onFilterResorts" name="Filter[page]">
                {% for i in 1..pages %}
                    {%  if i == page %}
                        <option value="{{page}}" selected>{{ page }}</option>
                    {% else %}
                        <option value="{{i}}">{{ i }}</option>
                    {% endif %}
                {% endfor %}
            </select>


            {{ resorts.render|raw }}
 
             </div>
            </div>
        </div>
{{ form_close() }} 

<script>
$('#pagination').on('click', '.pagination a', function (event) {
    event.preventDefault();
    if ($(this).attr('href') != '#') {    
        $("html, body").animate({scrollTop: 0}, "fast");
        $.request('onFilterResorts', {
        data: {page: page, sortDirection: sortDirection, sortField: sortField},
        update: {'resorts/resorts' : '#content', 'paginate' : '#pagination'}
        });
    }
});
</script>

Hi there all! I am still very interested in making this paginator work. Are there any tutorials about this online yet? Best R

rafaelteb avatar Jul 14 '20 09:07 rafaelteb

I have added bootstrap pagination in the following way. =>first make the dropdown pagination work. =>put the bootstrap pagination code at the end in the partial e-g movie/movie.htm or whatever you filename is. to display it at the end of the records.

{% if pages > 1 %}
<div class="row col-md-12 ml-1 mt-5">
    <nav aria-label="pagination example" id="p_cutom">
        <ul class="pagination pagination-lg pg-blue">
            {% if page > 1 %}
            <!--Arrow left-->
            <li class="page-item">
                <a class="page-link" href="{{page-1}}" aria-label="Previous">
                    <span aria-hidden="true">&laquo; Previous</span>
                    <span class="sr-only">Previous</span>
                </a>
            </li>
            {% endif %}


                    {% for i in 1..pages %}
                             <li class="page-item {% if i == page %}active{% endif %}">
                                <a class="page-link" href="{{i}}" aria-label="{{i}}">
                                    <span aria-hidden="true">{{i}} </span>
                                    <span class="sr-only">{{i}}</span>
                                </a>
                            </li>   
                    {% endfor %}


            <!--Arrow right-->
            {% if pages > page %}
            <li class="page-item">
                <a class="page-link" href="{{page+1}}" aria-label="Next">
                    <span aria-hidden="true">Next &raquo;</span>
                    <span class="sr-only">Next</span>
                </a>
            </li>
            {% endif %}
        </ul>
    </nav>
</div>
{% endif %}

{{ pages.render|raw }}

=>then you have to add some javascript code

 $(document).on("click","#p_cutom .pagination > li > a",function() {
    var url = $(this).attr('href');
    $('#d_filter').val(url); 
    $(this).removeAttr("href");

    var $form = $(this).closest('form');
    $form.request();

 });

=>if you don't need the dropdown you can hide it with display:none. but its needs to be implemented. I hope this helps someone.

mudassarqureshi avatar Aug 25 '20 10:08 mudassarqureshi

Hey @ivandoric since none of these solutions works, could you make video about? 🥺🙏

I also tried with radio buttons, like u suggested in this video, but the problem is (name="Filter[page]) attribute on input that is inside loop and is the same too many times. Because of this name field, any page i click it keeps displaying page 1.

{% for i in 1..pages %}
        {% if i == page %}
                <label class="form-check-label" for="pages{{ page }}">
                        {{ page }}
                </label>
                <input class="form-check-input" name="Filter[page]" type="radio" id="flexRadioDefault{{ page }}" checked>
        {% else %}
                <label class="form-check-label" for="flexRadioDefaul{{ i }}">
                        {{ i }}
                </label>
                <input class="form-check-input" name="Filter[page]" type="radio" id="flexRadioDefault{{ i }}">
        {% endif %}
{% endfor %}

I there any quick fix for this? Or should I do it the long way (for every page selected inside select, click radio button via JavaScript)

mskraban avatar Mar 14 '21 21:03 mskraban