How to download a pdf using ajax and TCPDF - php

My code works fine when I run the php script without ajax as a GET request. I get prompted to download the rendered pdf and all is well. However, I need to use ajax because I need to send more info from an html page to the php script than can be handled in a GET request.
What do I need to put into my ajax to make this work?
Thanks
js
function makePDF()
{
var x;
if(window.event) // IE8 and earlier
{
x=event.keyCode;
}
else if(event.which) // IE9/Firefox/Chrome/Opera/Safari
{
x=event.which;
}
keychar=String.fromCharCode(x);
alert(keychar);
if (keychar == 'p' || keychar == 'P')
{
var charSheetHTML = characterSheet.innerHTML;
$.ajax({
url: 'pdf.php',
data: {'charactersheet': charSheetHTML,},
type: 'post',
success: function (data) {**WHAT_DO_I_PUT_HERE??**},
error: function (data) { alert("error\n" + data.toString()); }
});
}
}
pdf.php
<?php
include_once( "bxcharacter/PDFChar.php.inc" );
PDFChar();
?>
PDFChar.hph.inc
<?php
require_once('./tcpdf/tcpdf.php');
function PDFChar(){
$pdf = new TCPDF();
$pdf->AddPage('P');
$pdf->writeHTML($_POST['charactersheet']);
$pdf->Output("character.pdf", 'D');
}
?>

This is not an ajax solution, but you can send your data with this way and if no error occurs, your page will not change.
Create a form element with inputs hidden which contains your data you want to send:
example format:
<form id="myForm" method="GET" action="pdf.php">
<input type="hidden" name="data1" type="hidden" value="your JSON.stringify() data">
</form>
js code (call these where your ajax request is):
var myForm = '<form id="myForm" method="GET" action="pdf.php">';
myForm += '<input type="hidden" name="data1" type="hidden" value="JSON.stringify() data">';
myForm += '</form>';
$("body").append(myForm); // temporarily appending
$("#myData-form").submit(); // submitting form with data
$("#myData-form").remove(); // remove form after submit
And as you said, force download will force file to download and page will remain same. However, if an error occurs, your page will change of course.
I don't know whether this is an effective way or not but in my case, this does the trick.

