I'm using AJAX to request client names from my DB using autocomplete() inside an input #descricao. It requests a route that I created inside Symfony 4 (/acao).
The problem is that I'm trying to set a parameter (/acao?parametro=clientname) but I'm get an error:
Could not resolve argument $parametro of
"App\Controller\DefaultController::filter()", maybe you forgot to
register the controller as a service or missed tagging it with the
"controller.service_arguments"?
I tried to change my routes.yaml:
acao:
path: /acao
controller: App\Controller\DefaultController::filter
methods: GET
but it didn't work.
script.js:
$( "#descricao" ).autocomplete({
source: function( parametro, response ) {
$.ajax({
url: '/acao',
dataType: "json",
data: {
parametro: $('#descricao').val()
},
success: function(data) {
response(data);
}
});
}
});
DefaultController:
/**
* #param string $parametro
* #return JsonResponse
* #Route("/acao", name="acao", methods="GET")
*/
public function filter(string $parametro){
$em = $this->getDoctrine()->getManager()->getRepository(Clients::class)
->createQueryBuilder('c')
->andWhere('c.name_fantasy ilike :parametro')
->setParameter('parametro','%'.$parametro.'%')
->getQuery()
->getArrayResult();
return new JsonResponse($em);
}
What am I doing wrong?
ANSWER:
I managed to make it work using POST and changing table name c.name_fantasy to values:
Controller:
/**
* #param Request $request
* #return JsonResponse
* #Route("/acao", name="acao", methods="POST")
*/
public function filter(Request $request){
$q = strtoupper(trim($request->request->get('parametro')));
$em = $this->getDoctrine()->getManager()->getRepository(Clients::class)
->createQueryBuilder('c')->select('c.name_fantasy AS value')
->andWhere('c.name_fantasy like :parametro')
->setParameter('parametro', '%'.$q.'%')
->getQuery()
->getArrayResult();
return new JsonResponse($em);
}
AJAX:
$( "#descricao" ).autocomplete({
source: function( parametro, response ) {
$.ajax({
url: '/acao',
dataType: 'json',
method: 'POST',
data: {
parametro: $('#descricao').val()
},
success: function(data) {
if (data.length > 0) {
response(data);
}
else {
data = '';
response(data)
}
},
});
}
});
Firstly, you dont need use routes.yaml for routing, if you use the Route Component:
Symfony\Component\Routing\Annotation\Route
So just delete that stuff from routes.yaml.
EDITED:
/**
* #param Request $request
* #return JsonResponse
* #Route("/acao", name="acao", methods="GET", options={"expose"=true})
*/
public function filter(Request $request)
{
//you should strip and trim the parameter, like (just basic):
$clientName = strip_tags(
trim($request->query->get('parametro'))
);
// ...
}
Where Request is Symfony\Component\HttpFoundation\Request <-- you need add to the use statements!
If this not working for you, with your original ajax (what in your question), try on this way:
// ...
let formData = new FormData();
formData.append("parametro", $('#descricao').val());
$.ajax({
url: '/acao',
// ...
data : formData,
// ...
JUST A TIP:
I recommend, use the symfony/bundles/FOSJsRoutingBundle. You can link your routes in js like this:
import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router';
import Routes from '../../public/assets/js/fos_js_routes.json';
Routing.setRoutingData(Routes);
// ...
$.ajax({
//acao is your route name and you route in this case:
url: Routing.generate("acao"),
Dump the latest added routes, with this command:
php bin/console fos:js-routing:dump --format=json --target=public/assets/js/fos_js_routes.json
...
Related
i can't find the problem, i want to update the data to database, but i get Patch method is not support. i can't find the problem, i check from book refrence have not different, but in this case can't run for update.
this is my web.php
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::get('laravel/data', 'LaravelController#listData')->name('laravel.data');
Route::resource('laravel', 'LaravelController');
this my controller
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$laravel = Laravel::find($id);
$laravel = $request['id'];
$laravel->tanggal_pemasangan = $request['tanggal'];
$laravel->pitstop = $request['pitstop'];
$laravel->merk_ban = $request['merk_ban'];
$laravel->no_series_ban = $request['series_ban'];
$laravel->jenis_mobil = $request['jenis_mobil'];
$laravel->plat_nomor = $request['plat_mobil'];
$laravel->posisi_ban = $request['posisi_ban'];
$laravel->status = $request['status'];
$laravel->update();
}
my form.blade
<form class="form-horizontal" data-toggle="validator" method="POST">
#method('POST')
#csrf
and my ajax
$('#modal-form form').validator().on('submit', function(e){
if(!e.isDefaultPrevented()){
var id = $('#id').val();
if(save_method == "add") url = "{{ route('laravel.store') }}"
else url = "laravel/"+id;
$.ajax({
url : url,
type: "POST",
data: $('#modal-form form').serializa(),
success : function(data){
$('#modal-form form').modal('hide');
table.ajax.reload();
},
error: function(){
alert("Tidak dapat menyimpan data!");
}
});
return false;
}
});
function editForm(id){
save_method = "edit";
$('input[name = _method]').val('PATCH');
$('#modal-form form')[0].reset();
$.ajax({
url : "laravel/"+id+"/edit",
type: "GET",
dataType: "JSON",
success: function(data){
$('#modal-form').modal('show');
$('.modal-title').text('Edit Data');
$('#id').val(data.id);
$('#tanggal').val(data.tanggal_pemasangan);
$('#pitstop').val(data.pitstop);
$('#merk_ban').val(data.merk_ban);
$('#series_ban').val(data.no_series_ban);
$('#jenis_mobil').val(data.jenis_mobil);
$('#plat_mobil').val(data.plat_nomor);
$('#posisi_ban').val(data.posisi_ban);
$('#status').val(data.status);
},
error: function(){
alert("Tidak dapat menampilkan data!");
}
});
}
every time i want to do update, always give me error 405 this method is not support
Verify that your server supports the HTTP request: "PUT".
In your blade.php file add the #method('put') inside the form.
<form method="POST">
#method('PUT')
#csrf
...
</form>
Considering that resource type controllers generate the routes for you, perhaps you should use the php artisan route:list command to check the update route parameters.
Some examples of generated routes for resource type controllers, here.
Now maybe it can be a route hierarchy problem, try changing the order of your routes like this.
Route::resource('laravel', 'LaravelController');
Route::get('laravel/data', 'LaravelController#listData')->name('laravel.data');
Route::resource() #update method uses PATCH|PUT verb instead of POST
In your case you use POST method so the request will be not compatible, You need to use PATCH or PUT instead of POST in your type in ajax or in the form if necessary
I'm trying to make a tabs nav with a central block that contains a Symfony form.
When I click into a link in a tab navs, I reload the block with form and data.
But the issue is how to pass formView object from the first twig to the AJAX twig response view?
My controller
/**
* #Route("/change-tab/{tabId}", name="change_tab")
* #param Request $request
* #return Response
*/
public function changeTab(Request $request, $tabId): Response
{
$firstElement = $this->getDoctrine()->getRepository(Element::class)->findOneBy([
'cart'=>$tabId,
]);
return $this->render('partials/_bloc-cart.html.twig',[
'firstElement '=> $firstElement ,
//'form' => $request->getContent()
]);
}
My twig view
<div class="row p-2">
<div class="col-md-12 px-0" id="bloc-form">
{{ include('partials/_form.html.twig') }}
</div>
</div>
And the ajax JS :
$(document).on('click', '.linkToChange', function () {
$('.linkToChange.active').removeClass('active');
$(this).addClass('active');
let formPlan = $('#bloc-form').data('form');
$.ajax({
type: "POST",
data : formPlan,
url: "/ajax/change-tab/" + $(this).data('cart'),
success : function (datas) {
$('#bloc-form').html(datas);
}
});
});
You have different ways to do it, if you use the Form Component, you can do something like this:
public function changeTab(Request $request, $tabId): Response
{
$firstElement = $this->getDoctrine()->getRepository(Element::class)->findOneBy([
'cart'=>$tabId,
]);
$form = $this->createForm(ElementType::class, $firstElement);
$form->handleRequest($request);
// Save if form is submitted and valid
return $this->render('partials/_bloc-cart.html.twig',[
'firstElement '=> $firstElement ,
'form' => $form->createView()
]);
}
You can try:
/**
* #Route("/change-tab", name="change_tab", method="{POST}")
* #param Request $request
* #return Response
*/
public function changeTab(Request $request)
{
$tabId = $request->get('tab_id');
$firstElement = $this->getDoctrine()->getRepository(Element::class)->findOneBy([
'cart'=>$tabId,
]);
$html = $this->render('partials/_bloc-cart.html.twig',[
'firstElement '=> $firstElement ,
//'form' => $request->getContent()
]);
return $this->json(['html' => $html]);
}
Jquery:
$.ajax({
type: "POST",
data : formPlan,
url: "{{ url('change-tab') }}",
dataType: 'json',
data: {
'tab_id' : $(this).data('cart'),
}
success : function (data) {
$('#bloc-form').remove();
$('#bloc-form').html(data.html);
}
});
So I want to call a controller in symfony by passing in my route declared in routes.yaml with a jquery fetch function and I want to pass to variables from jquery to the controller. How can I do that ?
Here's my jquery. I call this route and I want to pass the two variable on top with it.
var longitudde = lonLat[0];
var latudde = lonLat[1];
fetch('/weather_request)
.then(function(response) {
return response.json();
}).then(function(json) {
// ...
});
To pass those variables to routes.yaml in Symfony:
weather_request:
path: /weather_request
controller: App\Controller\WeatherController::weather
methods: [get]
defaults:
longitude: longitude
latitude: latitude
To finaly pass them in the weather function in WeatherController:
public function weather($longitude, $latitude)
{
return $this->render('weather/index.html.twig', ['weatherInfos' => $this->weatherService->getWeather($longitude, $latitude)]);
}
So how can I pass the longitude and latitude from jquery fetch to the controller here ? I'm new to Symfony so I could be completely wrong.
I guess this can help you :
$.ajax({
url: '{{path('weather_request')}}',
type: 'GET',
data: {
longitude: lonLat[0],
latutide: lonLat[1],
},
success: function(response) {
//called when successful
},
error: function(e) {
//called when there is an error
//console.log(e.message);
}
});
In your controller :
use Symfony\Component\HttpFoundation\Request;
public function weather(Request $request)
{
if ($request->isXMLHttpRequest()) {
$longitude = $request->query->get('longitude');
$latutide = $request->query->get('latutide');
}
}
for me I use it like that:
In Js:
const obj = {
"longitudde":lonLat[0],
"latudde":lonLat[1]
}
fetch('/weather_request',
{
method:'POST',
headers: {
'Content-Type':'application/json'
},
body:JSON.stringify(obj)
}).then(resp => {
return resp.json();
}).then(res => {
console.log(res)
//...
})
}
In Controller route annotations,but you can use with Route.yaml:
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
/**
* #Route("/weather_request", methods={"POST"})
*
*/
public function weather(Request $request)
{
$data = json_decode($request->getContent());
$longitude = $data->longitudde;
$latitude = $data->latudde;
return $this->render('weather/index.html.twig',
[
'weatherInfos' => $this->weatherService
->getWeather($longitude, $latitude)
]);
}
I have an API that requires a string parameter. I want to take the query parameter to the controller and process there. I tried $ajax_data = Input::get('query'); but it didnt work. Searched the same question but cant find a decent answer. Current error is $ajax_data is empty.
My ajax request:
const sendAPIRequest = function (csrf, f) {
$.ajax({
async: false,
url: 'api/apitest',
method: 'get',
data:{
query:"select?facet=on&q=*:*&rows=1&json.facet={Categories:{type:terms,field:price,limit:3}}"
},
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer ' + tkid);
xhr.setRequestHeader('Accept', 'application/json');
xhr.setRequestHeader('X-CSRF-TOKEN', csrf.trim());
},
success: function (data) {
f(data);
},
error: function(xhr) {
//Do Something to handle error
}
});
};
My Controller API part:
public function apitest(){
$ajax_data = Input::get('query');
$user_type = UserAuthorizationHelper::user_authorization();
if ($user_type == Authorities::EDIT_ORGANISATIONS) {}
$query = new GuzzleHttp\Client();
try {
$response = $query->request('GET',SolrController::$url.$ajax_data);
} catch (GuzzleHttp\Exception\GuzzleException $e) {}
$data = $response->getBody()->getContents();
return response()->json(json_decode($data));
}
You are having a problem in this line:
$ajax_data = Input::get('query');
When you are making a request, Request object is sent with the data.
So, instead of Input replace it with Request's object, and you will get the desired output.
Something like this:
// Don't forget to import the Request's namespace
public function apitest(Request $request)
{
$ajax_data = $request->get('query');
// ... Rest of your code
}
I have an Ajax call that calls an action in the controller.
The Ajax call looks like this
$(document).on('click', '.editQuestionButton', function() {
var question_id = $(this).data('question');
console.log(question_id);
$.ajax({
type: "POST",
url: "/dashboard/form/AjaxEditQuestionForm/" + question_id + "",
success: function(data) {
$('#form-modal').html(data);
}
});
});
$(document).on('click', '.modal .fn-submit', function() {
$(this).closest('.modal').find('form').submit();
});
And this is the action.
/**
* #Route("/AjaxEditQuestionForm/{question}")
* #Template
* #ParamConverter("question", class="AppBundle:Question")
*/
public function ajaxEditQuestionFormAction(Request $request, $question)
{
$edit_question_form = $this->createForm(new AddQuestionType(), $question);
$edit_question_form->handleRequest($request);
if ($edit_question_form->isValid()) {
$em->flush();
return $this->redirectToRoute('app_form_create');
}
else{
die();
}
return array(
'question' => $question,
'editAjaxQuestionForm' => $edit_question_form->createView(),
);
}
The problem is that the action never returns the form but goes straight into checking if the form is valid.
I figure this has something to do with the $request but I'm not sure how to change this.
The action should first get the data from the Ajax call, return the form and if the form is submitted, check if the form is valid and flush the Question entity.
Any idea on how I should do this?