Ajax and jQuery tutorials for Symfony2 - by TipoCode


Symfony2 Ajax Lab - jQuery Plugins for Symfony2

Home Ajax - jQuery autocomplete & symfony2

Ajax - jQuery autocomplete & symfony2

How to add an autocomplete field in forms Symfony2 using jQuery / AJAX

For the full tutorial explanation, click here.

Demo

Please search for a country and select the one you want on the returning list (type at least 2 characters).

Code

Bundle name: Sim100/TutoBundle

Layout

First, somewhere in your layout, at the bottom of your page, inside the {% block javascripts %} block, please add:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="{{ asset('bundles/tuto/js/autocomplete-countries.js') }}"></script>
<script>
    var loader = "{{ asset('bundles/tuto/images/loader-small.gif') }}"; //link to the animated loader-small.gif
    var ROOT_URL = "{{ url('tuto_homepage')}}"; //your root URL, used in autocomplete-countries.js file
</script>

JS

bundles/tuto/js/autocomplete-countries.js

$(document).ready(function(){
     $("#myTextField").on('keyup', function() { // everytime keyup event
             var input = $(this).val(); // We take the input value
             if ( input.length >= 2 ) { // Minimum characters = 2 (you can change)
                     $('#match').html('<img src="' + window.loader + '" />'); // Loader icon apprears in the <div id="match"></div>
                     var data = {input: input}; // We pass input argument in Ajax
                     $.ajax({
                             type: "POST",
                             url: ROOT_URL + "ajax/autocomplete/update/data", // call the php file ajax/tuto-autocomplete.php (check the routine we defined)
                             data: data, // Send dataFields var
                             dataType: 'json', // json method
                             timeout: 3000,
                             success: function(response){ // If success
                                     $('#match').html(response.countryList); // Return data (UL list) and insert it in the <div id="match"></div>
                                     $('#matchList li').on('click', function() { // When click on an element in the list
                                             $('#myTextField').val($(this).text()); // Update the field with the new element
                                             $('#match').text(''); // Clear the <div id="match"></div>
                                     });     
                             },
                             error: function() { // if error
                                     $('#match').text('Problem!');
                             }
                     });
             } else {
                     $('#match').text(''); // If less than 2 characters, clear the <div id="match"></div>
             }
     });
 });

Controller

AjaxAutocompleteController.php

<?php
namespace Sim100\TutoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Sim100\TutoBundle\Entity\countries;

class AjaxAutocompleteController extends Controller
{
    public function updateDataAction(Request $request)
    {
        $data = $request->get('input');
        
        $em = $this->getDoctrine()->getManager();

        $query = $em->createQuery(''
                . 'SELECT c.id, c.name '
                . 'FROM Sim100TutoBundle:countries c ' 
                . 'WHERE c.name LIKE :data '
                . 'ORDER BY c.name ASC'
                )
                ->setParameter('data', '%' . $data . '%');
        $results = $query->getResult();
        
        $countryList = '<ul id="matchList">';
        foreach ($results as $result) {
            $matchStringBold = preg_replace('/('.$data.')/i', '<strong>$1</strong>', $result['name']); // Replace text field input by bold one
            $countryList .= '<li id="'.$result['name'].'">'.$matchStringBold.'</li>'; // Create the matching list - we put maching name in the ID too
        }
        $countryList .= '</ul>';

        $response = new JsonResponse();
        $response->setData(array('countryList' => $countryList));
        return $response;
    }
}

AutocompleteController.php

<?php
namespace Sim100\TutoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sim100\TutoBundle\Entity\countries;

class AutocompleteController extends Controller
{
    public function indexAction()
    {
        $repository = $this
            ->getDoctrine()
            ->getManager()
            ->getRepository('Sim100TutoBundle:countries')
          ;

        $listCountries = $repository->findBy(
            array(),                      // Critere
            array('id' => 'desc'),        // Tri
            null,                         // Limite
            null                          // Offset
          );

        
      return $this->render('Sim100TutoBundle:Autocomplete:index.html.twig', array(
          'listCountries' => $listCountries,
      ));
      
    }
}

Entity

countries.php

<?php
namespace Sim100\TutoBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * countries
 *
 * @ORM\Table(name="tc_countries")
 * @ORM\Entity(repositoryClass="Sim100\TutoBundle\Repository\countriesRepository")
 */
class countries
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;


    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return countries
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
}

Repository

countriesRepository.php

<?php
namespace Sim100\TutoBundle\Repository;

/**
 * countriesRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class countriesRepository extends \Doctrine\ORM\EntityRepository
{
}

Resources

config

routing.yml

tuto_autocomplete:
    path:     /autocomplete
    defaults: { _controller: Sim100TutoBundle:Autocomplete:index }

ajax_autocomplete_countries:
  path:  /ajax/autocomplete/update/data
  defaults: { _controller: Sim100TutoBundle:AjaxAutocomplete:updateData }

views

Autocomplete

index.html.twig

<p>Please search for a country and select the one you want on the returning list (type at least 2 characters).</p>
    <p>
    <input type="text" id="myTextField" />
    <div id="match"></div>
    </p>

© 2017 tipocode.com, all rights reserved.