ajax routing with symfony - ajax

I am using symfony and twig and trying to route to a controller function that exists, using ajax. The route I am trying to get to seems to be appended to the current route (page) that is calling the ajax. What is causing this and what am I doing wrong? I am intermediate at this. Thanks in advance for your efforts.
The ajax looks like;
$.ajax({url: "{{ path('material-stock_check') }}/" + quoteRing.materialId + "/" + quoteRing.gaugeId + "/" + decimal, success: function (results) {
if (results.length === 0) {
quoteRing.findStripWidthAlternates();
}
}});
and the controller looks like
/**
* Check if the strip width is in the Inventory
* #Route("/check/{materialId}/{gaugeId}/{decimal}", defaults={"materialId" = 0, "gaugeId" = 0, "decimal" = 0}, name="material-stock_check")
* #Method("GET")
*/
public function checkStripWidthAction (Request $request, $materialId, $gaugeId, $decimal)
{
$em = $this->getDoctrine()->getManager();
$materialStocks = $em->getRepository('UniflyteBundle:MaterialStock')->findAllByParams(['widthDecimal' => $decimal, 'materialId' => $materialId, 'gaugeId' => $gaugeId]);
if ($request->isXmlHttpRequest()) {
if (null === $materialStocks) {
return new JsonResponse('failure');
}
$results = [];
foreach ($materialStocks as $result) {
$results[] = [
'gaugeId' => $result->getGauge()->getId(),
'materialId' => $result->getMaterial()->getId()
];
}
return new JsonResponse($results);
}
}
When the ajax is called I am getting
No route found for "GET /uniflyte/quote-ring/new/%7B%7B%20path('material-stock_check')%20%7D%7D/93/347/3.45" (from "http://localhost:8088/uniflyte/quote-ring/new/rolled-ring")
The ajax route looks appended to the existing route. What am I doing wrong?

It seems {{ path(...) }} is not being evaluated by twig as #Omar Alves told.
try this, declare a variable in your twig file
<script>
var url = '{{ path("material-stock_check") }}';
</script>
and then use it

Have you declare the path in route file

Related

Codeigniter 4 dropzone upload after redirect url

I am uploading files with Codeigniter 4. I want the page to refresh after loading but my code is not working. Here is the controller I use.
At the bottom I have the code for the redirect but this code is not working.
<?php namespace App\Controllers;
use App\Models\Hizmetmodels;
use App\Models\Dosyamodels;
class Dosyacontroller extends BaseController
{
protected $helpers = ['form' ,'url'];
protected $Dosyamodels;
public function index($sap = null)
{
$Hizmetmodels= new Hizmetmodels();
$data['hizmetsat'] = $Hizmetmodels->where('sap', $sap)->first();
$Dosyamodels= new Dosyamodels();
$where = "sap='$sap'";
$data['dosya'] = $Dosyamodels->orderBy('id', 'ASC')->where($where)->findAll();
return view('Admin/Dosyalar/index', $data);
}
public function form()
{
$sap = $this->request->getPost('sap');
$Dosyamodels= new Dosyamodels();
helper(['text','inflector']);
$file = $this->request->getFile('file');
$size = $file->getSize();
$kilobytes = $file->getSizeByUnit('kb');
$path = 'public/uploads';
$name = convert_accented_characters(underscore($file->getName()));
$newname = "$sap-$name";
$file->move(ROOTPATH . $path, $newname);
$ext = $file->getClientExtension();
$data = [
'adi' => $newname,
'yol' => $path . '/' . $name,
'sap' => $sap,
'boyut' => $kilobytes,
'uzt' => $ext,
];
$save = $Dosyamodels->insert($data);
return redirect()->to('/Dosyalar/index/'. $sap)->with('success', 'Tebrikler! <br> Dosyalar başarı ile yüklendi.');
}
}
The issue could be with the redirect URL that you are trying to redirect to. In this case, the URL is /Dosyalar/index/'. $sap which is missing the base URL. To resolve the issue, you can use the base URL in the redirect URL, like this:
return redirect()->to(base_url('Dosyalar/index/'. $sap))->with('success', 'Tebrikler! <br> Dosyalar başarı ile yüklendi.');
Try to change
this.on('queuecomplete', function (file) { location.reload(); }); to this.on('success', function (file, responseText) { location.reload(); });
With dropzone the document is uploaded to the correct folder. saved to the database. no problems so far. the only problem is i can't refresh the page no matter what i do after it loads.here is my java script code:
$(function() {
Dropzone.options.dropzoneform = {
paramName: 'file',
maxFilesize: 2, // MB
maxFiles: 5,
init: function () {
this.on('queuecomplete', function (file) {
location.reload();
});
}
}
});

