I'm developing an application in Laravel 5.0, from a view I make a petition to generate a PDF file and download, I'm using DomPDF, for that, I have a controller who manages everything related to the PDF, I have a function:
public function invoice()
{
$view = \View::make('invoice')->render();
$pdf = \App::make('dompdf.wrapper');
$pdf->loadHTML($view);
$pdf->download('invoice.pdf');
}
Then, in the view I made the request using AJAX, this is my code:
$("#dowload").click( function(){
$.ajax({
url: 'pdf',
type: "get",
data: {},
success: function(data){
window.location = 'pdf';
}
})
}
That is working with no errors, the thing is that it makes it very very slow, and there's no reason because the information displayed in the view invoice is static, nothing dynamic, no data processing, nothing and they're only 2 pages!
So, I was checking and I noticed that the slow command is $pdf->download('invoice.pdf'); so, what should I check?
Related
I'm trying to send some data from my view to my controller via ajax. How do I retrieve this data in my action?
I've tried jQuery's $.ajax and $.post methods, providing the url and data, but using $this->data, $this->request->data, $_POST, $_GET or $_REQUEST doesn't work (all return as empty arrays).
$.ajax({
url: "<?php echo Router::url( array("controller" => "Progression", "action" => "submit", $user['User']['id']) ); ?>",
type: 'post',
data: { name: "John" }
}).done( function(data) {
console.log(data);
});
function submit() {
$this->request->allowMethod('ajax');
$this->autoRender = false;
$data = array();
$data['answer'] = $this->request->data; // or any of $_POST, $_GET, etc.
return json_encode($data);
}
My console always keeps printing {"answer":[]}. I checked the network tab of my devtools and the data is successfully listed under Form data, yet I can't seem to get hold of the data in the action.
EDIT:
Thanks to Greg Schmidt I found out that my request indeed got redirected: first it gives me a 302, then it makes a new request without the post data and returns a 200. I just can't find what the critical difference is between the two requests (URLs look the same, no case difference or anything). Can anybody help me with that?
First request:
Second request:
Im new to ajax. I was trying to find the answer but was not lucky to find the corresponsing one. Basically I need to use an ajax to get some data and after that to put this data to the variable that later will be used as an attribute for the callback function with custom code.
This ajax part is just a method of myObject.
So, in the end I need this kind of functionality:
myObject.getData(url, callback(data) {
//my custom code of what I wanna do after ajax is complete
});
My code
/*
HERE COME SOME PROPERTIES AND OTHER METHODS WICH IS NOT THE CASE
*/
//This is where Im stuck
var getData = function getFromUrl($url) {
$.ajax({
type: 'get',
url: $url,
dataType: 'html',
success: function(html) {
$obj = html;//Im lost on this step!
},
});
};
P.S. Im trying to find an async way (without using async:false). Hope its possible
First I encountered many problems. My first problem was No Access-Control-Allow-Origin, most websites dont allow you to just scrap get their data for security reasons. Luckily someone already made a proxy: http://cors.io/ . Second problem is that you cant embed http on https, so I cant use jsfiddle to show you this working, it works on my local enviroment. After you get the raw html you have to parse it, you can do it with full regex, or you can power yourself with jquery like I'm doing on this example. What we're doing is checking stackoverflow.com and getting the amount of featured questions with .find(".bounty-indicator-tab").first().html(); But once you have the full html you can get any data you need.
var getData = function getFromUrl(url) {
$.ajax({
url: 'http://cors.io/?' + url,
crossDomain: true,
dataType: 'html',
success: function (html) {
var match = $(html).find(".bounty-indicator-tab").first().html();
console.log(match);
return match;
},
error: function(e) {
console.log('Error: '+e);
}
});
};
url = 'http://stackoverflow.com/';
data = getData(url);
//You cant use data yet because its working async
Attaching .done .fail and .always to ajax calls is now doable for me - it is "easy" when the script is at the bottom of the html page.
Now I want to create generalized ajax functions that I can use just by including a js file in the header. I've been successful with ajax functions that read data from server (.done always works). I'm having problems when I just write or update data to the server (no return of data). Here are the specifics-
Standard ajax add/update call that always works - in script tags at bottom of page.
$.ajax({
type: 'POST',
url: 'supdateajaxfunctiontestbackend.php',
data: {localid: localid,
firstname: firstname,
lastname: lastname}
}).done(function(){ alert('Done with Add/Update!'); });
If I create a function at the bottom of the page, or add the function to a js file, this add/update always works.
function generalWriteAjax(filetocall, datatosend) {
$.ajax({
type: 'POST',
url: filetocall,
data: datatosend
}).done(function(){ alert('Done with Add/Update!'); });
}
I would like to detach the .done from the function, and call the .done when attached to a separate function/object. The following code works fine WHEN THERE IS DATA RETURNED FROM THE SERVER. (a separate generalReadAjax function that asks for server data). The done is attached to an object that is returned from the server (This concept I found here on Stackoverflow).
backenddata = generalReadAjax('readtesttablebackend.php');
displayData(backenddata);
backenddata.done(function(){ alert("Done with read!"); });
});
I have tried all of the following with the WRITE/UPDATE only function, and none of them work.
generalWriteAjax(filetocall4update, datatosend4update).done(function(){ alert('Done function'); });
generalWriteAjax(filetocall4update, datatosend4update).when(function(){ alert('Done function'); });
generalWriteAjax(filetocall4update, datatosend4update).then(function(){ alert('Done function'); });
generalWriteAjax(filetocall4update, datatosend4update);
createdonealert = generalWriteAjax(filetocall4update, datatosend4update);
createdonealert.done(function(){ alert('Done function'); });
createdonealert.when(function(){ alert('Done function'); });
createdonealert.then(function(){ alert('Done function'); });
So obviously, there is a difference in the way the promise is handled between a "go get me data" and "here is data, please store it".
I even put an echo "Done"; at the bottom of the update php file just to return something, and still no luck.
I've searched this site and google with combinations of:
ajax .done attach add update not working promise
and have found nothing that deals with my specific example.
Can someone give me some guidance?
I thank you in advance.
Well, no one has responded, and I've learned a bit by hacking on this for the last day. Here are some things I THINK I've learned:
If you create a general callable function using ajax, it does not act the same as an "inline" ajax - you do not get the same callback actions as you do when the ajax code is at the bottom of an HTML page between script tags.
If you return something from the server, the ajax function acts similarly to when it is between script tags.
If you DO NOT return data from the server, the ajax function does NOT act the same as when it is inline.
So what I've done is on all php files that are "write/update" only (no data returned), I add a little code to the bottom of each php file that returns a small amount of json "junk". With this "junk" the ajax function acts like a regular ajax call between script tags at the bottom of the page.
It's a kludge, but it works. Here is the code at the bottom of a read/update php file that normally would NOT return anything. It now returns a json array regarding "John":
$json = array('firstname' => 'John');
echo json_encode($json);
Here is the function in the attached js file:
function generalWriteAjax( filetocall, datatosend ) {
return $.ajax({
type: 'POST',
url: filetocall,
data: datatosend,
dataType: 'json'
});
}
Here is the code on the page that calls the .js function:
$("#clicktoupdate").click(function(e) {
var localid = $('#idnumber').val();
var firstname = $('#updatefirstname').val();
var lastname = $('#updatelastname').val();
var filetocall4update = 'supdateajaxfunctiontestbackend.php';
var datatosend4update = {localid: localid, firstname: firstname, lastname: lastname};
generalWriteAjax(filetocall4update, datatosend4update).done(function(){ alert('Done inline'); });
});//end of update click
I wish I understood the details, but this is an empiric solution that works.
Comments from the experts would be nice.
Thanks for looking!
I need to make an AJAX call from a page, sending some JavaScript data to a PHP file, which creates a file based on that data. I then want this file to be downloaded by the user.
So is it an option, to make a force download of a file created by PHP (specifically PHPExcel in my case) via an AJAX request?
The code shown below does not yet send any JavaScript data, but does generate a file.
This is my PHP script, which creates a file using PHPExcel:
public function renderTasksToExcel($tasksData){
$objPHPExcel = new PHPExcel();
// Set properties
$objPHPExcel->getProperties()->setCreator("TRW");
// ...
// Add some data
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->SetCellValue('A1', 'Hello');
// ...
// Rename sheet
$objPHPExcel->getActiveSheet()->setTitle('Simple');
// Save Excel 2007 file
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$file = '/export.' . date('Y-m-d-H-i-s').'.xlsx';
$objWriter->save($file);
// hotovo
return $this->sendResponse(new FileResponse($file));
}
And this is AJAX call:
$.ajax({
type: "POST",
url: {plink Tasks:tasksToExcel},
data: ajaxData,
success:function(data){
$('#download').html(data);
}
})
same with mine. but i already solve this problem,try this:
use this in your php:
$objWriter->save('export/FileName.xls');
and use this in your ajax call:
$.ajax({
type: "POST",
url: {plink Tasks:tasksToExcel},
data: ajaxData,
success:function(data){
$('#download').html(data);
var zz=document.createElement('a');
var data_type = 'data:application/vnd.ms-excel';
zz.href ='htp://localhost/bengkel/backend/export/FileName.xls';
zz.download='FileName'+'.xls';
zz.click();
}
})
simple concept,ajax cant download. then,save *xls file,and then download that file with JS.
sorry im junior programmer and my bad english..
hope this help you,good luck :)
I'm trying to use Ajax in CakePHP, and not really getting anywhere!
I have a page with a series of buttons - clicking one of these should show specific content on the current page. It's important that the page doesn't reload, because it'll be displaying a movie, and I don't want the movie to reset.
There are a few different buttons with different content for each; this content is potentially quite large, so I don't want to have to load it in until it's needed.
Normally I would do this via jQuery, but I can't get it to work in CakePHP.
So far I have:
In the view, the button control is like this:
$this->Html->link($this->Html->image('FilmViewer/notes_link.png', array('alt' => __('LinkNotes', true), 'onclick' => 'showNotebook("filmNotebook");')), array(), array('escape' => false));
Below this there is a div called "filmNotebook" which is where I'd like the new content to show.
In my functions.js file (in webroot/scripts) I have this function:
function showNotebook(divId) {
// Find div to load content to
var bookDiv = document.getElementById(divId);
if(!bookDiv) return false;
$.ajax({
url: "ajax/getgrammar",
type: "POST",
success: function(data) {
bookDiv.innerHTML = data;
}
});
return true;
}
In order to generate plain content which would get shown in the div, I set the following in routes.php:
Router::connect('/ajax/getgrammar', array('controller' => 'films', 'action' => 'getgrammar'));
In films_controller.php, the function getgrammar is:
function getgrammar() {
$this->layout = 'ajax';
$this->render('ajax');
}
The layout file just has:
and currently the view ajax.ctp is just:
<div id="grammarBook">
Here's the result
</div>
The problem is that when I click the button, I get the default layout (so it's like a page appears within my page), with the films index page in it. It's as if it's not finding the correct action in films_controller.php
I've done everything suggested in the CakePHP manual (http://book.cakephp.org/view/1594/Using-a-specific-Javascript-engine).
What am I doing wrong? I'm open to suggestions of better ways to do this, but I'd also like to know how the Ajax should work, for future reference.
everything you show seems fine. Double check that the ajax layout is there, because if it's not there, the default layout will be used. Use firebug and log function in cake to check if things go as you plan.
A few more suggestions: why do you need to POST to 'ajax/getgrammar' then redirect it to 'films/getgrammar'? And then render ajax.ctp view? It seems redundant to me. You can make the ajax call to 'films/getgrammar', and you don't need the Router rule. You can change ajax.ctp to getgrammar.ctp, and you won't need $this->render('ajax');
this is ajax call
$(function() {
$( "#element", this ).keyup(function( event ) {
if( $(this).val().length >= 4 ) {
$.ajax({
url: '/clients/index/' + escape( $(this).val() ),
cache: false,
type: 'GET',
dataType: 'HTML',
success: function (clients) {
$('#clients').html(clients);
}
});
}
});
});
This the action called by ajax
public function index($searchterm=NULL) {
if ( $this->RequestHandler->isAjax() ) {
$clients=$this->Client->find('list', array(
'conditions'=>array('LOWER(Client.lname) LIKE \''.$searchterm.'%\''),
'limit'=>500
));
$this->set('clients', $clients);
}
}
This is a function I use to submit forms in cakephp 3.x it uses sweet alerts but that can be changed to a normal alert. It's very variable simply put an action in your controller to catch the form submission. Also the location reload will reload the data to give the user immediate feedback. That can be taken out.
$('#myForm').submit(function(e) {
// Catch form submit
e.preventDefault();
$form = $(this);
// console.log($form);
// Get form data
$form_data = $form.serialize();
$form_action = $form.attr('action') + '.json';
// Do ajax post to cake add function instead
$.ajax({
type : "PUT",
url : $form_action,
data : $form_data,
success: function(data) {
swal({
title: "Updated!",
text: "Your entity was updated successfully",
type: "success"
},
function(){
location.reload(true);
});
}
});
});