DataTables Frequently Asked Questions

Frequently Asked Questions

Code

Controller

<?php
namespace Brown298\DtTestBundle\Controller;

use Brown298\DtTestBundle\Model\FaqTable;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

/**
 * Class FaqController
 * @package Brown298\DtTestBundle\Controller
 */
class FaqController extends Controller
{

    /**
     * @Route("/faq", name="faq")
     * @Template()
     */
    public function indexAction(Request $request)
    {
        $renderer = $this->get('templating');
        $em       = $this->get('doctrine.orm.entity_manager');

        // process the data table
        $faq = new FaqTable($renderer, $em);
        $faq->setContainer($this->container);
        if($response = $faq->processRequest($request)) {
            return $response;
        }

        return array(
            'columns' => $faq->getColumns(),
        );
    }
}

Model (FaqTable.php)

<?php
namespace Brown298\DtTestBundle\Model;

use Brown298\DataTablesBundle\Model\DataTable\AbstractQueryBuilderDataTable;
use Brown298\DataTablesBundle\Model\DataTable\QueryBuilderDataTableInterface;
use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Class FaqTable
 *
 * provides frequently asked questions
 *
 * @package Brown298\DtTestBundle\Model
 */
class FaqTable extends AbstractQueryBuilderDataTable implements QueryBuilderDataTableInterface
{
    /**
     * @var EngineInterface
     */
    protected $renderer;

    /**
     * @var array
     */
    protected $columns = array(
        'faq.question' => 'Frequently Asked Questions',
    );

    /**
     * @param EngineInterface $renderer
     * @param EntityManager $em
     */
    public function __construct(EngineInterface $renderer, EntityManager $em)
    {
        $this->renderer = $renderer;
        $this->em       = $em;
    }

    /**
     * getQueryBuilder
     *
     * @param Request $request
     *
     * @return null
     */
    public function getQueryBuilder(Request $request = null)
    {
        $userRepository = $this->em->getRepository('Brown298\DtTestBundle\Entity\Faq');
        $qb = $userRepository->createQueryBuilder('faq')
            ->andWhere('faq.deleted = false')
            ->andWhere('faq.active = true');

        return $qb;
    }

    /**
     * execute
     *
     * override execute to return objects
     *
     * @param $service
     * @param $formatter
     *
     * @return mixed
     */
    public function execute($service, $formatter)
    {
        return $service->process($formatter, true);
    }

    /**
     * getDataFormatter
     *
     * @return \Closure
     */
    public function getDataFormatter()
    {
        return function($data) {
            $count   = 0;
            $results = array();

            foreach ($data as $row) {
                $results[$count][] = array(
                    'question' => $row->getQuestion(),
                    'answer'   => $row->getAnswer(),
                );
                $count += 1;
            }

            return $results;
        };
    }
}

Twig Index (index.html.twig)

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

{% block javascripts %}
    {{ parent() }}
    <script type="text/javascript">
        /** callback for DataTable Render **/
        var faqRender = false;
        var faq_collapseCallback = function (oSettings) {
            var data = oSettings.aoData;
            if (data.length > 0 && faqRender === false) {
                faqRender = true;
                jQuery('.answer').hide();
                jQuery('.expand').on('click', function () {
                    jQuery(this).closest('.collapse-block').find('.answer').toggle("slow");
                });
            }
        };

        /** create the row format **/
        var faq_fnRowCallback = function (nRow, aData, iDisplayIndex) {
            var collapseBlock = jQuery('<div class="collapse-block"></div>');
            collapseBlock.append('<h4 class="expand"> + ' + aData[0].question + '</h4>');
            collapseBlock.append('<div class="answer">' + aData[0].answer + '</h4>');

            jQuery("td:eq(0)", nRow).html(collapseBlock);
            return nRow;
        };

    </script>
{% endblock %}

{% block body %}
    <h2>DataTables Frequently Asked Questions</h2>

    <div class="table-bordered">
        {{ addDataTable(columns, {
            'bLengthChange': 0,
            'bInfo':         0,
            'bSort':         0,
            'bFilter':       0,
            'bServerSide':   0,
            'customParams':  {
                'fnDrawCallback': 'function (o) { faq_collapseCallback(o); }',
                'fnRowCallback':  'function (a, b, c) { faq_fnRowCallback(a, b, c); }',
            }
        }) }}
    </div>

{% endblock %}