How to pass id from ajax to controller - Laravel & Ajax

Currently, i am on the show page that is i am running the function show as in my controller so my url is showing like dashboard/1/people in the url address bar. Now, when i click on a person, it routes to a different page and that is where getPeople is called.
How can i get the id of the person i clicked which is 1 from the ajax request in the scripts and pass to my controller?
PS: At the moment, i have hardcoded 1 in the ajax request but i want it to be dynamic please
How do i get this done?
Script
datatable = $('#table').DataTable({
"ajax": "{{ route('dashboard/1/people') }}",
"columns": [
{data: 'check', name: 'check'},
],
Controller
public function show($id)
{
$class = Class::whereId($id)->first();
return view('show');
}
public function getPeople($id)
{
$get_id = $id;
$class = Class::whereId($get_id)->first();
$people = $class->peoples()->get();
return Datatables::of($people)->addColumn('action', function ($ppl) {
//return
})->make(true);
}
This should work:
In your getPeople method store the id in a session variable:
public function getPeople($id)
{
$get_id = $id;
//using session helper method
session(['show_id' => $id]);
$class = Class::whereId($get_id)->first();
$people = $class->peoples()->get();
return Datatables::of($people)->addColumn('action', function ($ppl) {
//return
})->make(true);
}
and then access it in you ajax code:
datatable = $('#table').DataTable({
"ajax": "{{ route('dashboard/'.session('show_id').'/people') }}",
"columns": [
{data: 'check', name: 'check'},
],
DataTable ajax allows yo to pass extra parameters in object format just like this:
datatable = $('#table').DataTable({
"ajax": {
"type": "GET",
data:{id: my_id_var},
"url": "my_route"
}
}
And in your function just get the Request var
public function getPeople(Request $request){
$get_id = $request->id;
$class = Class::whereId($get_id)->first();
$people = $class->peoples()->get();
return Datatables::of($people)->addColumn('action', function ($ppl) {
//return
})->make(true);
}
More Information in Sorce Page

Bootstrap Treeview links with laravel 5.4

I am using laravel 5.4 and Bootstrap Treeview.
I have enabled the node text as link:
$('#treeview').treeview({data: data, enableLinks: true});
and in the href field of each node in the Json array I have the laravel route
"{{ route('opciones.create') }}"
Here is where I create the tree (I encode this to Json format in another part of my code)
function buildTree(array $elements, $parentId) {
$branch = array();
foreach ($elements as $element) {
$element['text'] = $element['descripcion'];
$element['href'] = "{{ route('opciones.create') }}";
if ($element['padre'] == $parentId){
$nodes = buildTree($elements, $element['id']);
if ($nodes) {
$element['nodes'] = $nodes;
}
$branch[] = $element;
}
}
return $branch;
}
This is the function in the controller that I need to call which returns a view (a blade file)
public function create()
{ $opcionespadre = Opcion::where('tipo', '=', 'SUBMENU')->get();
return view($this->path.'.create', compact('opcionespadre'));
}
I am using this especific function just to test the tree nodes links, I have other functions in the controller where I need to send a parameter, but first I need to make the link goes somewhere.
When I click on the text of the node, it says that the page I am looking for doesn't exist.
This is what appears in the browser bar:
http://127.0.0.1:8000/{{route('opciones.create')}}
What should I do?
The problem is in this line :
$element['href'] = "{{ route('opciones.create') }}";
Do it like this :
function buildTree(array $elements, $parentId) {
$branch = array();
foreach ($elements as $element) {
$element['text'] = $element['descripcion'];
$element['href'] = route('opciones.create');
if ($element['padre'] == $parentId){
$nodes = buildTree($elements, $element['id']);
if ($nodes) {
$element['nodes'] = $nodes;
}
$branch[] = $element;
}
}
return $branch;
}

How to update pagination template of knppaginatorbundle after ajax query

Im using knppaginatorbundle to create pagination. I have created a jquery code to select data with ajax.
Everything is okay when I click on the page number , the content is loaded with the correct data.
But I have a problem , The pagination template is not changed after after ajax query:
previous and next links values must changed
current page must be disabled
and other changes that need to be done ...
How can I do this ?
public function listAction($page, Request $request)
{
$em = $this->getDoctrine()->getManager();
$paginator = $this->get('knp_paginator');
$qb = $em->getRepository('AppBundle:Travel')->getListTravels();
$pagination = $paginator->paginate(
$qb, $request->query->get('page', $page), 3
);
//ajax request
if ($request->isXmlHttpRequest()) {
$view = $this->renderView('#App/Frontend/Travel/list.html.twig', array(
'pagination' => $pagination
));
$response = new JsonResponse(array('ok' => $view));
return $response;
}
return $this->render('AppBundle:Frontend/Travel:travel-list-view.html.twig', array(
'pagination' => $pagination,
));
}
I have added an attr data-target to pagination template like this:
<a data-target="{{ page }}" href="{{ path(route, query|merge({(pageParameterName): page})) }}">{{ page }}</a>
View
//.....
<div id="mydiv">
// list.html.twig contains the loop
{% include "AppBundle:Frontend/Travel:list.html.twig" %}
</div>
<br>
{{ knp_pagination_render(pagination) }}
//....
<script>
$(document).ready(function () {
$("ul#pagination a").click(function (e) {
e.preventDefault();
var dataTarget = $(this).attr("data-target"); // each <a> has attr named data-target contains num of page
var hash;
hash = 'page=' + dataTarget;
window.location.hash = hash;
if (window.location.hash != "") {
$.ajax({
type: 'get',
dataType: 'json',
url: Routing.generate('frontend_travels_list', {'page': dataTarget}),
success: function (msg) {
if (msg["ok"] === undefined) {
alert('error');
} else {
$("#mydiv").html(msg["ok"]);
}
}
});
}
});
});
</script>
Route
frontend_travels_list:
path: /travels/{page}
defaults: { _controller: AppBundle:TravelFrontend:list, page: 1 }
options:
expose: true
If someone else needs a solution there 2 ways.
You can use that bundle https://github.com/nacholibre/knppaginator-ajax
You should build new pagination string in controller and send it in JsonResponse as a param. Then replace pagination element in DOM via jQuery on success.
For SF 4.3 you can use my approach
To be able to inject the Processor in controller you have to add alias for autowiring in services.yaml
Knp\Bundle\PaginatorBundle\Helper\Processor: '#knp_paginator.helper.processor'
Based on injected PaginatorInterface you should build your $pagination object (PaginationInterface)
Use Processor to build the context array for Twig.
$paginationContext = $processor->render($pagination);
render method expects SlidingPagination object, but got $pagination which is PaginationInterface - however it seems that is ok
Get the Twig and render a final string
$twig = $this->get('twig');
$paginationString = $twig->render($pagination->getTemplate(), $paginationContext);
Example of working controller
if ($request->isXmlHttpRequest()) {
$view = $this->render('#App/Frontend/Travel/list.html.twig', array(
'pagination' => $pagination
))->getContent();
$paginationContext = $processor->render($pagination);
$twig = $this->get('twig');
$paginationHtml = $twig->render($pagination->getTemplate(), $paginationContext);
$response = new JsonResponse(['view' => $view, 'paginationHtml' => $paginationHtml]);
return $response;
}
then in jQuery
success: function (msg) {
if (msg["ok"] === undefined) {
alert('error');
} else {
$("#mydiv").html(msg["view"]);
$("#myDivContainingPagination").html(msg["paginationHtml"])
}
}

Unable to get_the_content(); of a post in Wordpress via AJAX

I'm trying to ajaxify my Wordpress theme and I use the ajax-in-WordPress method and I'm now trying get_the_content of post via functions.php. Using jQuery, when I do alert(data) I get the 'title' echo but not the content of the existing post I want (returns 0).
What am I doing wrong?
The jQuery part
$('.ajaxed,.ajaxed a,.menu-item-home a,.menu-item-object-page a').live('click', function(event) {
event.preventDefault();
var link = $(this).attr('href');
var toRemove = MySettings.url;
var rewritepath = link.replace(toRemove,'');
var handler = function(data) {
$('title').html($('title', data).html());
$('#primary').html($('#primary', data).html());
$('#primary').hide().fadeIn('slow');
$.address.title(/>([^<]*)<\/title/.exec(data)[1]);
};
$.post(ajax_object.ajaxurl, {
action: 'ajax_action',
post_id: $(this).find('input.post_id').attr('value')
},function(data) {
alert(data.post_title);
alert(data.post_content);
});
/*$.ajax({
url: link,
error: function(XMLHttpRequest, textStatus, errorThrown) {
handler(XMLHttpRequest.responseText);
},
success: function(data, textStatus, XMLHttpRequest) {
handler(data, function(){
});
}
});*/
$.address.state(MySettings.path).crawlable(true).value(rewritepath);
return false;
});
The functions.php part
<?php
function javascripts() {
if( !is_admin()){
$blogurl = get_bloginfo('url');
$thumbnail_width = get_option('thumbnail_size_w');
$thumbnail_height = get_option('thumbnail_size_h');
$path = parse_url(get_bloginfo('siteurl'), PHP_URL_PATH);
$url = 'http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js';
wp_deregister_script('jquery');
if (get_transient('google_jquery') == true) {
wp_register_script('jquery', $url, array(), null, true);
}
else {
$resp = wp_remote_head($url);
if (!is_wp_error($resp) && 200 == $resp['response']['code']) {
set_transient('google_jquery', true, 60 * 5);
wp_register_script('jquery', $url, array(), null, true);
}
else {
set_transient('google_jquery', false, 60 * 5);
$url = get_bloginfo('wpurl') . '/wp-includes/js/jquery/jquery.js';
wp_register_script('jquery', $url, array(), '1.7', true);
}
}
wp_enqueue_script('plugins.js', get_bloginfo('template_directory') . "/js/plugins.js" , array('jquery'));
wp_enqueue_script('ajax-script', get_bloginfo('template_directory') . "/js/scripts.js", array('jquery'));
wp_localize_script('ajax-script', 'ajax_object', array('ajaxurl' => admin_url( 'admin-ajax.php' )));
wp_localize_script('jquery', 'MySettings', array('width' => $thumbnail_width,'height' => $thumbnail_height,'url' => $blogurl,'path' => $path));
}
}
add_action('wp_enqueue_scripts', 'javascripts');
add_action('wp_ajax_ajax_action', 'ajax_action_stuff'); // ajax for logged in users
add_action('wp_ajax_nopriv_ajax_action', 'ajax_action_stuff'); // ajax for not logged in users
function ajax_action_stuff() {
$post_id = $_POST['post_id'];
update_post_meta($post_id, 'post_key', 'meta_value'); //not sure why you need this
$post_data = get_post($post_id);
echo json_encode($post_data);
}
?>
What am I doing wrong? Thanks
Without seeing the entire scope of your code, it appears that you might be calling get_the_content() outside of the context of The Loop. If so, the function doesn't understand which post you'd like to retrieve the content for. Try organizing the function this way:
function ajax_action_stuff() {
$post_id = $_POST['post_id'];
update_post_meta($post_id, 'post_key', 'meta_value'); //not sure why you need this
$post_data = get_post($post_id);
$title = $post_data->post_title;
$content = $post_data->post_content;
echo $title;
echo $content;
}
Here we've used get_post() to return an object with all of the post data.
The jQuery function you've created...
function(data) {
alert(data);
});
... should essentially contain a string in the data object that contains your title and content.
Here's a recommendation though, on how you can return your data in a more organized fashion, if you like.
The 'data' object (which is what you've echoed in the php function ajax_action_stuff()) is just a string value. The problem though is that the data isn't really structured in a way for jQuery to fully understand and use to its full potential. If you change your php function to return a JSON object though, then you can use all your properties in jQuery individually. I'll show you how...
function ajax_action_stuff() {
$post_id = $_POST['post_id'];
update_post_meta($post_id, 'post_key', 'meta_value'); //not sure why you need this
$post_data = get_post($post_id);
echo json_encode($post_data);
}
Then in the jQuery function you have access to each property like this:
$.post(ajax_object.ajaxurl, {
action: 'ajax_action',
post_id: $(this).find('input.post_id').attr('value')
},function(data) {
alert(data.post_title);
alert(data.post_content);
});
Have a look at the get_post() function to see all of the properties that you have available to you.
You aren't telling get_the_content() which post to retrieve the content for. Internally, this function checks for the global $post object and filters the content of that object.
So change your ajax function to something like this:
function ajax_action_stuff() {
global $post;
$post_id = $_POST[ 'post_id' ];
update_post_meta( $post_id, 'post_key', 'meta_value' );
$post = get_post( $post_id );
$title = 'title';
$content = get_the_content();
echo $title;
echo $content;
}
This will use the ID you've passed in to query the database for a specific post and populate the global $post object. Now, get_the_content() and even get_the_title() should function normally.

Resources