Letzte Woche kam die Anforderung nach einem Ajax-basiertes Autocomplete-Formular-Element. Der Benutzer soll einen Ort bzw. eine Postleitzahl eingeben und in Abhängigkeit des Inputs liefert das System verschiedene Vorschläge. Mit dem zuständigen Frontend-Developer vereinbarte ich eine Ajax-basierte JSON-Schnittstelle.
[
{"postalcode":"26123","cityname":"Oldenburg in Oldenburg"},
{"postalcode":"21385","cityname":"Oldendorf (Luhe)"},
{"postalcode":"25588","cityname":"Oldendorf, Holstein"},
{"postalcode":"21726","cityname":"Oldendorf, Kreis Stade"},
{"postalcode":"25870","cityname":"Oldenswort"}
]
Im Anschluss ging es an die Implementierung des Ajax-Controllers. Hierbei ist es ratsam, im Response Header den ‚Content-type‘ auf ‚application/json; charset=utf-8‘ zusetzen (Zeile 12). Somit weiß der Client, welches Format der Controller zurückliefert. Die Eingabe des Users wird dann aus dem Request gelesen, die Datenbank abgefragt und die Ausgabe als PHP array generiert. Mittels der Funktion json_encode lässt sich dieses array dann einfach in den Content des Response schreiben (Zeile 38) und fertig ist der Json Response:
<?php
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
class LocationController extends Controller {
/**
* @Route("/location/suggest.json", name="location")
*/
public function suggestAction() {
$response = new Response();
$response->headers->set('Content-type', 'application/json; charset=utf-8');
$pattern = $this->getRequest()->get('q', null);
$return = array();
if ($pattern !== null) {
$qb = $this->get('doctrine.orm.entity_manager')
->createQueryBuilder()
->select('p')
->from('Movesto\OfferBundle\Entity\Postalcode', 'p');
$numeric = false;
if (is_numeric($pattern)) {
$qb->where($qb->expr()->like('p.postalcode', '?1'))
->orderBy('p.postalcode', 'ASC');
$numeric = true;
} else {
$qb->where($qb->expr()->like('p.cityname', '?1'))
->orderBy('p.cityname', 'ASC');
}
$pattern = $pattern . '%';
$qb->setParameter(1, $pattern);
$query = $qb->getQuery();
foreach ($query->getResult() as $p) {
$return[] = array('postalcode' => $p->getPostalcode(),
'cityname' => $p->getCityname()
);
}
}
$response->setContent(json_encode($return));
return $response;
}
}