Old question, but I was trying to do something similar with Laravel PDF extension, and stumbled across this question. I did successfully do this asynchronously with the help of a nice blog post
https://nehalist.io/downloading-files-from-post-requests/
https://github.com/nehalist/download-post-requests
The using the form method, like the previous answer works fine too, but maybe this will help anyone else trying to achieve this with AJAX. The author's XMLHttpRequest method worked great for me!
The code that worked for me (almost verbatim from the blog post) ->
document.getElementById('exportpdf').addEventListener('click', function () {
var request = new XMLHttpRequest();
request.open('POST', '/your/post/endpoint/here', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.responseType = 'blob';
request.onload = function() {
if(request.status === 200) {
var disposition = request.getResponseHeader('content-disposition');
var matches = /"([^"]*)"/.exec(disposition);
var filename = (matches != null && matches[1] ? matches[1] : 'file.pdf');
var blob = new Blob([request.response], { type: 'application/pdf' });
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
};
I tried to get it to work with jQuery AJAX but failed, so I went with XMLHttpRequest. With jQuery, The download would work, but the content was always empty. I tried to do something like in this post -
https://keyangxiang.com/2017/09/01/HTML5-XHR-download-binary-content-as-Blob/
$.ajax does not support either arraybuffer or blob as its dataType. Thus we need write a beforeSend handler:
//setup ajax
$.ajaxSetup({
beforeSend:function(jqXHR,settings){
if (settings.dataType === 'binary'){
settings.xhr().responseType='arraybuffer';
settings.processData=false;
}
}
})
//use ajax now
$.ajax({
url:url,
dataType:"binary",
success:function(data){
console.log(data); //ArrayBuffer
console.log(new Blob([data])) // Blob
}
})
But never got it to work. Maybe someone smarter can figure out the jQuery method :)

Related

sending array from javascript through url in php page but

Rooms are an array
window.location = "booking_status.php?array="+ JSON.stringify(rooms);
sending from javascript to php page
on php page url show full array value which are store in array in page address bar url
like that
http://localhost/zalawadi/booking_status.php?array=[{%22id%22:10,%22rate%22:100}]
I want to prevent this data which show in url %22id%22:10,%22rate%22:100
I am decoding on php page any other way to send array data from javascript to php page
The only way to send data to another page without showing them in the url is to use POST.
Basically, you can put your data into an invisible form input :
<form method="post" id="form" action="booking_status.php">
<input name="array" id="array" type="hidden" value="" />
</form>
Send
<script type="text/javascript">
function sendForm(){
document.getElementById('array').value = JSON.stringify(rooms);
document.getElementById('form').submit(); //fixed syntax
}
</script>
You can use a hidden form and the post method. Then you would use $_POST instead of $_GET.
<form action="script.php" onsubmit="this.firstChild.value=JSON.stringify(value);">
<input type="hidden" value="" />
Link text
</form>
You can use a POST request, however this would require generating and submitting a form:
// assuming `rooms` already defined
var frm = document.createElement('form'), inp = document.createElement('input');
frm.action = "booking_status.php";
frm.method = "post";
inp.type = "hidden";
inp.name = "array";
inp.value = JSON.stringify(rooms);
frm.appendChild(inp);
document.body.appendChild(frm);
frm.submit();
Why not just POST the data instead then?
For example, with jQuery:
$.ajax({
type: "POST",
url: "booking_status.php",
data: JSON.stringify(rooms),
success: // add success function here!
});
The advantage is you're not passing some horrific URL. As an added bonus, this example is also asynchronous, so the user doesn't see any refresh in their browser.
Non-Framework Version
If you don't wish to use jQuery, you can do this with pure Javascript, using the XMLHttpRequest object, like so:
var url = "get_data.php";
var param = JSON.stringify(rooms);
var http = new XMLHttpRequest();
http.open("POST", url, true);
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
// Request has gone well. Add something here.
}
}
http.send(param);

Ajax/ Jquery in Zend framework

