formssymfonyformcollectionknppaginator

Pagination of a Symfony form collection with KnpPaginatorBundle


like in How to handle Symfony form collection with 500+ items i have got a big symfony form collection. In the mentioned thread someone suggests to use pagination for the collection.

How can i paginate such a form collection with the knpPaginatorBundle?

The form type is like this

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('myType', 'collection', array(
            'type' => new MyType(),
        ))
    ;
}

My controller generates a form with the collection

$form = $this->createForm(new MyFormCollectionType());

and then i'm trying to use the paginator

$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
    $form['myType'],
    $request->get('page', 1),
    10
);

I think i'm using the wrong target for paginate($target), whats the correct target in a symfony form collection?


Solution

  • Example on Symfony3 :

    Catalog Controller

    // I want to paginate products (my collection)
    $products = $catalog->getProducts();   // ArrayCollection
    
    // Pagination
    $paginator  = $this->get('knp_paginator');
    $pagination = $paginator->paginate($products, $request->query->getInt('page', 1), 10);
    
    // build the form with catalog data
    $form = $this->createForm(CatalogProductType::class, $catalog, array("pagination" => $pagination));
    
    // [...]
    
    // show page
    return $this->render('catalogs/products.html.twig', array(
        'catalog'    => $catalog,
        'form'       => $form->createView(),
        'pagination' => $pagination
    ));
    

    Catalog Form (CatalogProductType)

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('products',   CollectionType::class, array(
                'entry_type'    => ProductType::class,
                'data'          => $options['pagination'],
                'allow_add'     => true,
                'allow_delete'  => true,
                'prototype'     => true,
                'label'         => false,
                'by_reference'  => false
            ))
            ->add('save', SubmitType::class, array(
                'attr'    => array('class' => 'button-link save'),
                'label'   => 'Validate'
            ))
        ;
    }
    
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'    => 'AppBundle\Entity\Catalog',
            'pagination'    => null    // Don't forget this !
        ));
    }
    

    My view (products.html.twig)

    <div class="navigation">{{ knp_pagination_render(pagination) }}</div>
    
    {% if pagination.getTotalItemCount > 0 %}
        {% for widget in form.products.children %}
            {# Refers to a Twig macro #}
            {{ _self.prototype_product(widget) }}
        {% endfor %}
    {% else %}
        <div class="error">The is no product in this catalog</div>
    {% endif %}
    

    My products collection is now paginated.