Full (php + javascript) method on admin class. Just an override of SonataAdminBundle:CRUD:list.html.twig with custom AJAX method for add autocompletion to filters on properties name and firstname of my Admin Class.
Last active
March 24, 2022 11:23
-
-
Save chalasr/5c27ae64dc596967f18a to your computer and use it in GitHub Desktop.
Autocompletion AJAX for SonataAdminBundle $datagridMapper filters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% extends 'SonataAdminBundle:CRUD:base_list.html.twig' %} | |
{% block javascripts %} | |
{{ parent() }} | |
<script type="text/javascript"> | |
$(document).ready(function(){ | |
var MIN_LENGTH = 3; | |
var datalistFirst = $('<ul class="select2-results autoResults" role="listbox" id="datalist_filter_firstname_value"></ul>'); | |
var datalistName = $('<ul class="select2-results autoResults" role="listbox" id="datalist_filter_name_value"></ul>'); | |
$('#filter_name_value').after(datalistName); | |
$('#filter_firstname_value').after(datalistFirst); | |
var results = []; | |
$('input').keydown(function(event){ | |
var idAttr = $(this).attr('id'); | |
if((event.keyCode == 13) && (results.length > 0)) { | |
event.preventDefault(); | |
var choice = $('.'+idAttr+'-selected').text(); | |
if(choice != ''){ | |
$('#'+idAttr).val(choice); | |
$('.select2-results').empty(); | |
} | |
}else if((event.keyCode) == 40){ | |
var chosen = $('.'+idAttr+'-selected').attr('data-item'); | |
var next = Number(chosen)+1; | |
if(next < results.length){ | |
var nextLi = $('#datalist_'+idAttr+' li[data-item="'+next+'"]'); | |
$('.'+idAttr+'-selected').removeClass(idAttr+'-selected'); | |
nextLi.addClass(idAttr+'-selected'); | |
$("#datalist_"+idAttr).scrollTo($('.'+idAttr+'-selected')); | |
} | |
}else if((event.keyCode == 38)){ | |
var chosen = $('.'+idAttr+'-selected').attr('data-item'); | |
var next = Number(chosen)-1; | |
if(next >= 0){ | |
var nextLi = $('#datalist_'+idAttr+' li[data-item="'+next+'"]'); | |
$('.'+idAttr+'-selected').removeClass(idAttr+'-selected'); | |
nextLi.addClass(idAttr+'-selected'); | |
$("#datalist_"+idAttr).scrollTo($('.'+idAttr+'-selected')); | |
} | |
} | |
}); | |
$("input").keyup(function(event) { | |
var idAttr = $(this).attr('id'); | |
if(idAttr == 'filter_name_value' || idAttr == 'filter_firstname_value'){ | |
var keyword = $(this).val(); | |
if((event.keyCode != 40) && (event.keyCode != 38)){ | |
results = []; | |
$('#datalist_'+idAttr).empty(); | |
if (keyword.length >= MIN_LENGTH && (event.keyCode != 13)) { | |
var where = idAttr == 'filter_name_value' ? $('#filter_firstname_value').val() : $('#filter_name_value').val(); | |
var dataObj = { keyword: keyword, field: idAttr, where: where }; | |
$.post("/admin/application/personne/personne/autocomplete", dataObj) | |
.done(function(data) { | |
data.forEach(function(item){ | |
var content = idAttr == 'filter_name_value' ? item.name : item.firstname; | |
if(results.indexOf(content) == -1){ | |
results.push(content); | |
var indexItem = results.indexOf(content); | |
var option = '<li id="'+content+'" data-name="'+idAttr+'" data-item="'+indexItem+'" class="select2-no-results result">'+content+'</li>'; | |
$('#datalist_'+idAttr).append(option); | |
$('#datalist_'+idAttr).show(); | |
$('.result').click(function(){ | |
var goodInput = $(this).attr('data-name'); | |
var newName = $(this).attr('id'); | |
$('#'+goodInput).val(newName); | |
$('.select2-results').empty(); | |
results = []; | |
}) | |
} | |
}) | |
if(results.length > 0){ | |
var firstChoice = $('#datalist_'+idAttr+' li:first'); | |
firstChoice.addClass(idAttr+'-selected'); | |
} | |
}); | |
}else if(keyword.length < 3){ | |
$('#datalist_'+idAttr).empty(); | |
results = []; | |
} | |
} | |
} | |
}); | |
}); | |
</script> | |
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#datalist_filter_name_value li:hover{ | |
cursor: pointer; | |
} | |
#datalist_filter_name_value li{ | |
padding-top: 5px; | |
padding-bottom: 5px; | |
border-bottom: 1px solid #757575; | |
background: rgba(244, 244, 244, 0.9); | |
font-weight: 600; | |
} | |
#datalist_filter_firstname_value li:hover{ | |
cursor: pointer; | |
} | |
#datalist_filter_firstname_value li{ | |
padding-top: 5px; | |
padding-bottom: 5px; | |
background: rgba(244, 244, 244, 0.9); | |
font-weight: 600; | |
} | |
.autoResults{ | |
z-index: 3; | |
position: absolute; | |
max-height: 125px; | |
width: 15%; | |
} | |
.filter_firstname_value-selected{ | |
background: #757575!important; | |
} | |
.filter_name_value-selected{ | |
background: #757575!important; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Application\PersonneBundle\Controller; | |
use Sonata\AdminBundle\Controller\CRUDController as Controller; | |
use Symfony\Component\HttpFoundation\JsonResponse; | |
use Symfony\Component\HttpFoundation\Request; | |
class PersonneAdminController extends Controller | |
{ | |
public function autocompleteAction(){ | |
$request = new Request(); | |
$request = $request->createFromGlobals(); | |
$keyword = $request->request->get('keyword'); | |
$field = $request->request->get('field'); | |
$where = $request->request->get('where'); | |
$property = explode('_', $field)[1]; | |
$whereProperty = $property == 'name' ? 'firstname' : 'name'; | |
$repository = $this->getDoctrine() | |
->getRepository('ApplicationPersonneBundle:Personne'); | |
$query = $repository->createQueryBuilder('p') | |
->select('p.'.$property) | |
->where('p.'.$property.' LIKE :word') | |
->andWhere('p.'.$whereProperty.' LIKE :where') | |
->setParameter('word', '%'.$keyword.'%') | |
->setParameter('where', '%'.$where.'%') | |
->getQuery(); | |
$data = $query->getResult(); | |
return new JsonResponse($data); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice work! Though there is a lot of javascript code going on! ;) I guess it would have been easier to get some of the core select2 code from the autocompleter.
Maybe we're lucky and it will become a feature:
sonata-project/SonataAdminBundle#3172
Came from: