KNP Pagination: How to use javascript to get paginated page contents match a given page

95 Views Asked by At

A project has a page that allows edit of a Meal entity. Meal has a ManyToMany relationship with a Food entity. The edit page shows a list of food already selected for the meal, along with a KNP paginated list of foods available. When an available food is clicked on the script rewrites the list of selected foods as well as rewrites the list of available foods. So far so good.

What happens, though, is the script builds the available list from the bottom up. So, for instance, if an item on page 3 is selected, the page selector will show page 3 as active but the contents of the page is that of page 1. I'd like instead to either make page 1 active or the page contents be appropriate to the active page number.

If this makes sense, here's some relevant code. (Note: It may be obvious that I'm not fluent in javascript.)

add-food.js (key variable is pageNumber):

$('td').on('click', function (e) {
    foodId = $(e.currentTarget).data('foodid');
    mealId = $("#mealid").data("mealid");
    var pageNumber = $('li.active').first().text().trim();
    var pageLimit = $("#mealid").data("pagelimit");
    $packet = JSON.stringify([foodId, mealId]);
    $.post('http://diet/meal/' + mealId + '/addFoodToMeal', $packet, function (response) {
        editFoods = $.parseJSON(response);
        var readyToEat = $.parseJSON(editFoods[0]);
        var pantry = $.parseJSON(editFoods[1]);
        var table = document.getElementById('ready_foods')
        $('#ready_foods tr:not(:first)').remove();
        $.each(readyToEat, function(key, food) {
            var row = table.insertRow(-1);
            var cell = row.insertCell(0);
            cell.innerHTML = food;
        })
        var table = document.getElementById('pantry')
        $('#pantry tr:not(:first)').remove();
        
        $.each(pantry.slice(0, pageLimit), function(key, array) {
            food = array.split(",");
            foodId = food[0];
            foodName = food[1];
            var row = table.insertRow(-1);
            var cell = row.insertCell(0);
            cell.innerHTML = foodName;
            cell.setAttribute('data-foodid', foodId);
        })
    });
});

edit.html.twig:

{% extends 'base.html.twig' %}

{% block title %}Edit Meal{% endblock %}

{% block body %}
    <h1>Edit Meal</h1>
    <div id="mealid" data-mealid="{{meal.id}}" data-pagelimit="{{ pageLimit }}"></div>
    {{ form_start(form, {'attr': {'class': 'js-meal-form'}}) }}
    <div class="row">
        <div class="col-6">
            {{ include('meal/_form.html.twig') }}
                <table class="table" id="ready_foods">
                    <thead>
                        <tr>
                            <th>Ready to eat</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for food in meal.foods %}
                            <tr>
                                <td>{{ food.foodName }}</td>
                            </tr>
                        {% endfor %}
                    </tbody>
                </table>            
        </div>
        <div class="col-6">
            {{ include('food/_foods.html.twig') }}
        </div>
    </div>
    <button class="btn btn-info">{{ button_label|default('Save') }}</button>
    {{ form_end(form) }}
    <a href="{{ path('app_meal_index') }}">back to list</a>

    {{ include('meal/_delete_form.html.twig') }}
{% endblock %}
{% block javascripts %}
    {{ parent() }}
    <script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js" defer ></script>
    <script>
        $(document).ready(function () {
            $('.js-datepicker').datepicker({
                format: 'yyyy-mm-dd'
            });
        });
    </script>
    {{ encore_entry_script_tags('add-food') }}
{% endblock %}

_foods.html.twig (where pagination happens)

{# templates/food/_foods.html.twig #}
<h3>Available foods</h3>
<div class="input-group mb-3">
    <input type="text"
           name="q"
           class="form-control"
           value="{{ app.request.query.get('q') }}"
           placeholder="Search..."
           >
    <div class="input-group-append">
        <button type="submit"
                class="btn btn-outline-secondary">
            <span class="fa fa-search"></span>
            Search
        </button>
    </div>
</div>

{% if pagination is not empty %}
    <table class="table" id="pantry">
        <thead>
            <tr>
                <th>Click name to add to meal</th>
            </tr>
        </thead>
        <tbody>
            {% for food in pagination %}
                <tr>
                    <td data-foodid={{ food.id }}>{{ food.foodName }}</td>
               </tr>
            {% else %}
                <tr>
                    <td colspan="3">no records found</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
    {{ knp_pagination_render(pagination) }}
{% endif %}
1

There are 1 best solutions below

0
geoB On

Turns out there's a simple way to make page 1 of the pagination active - since the first page will be rendered by the script. Two lines:

        $('li.active').removeClass('active');
        $('li.page-item:nth-of-type(2)').addClass('active');