ivandoric / Making-Websites-With-October-CMS

This is a repository for video tutorial series about making websites with October CMS. You can check out the series here: https://goo.gl/eW32CM
160 stars 52 forks source link

Creating Ajax pagination with default October Pagination #9

Open ivandoric opened 7 years ago

ivandoric commented 7 years ago

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!

ghost commented 6 years ago

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!

ivandoric commented 6 years ago

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

LarryBarker commented 6 years ago

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.

Krank3n commented 5 years ago

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

cg0012 commented 4 years ago
//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

Krank3n commented 4 years ago
//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.

cg0012 commented 4 years ago

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

Krank3n commented 4 years ago

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>
kasperbb commented 4 years ago
$('.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.

rafaelteb commented 4 years ago

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

mudassarqureshi commented 4 years ago

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.

mskraban commented 3 years ago

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)