I’m using Zend framework (php) and I’m trying to submit a from using ajax/jquery.
Here’s the .phtml:
<form id="find">
<input type="text" name="name">
<input type="submit" id="submit" value="Submit">
</form>
Here’s the ajax/jquery part:
$(document).ready(function() {
$("#submit").click(function(){
$.ajax({
type:'POST',
url: "<?php echo SITE_URL;?>Training/test",
data:$('#find').val(),
success: function(response) {
alert (response);
}
});
});
});
Here, “Training” is the controller and “test” is the action inside the controller. The action has just 1 line of code which is echo “hello”. After the user types a number in the box and clicks on “submit”, the control has to go to the controller thus displaying “hello” on success. However, nothing happens when I click on it. Please help me. Thanks in advance.
You didn't name parametr in Ajax call
data:$('#find').val(),
change it to
data:{'param': $('#find').val()},
About Zend it doesn't matter if it's zend or not. You can handle request just providing proper URL. You can access param value in Zend via $this->getParam('param') method.
Also you don't prevent default submit action. Change your function to:
$("#submit").click(function(ev){
ev.preventDefault();
or use in the end of function return false;
I did not test your jQuery. But note you need the instruction event.preventDefault to ensure you haven't the normal form submit action.
The main problem is at your zend Controller because you need a
special response. I suppose you have a controller to perform the request logics. I'll name it AjaxController and I'll name the action ajaxrecuestAction to illustrate how to send a proper response.
<?php
// Filename: yourProject/module/ModuleName/src/Controller/AjaxController.php
namespace ModuleName\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class AjaxController extends AbstractActionController {
public function ajaxrecuestAction(){
// This function is called by zend to procces your ayax request
// you must test if it's an xmlHttpRequest
$request = $this->getRequest();
$is_xmlHttpRequest = ($request->isXmlHttpRequest()) ? 1 : 0;
if(!$is_xmlHttpRequest){
// If not you must return a normal page, a message page
// perhaps a forgiven message page, etc. It depends on your site
// logics
}else{
// The solution's KEY
// You must disable the zend's normal output
$viewmodel = new ViewModel();
$viewmodel->setTerminal($is_xmlhttprequest);
// Proccess the input and prepare your output
$output = CallTheLogicsToPrepareIt($request->getContent());
// send your response
$response = $this->getResponse();
$response->setContent($output);
return $response;
}
}
**EDIT: Just noted that, in your HTML, you didn't give an ID attribute to the "find" field. Therefore $('#find').val() will give you an error, something like "cannot find method val() of undefined. Add the id=find tag to your and it should work.
** Other Edit: Sorry about the confusion. Your form has id=find but what you want to send to the server (I believe), is the value of the fields. So give an ID=name to your input then use:
var data = {find: $('#name').val()};
You should start by using your console to see if the event is triggered. Something like:
<script>
$(document).ready(function() {
$("#submit").click(function(e){
e.preventDefault ? e.preventDefault() : e.returnValue = false; //This will prevent the regular submit
console.log('Hello');
});
});
</script>
(You do use Fire bug or the Chrome dev tools, right) ? If not, look at the end of this post.
If you can see the Hello in your console, you're on the right path. Then try to set your url in a variable and try to check it in your console:
<script>
var url = "<?php echo SITE_URL;?>Training/test";
$(document).ready(function() {
$("#submit").click(function(e){
e.preventDefault ? e.preventDefault() : e.returnValue = false; //This will prevent the regular submit
console.log(url);
});
});
</script>
Then you should see the url in the console, meaning you're still doing good.
If that works, try to set the data and check the output in the same way:
<script>
var url = "<?php echo SITE_URL;?>Training/test";
var data = {
find: $('#find').val()
};
$(document).ready(function() {
$("#submit").click(function(e){
e.preventDefault ? e.preventDefault() : e.returnValue = false; //This will prevent the regular submit
console.log(data);
});
});
</script>
Hoping everything still works (you saw the data), then try the actual full code and see if you have an error or something. Also, be sure to include an error function to your ajax call so you will have a response if something went wrong on the server.
<script>
var url = "<?php echo SITE_URL;?>Training/test";
$(document).ready(function() {
$("#submit").click(function(e){
e.preventDefault ? e.preventDefault() : e.returnValue = false; //This will prevent the regular submit
var url = "<?php echo SITE_URL;?>Training/test";
var data = {
find: $('#find').val()
};
$.ajax({
type:'POST',
url: url,
data: data,
success: function(response) {
alert (response);
},
error: function(resp) {
alert(resp.responseText);
}
});
});
});
</script>
Some tools to help you out:
If you are using FireFox, use FireBug for your debugging: https://addons.mozilla.org/fr/firefox/addon/firebug/
If you are using Chrome (my personal favorite), learn a bit more about Chrome Developer Tools: https://developers.google.com/chrome-developer-tools/?hl=fr
If you are using IE, please switch to something else for development purposes, then try it in IE to make sure you code is compatible (most likely won't be but it will be easier to find out why it doesn't work afterwards).
As for the line e.preventDefault......, look into this SO post for more details: https://stackoverflow.com/a/15913969/1483513
Hope this helps !

AJAX post function not working properly after first call to the function

I'm totally new to jquery and AJAX, After trying hard for 5-6 hours and searching the solution I'm asking for the help.
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$(".submit").live('click',(function() {
var data = $("this").serialize();
var arr = $("input[name='productinfo[]']:checked").map(function() {
return this.value;
}).get();
if(arr=='')
{
$('.success').hide();
$('.error').show();
}
else
{
$.ajax({
data: $.post('install_product.php', {productvars: arr}),
type: "POST",
success: function(){
$(".productinfo").attr('checked', false);
$('.success').show();
$('.error').hide();
}
});
}
return false;
}));
});
</script>
and HTML+PHP code is,
$json = file_get_contents(feed address);
$products = json_decode($json);
foreach(products as product){
// define various $productvars as a string
<input type="checkbox" class="productvars" name="productinfo[]" value="<?php echo $productvars; ?>" />
}
<input type="submit" class="submit" value="Install Product" />
<span class="error" style="display:none"><font color="red">No product selected.</font></span>
<span class="success" style="display:none"><font color="green">product successfully added to database.</font></span>
As I'm pulling the product information from feed, I don't want to refresh the page, that's why I'm using AJAX post method. Using above code "install_product.php" page is handling the string properly and doing its job properly.
The problem I'm facing is, when first time I check the check box and install the product it works absolutely fine, but after first post "Sometimes it work and sometimes it won't work". As new list is pulled from feed every first post is perfect after that I need to click install button again and again to do so.
I tested the code on different browsers, but same problem. What may be the problem?
(I'm testing the code on live host not localhost)
$.live is deprecated, consider using $.on() instead.
Which function is not executing after it executes once? $.live?
Also, it should be:
var data = $(this).serialize();
not
var data = $("this").serialize();
In your example, you are looking for an explicit tag called 'this', not a scope.
UPDATE
$(function () {
$(".submit")
.live('click', function(event) {
var data = $(this).serialize();
var arr = $("input[name='productinfo[]']:checked")
.map(function () {
return this.value;
})
.get();
if (arr == '') {
$('.success')
.hide();
$('.error')
.show();
} else {
$.ajax({
data: $.post('install_product.php', {
productvars: arr
}),
type: "POST",
success: function () {
$(".productinfo")
.attr('checked', false);
$('.success')
.show();
$('.error')
.hide();
}
});
}
event.preventDefault();
});
});
Is it possible, it is missing the value at arr and showing up the error or is it like it is making call but not returning or it is not reaching the call at all?
Do a console.log to deal with debuging and check things out in firefox / chrome and see what and where is the issue.

Send POST data to PHP without using an HTML form?

Is there anyway to send post data to a php script other than having a form? (Not using GET of course).
I want javascript to reload the page after X seconds and post some data to the page at the same time. I could do it with GET but I would rather use POST, as it looks cleaner.
Thanks a lot.
EDIT: Would it be possible to do with PHP header? I'm sure it is better to use JQuery but for my current situation I could implement that a lot easier/faster : )
Cheers
I ended up doing it like so:
<script>
function mySubmit() {
var form = document.forms.myForm;
form.submit();
}
</script>
...
<body onLoad="mySubmit()";>
<form action="script.php?GET_Value=<?php echo $GET_var ?>" name="myForm" method="post">
<input type="hidden" name="POST_Value" value="<?php echo $POST_Var ?>">
</form>
</body>
Seems to work fine for me, but please say if there is anything wrong with it!
Thanks everyone.
As requested above, here is how you could dynamically add a hidden form and submit it when you want to refresh the page.
Somewhere in your HTML:
<div id="hidden_form_container" style="display:none;"></div>
And some Javascript:
function postRefreshPage () {
var theForm, newInput1, newInput2;
// Start by creating a <form>
theForm = document.createElement('form');
theForm.action = 'somepage.php';
theForm.method = 'post';
// Next create the <input>s in the form and give them names and values
newInput1 = document.createElement('input');
newInput1.type = 'hidden';
newInput1.name = 'input_1';
newInput1.value = 'value 1';
newInput2 = document.createElement('input');
newInput2.type = 'hidden';
newInput2.name = 'input_2';
newInput2.value = 'value 2';
// Now put everything together...
theForm.appendChild(newInput1);
theForm.appendChild(newInput2);
// ...and it to the DOM...
document.getElementById('hidden_form_container').appendChild(theForm);
// ...and submit it
theForm.submit();
}
This is equivalent to submitting this HTML form:
<form action="somepage.php" method="post">
<input type="hidden" name="input_1" value="value 1" />
<input type="hidden" name="input_2" value="value 2" />
</form>
You can use JQuery to post to a php page:
http://api.jquery.com/jQuery.post/
By jQuery:
$.ajax({
url: "yourphpscript.php",
type: "post",
data: json/array/whatever,
success: function(){ // trigger when request was successfull
window.location.href = 'somewhere'
},
error: anyFunction // when error happened
complete: otherFunction // when request is completed -no matter if the error or not
// callbacks are of course not mandatory
})
or simplest:
$.post( "yourphpscript.php", data, success_callback_as_above );
more on http://api.jquery.com/jQuery.ajax
Use the FormData API.
From the example there:
var formData = new FormData();
formData.append("username", "Groucho");
formData.append("accountnum", 123456);
var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);
Form your own header, as such:
POST /submit.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/4.0
Content-Length: 27
Content-Type: application/x-www-form-urlencoded
userId=admin&password=letmein
How about this:
function redirectWithPostData(strLocation, objData, strTarget)
{
var objForm = document.createElement('FORM');
objForm.method = 'post';
objForm.action = strLocation;
if (strTarget)
objForm.target = strTarget;
var strKey;
for (strKey in objData)
{
var objInput = document.createElement('INPUT');
objInput.type = 'hidden';
objInput.name = strKey;
objInput.value = objData[strKey];
objForm.appendChild(objInput);
}
document.body.appendChild(objForm);
objForm.submit();
if (strTarget)
document.body.removeChild(objForm);
}
use like this:
redirectWithPostData('page.aspx', {UserIDs: getMultiUserSelectedItems()},'_top');
You can send an xhr request with the data you want to post before reloading the page.
And reload the page only if the xhr request is finished.
So basically you would want to do a synchronous request.

Easiest Way To Make A Form Submit Without Refresh

I have been trying to create a simple calculator. Using PHP I managed to get the values from input fields and jump menus from the POST, but of course the form refreshes upon submit.
Using Javascript i tried using
function changeText(){
document.getElementById('result').innerHTML = '<?php echo "$result";?>'
but this would keep giving an answer of "0" after clicking the button because it could not get values from POST as the form had not been submitted.
So I am trying to work out either the Easiest Way to do it via ajax or something similar
or to get the selected values on the jump menu's with JavaScript.
I have read some of the ajax examples online but they are quite confusing (not familiar with the language)
Use jQuery + JSON combination to submit a form something like this:
test.php:
<script type="text/javascript" src="jquery-1.4.2.js"></script>
<script type="text/javascript" src="jsFile.js"></script>
<form action='_test.php' method='post' class='ajaxform'>
<input type='text' name='txt' value='Test Text'>
<input type='submit' value='submit'>
</form>
<div id='testDiv'>Result comes here..</div>
_test.php:
<?php
$arr = array( 'testDiv' => $_POST['txt'] );
echo json_encode( $arr );
?>
jsFile.js
jQuery(document).ready(function(){
jQuery('.ajaxform').submit( function() {
$.ajax({
url : $(this).attr('action'),
type : $(this).attr('method'),
dataType: 'json',
data : $(this).serialize(),
success : function( data ) {
for(var id in data) {
jQuery('#' + id).html( data[id] );
}
}
});
return false;
});
});
The best way to do this is with Ajax and jQuery
after you have include your jQuery library in your head, use something like the following
$('#someForm').submit(function(){
var form = $(this);
var serialized = form.serialize();
$.post('ajax/register.php',{payload:serialized},function(response){
//response is the result from the server.
if(response)
{
//Place the response after the form and remove the form.
form.after(response).remove();
}
});
//Return false to prevent the page from changing.
return false;
});
Your php would be like so.
<?php
if($_POST)
{
/*
Process data...
*/
if($registration_ok)
{
echo '<div class="success">Thankyou</a>';
die();
}
}
?>
I use a new window. On saving I open a new window which handles the saving and closes onload.
window.open('save.php?value=' + document.editor.edit1.value, 'Saving...','status,width=200,height=200');
The php file would contain a bodytag with onload="window.close();" and before that, the PHP script to save the contents of my editor.
Its probably not very secure, but its simple as you requested. The editor gets to keep its undo-information etc.

Categories