I am using Spring + ExtJS and need to 'export to' functionality on UI screen. I am making an Ajax call and sending the data in JSON format to controller. In controller I am doing all stuff to generate the PDF using iText and it does generate the document.
Now I am not seeing the generated PDF to downlaod/view in browser. If I do it without Ajax call, it works. Not sure whats making the difference.
I read few related articles around this which suggested to use below :
Content-type: application/pdf
Content-Disposition: attachment; filename="FileName.pdf"
But no luck with this. Please advice on this/let me know if going wrong.
As mentioned here and here, you can use an hidden iframe to do this.
Personnally I prefer the hidden form posting solution, here is an example :
var formEl = Ext.DomHelper.append(document.body, {
tag: 'form',
css : 'display:none;',
id: 'downloadForm'
}, true);
var form = new Ext.form.BasicForm(formEl, {
url : [your spring controller url],
method : 'POST',
fileUpload: true,
baseParams: [your JSON parameters]|| {}
});
form.doAction(new Ext.form.action.StandardSubmit({
form: form,
clientValidation: false
}));
I hope this helps.
Related
I was searching for a similar issue for a while now, but none of the solutions worked for me (and I couldn't find exactly the same issue).
First of all, the website I'm working on is running on Zend Framework. I suspect that it has something to do with the issue.
I want to make a pretty basic AJAX functionality, but for some reason my response always equals the html of the current page. I don't need any of Zend's functionality, the functions I need to implement could (and I'd prefer them to) work separately from the framework.
For testing purposes I made it as simple as I could and yet I fail to find the error. I have a page "test.php" which only has a link that triggers the ajax call. Here's how this call looks:
$('.quiz-link').click(function(e){
e.preventDefault();
$.ajax({
URL: "/quiz_api.php",
type: "POST",
cache: false,
data: {
'test': 'test'
},
success: function(resp){
console.log(resp);
},
error: function(resp){
console.log("Error: " + reps);
}
});
});
And this quiz_api.php is just:
<?php
echo "This is a test";
?>
When I click on the link I get the entire HTML of the current page. "This is a test" can't be found there. I'm also getting an error: "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/."
I reckon it has to do with the JS files that are included into this HTML response, but I've also tried setting "async: true" and it didn't help.
I would like to avoid using Zend Framework functions for this task, because I'm not well familiar with it and even making a simple controller sounds rather painful. Instead I want to find out what's causing such behavior and see if it can be changed.
PS: I've also tried moving quiz_api.php to another domain, but it didn't change anything.
I know that it might be an older code but it works, simple and very adaptable. Here's what I came up with. Hope it works for you.
//Here is the html
Link Test
<div id="test_div"></div>
function test(){
// Create our XMLHttpRequest object
var hr = new XMLHttpRequest();
// This is the php file link
var url = "quiz_api.php";
// Attaches the variables to the url ie:var1=1&var2=2 etc...
var vars = '';
hr.open("POST", url, true);
//Set content type header information for sending url encoded variables in the request
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Access the onreadystatechange event for the XMLHttpRequest object
hr.onreadystatechange =
function(){
if(hr.readyState == 4 && hr.status == 200){
var return_data = hr.responseText;
console.log(return_data);
document.getElementById('test_div').innerHTML = return_data;
}else{
document.getElementById('test_div').innerHTML = "XMLHttpRequest failed";
}
}
//Send the data to PHP now... and wait for response to update the login_error div
hr.send(vars); // Actually execute the request
}
you can change the whole page with a document.write instead of changing individual "div"s
I'm trying to make a custom page in the adminpanel of Prestashop where the shopowner can fill in his upcoming events that will appear in a column in the header.tpl page. The templates and controller are working so far, with a structure based on an answer here at Stack Overflow:
How to create a new page in prestashop admin panel?
Now I have made in the content.tpl (with the added custom JavaScript and CSS files) the form with the input fields. The next step is to send it to the controller to save it in the database. But I'm stuck this part. I can't find how I can nicely submit the form to the controller. First I tried it with an Ajax function but I couldn't find the right way. Also without Ajax no success.
$.ajax({
type: 'POST',
headers: { "cache-control": "no-cache" },
url: baseUri + '?rand=' + new Date().getTime(),
async: true,
cache: false,
dataType : "json",
data:{
processEvents: true,
ajax: 'true',
controller: 'AdminEvents',
token: static_token
},
//success: function(jsonData){
//}
});
This is an example of an Ajax function that I tried. My questions:
How does other tpl or js files receive the baseUri, where is that
variable set?
What is the function of the ?rand date and time in that line? A kind
of security token?
What is the url of the controller? Also the url when I use
I guess the processEvents : true and Ajax : true is for security
reasons and to check if the form is submitted by Ajax or not?
Why is it necessary to send the controller name?
Where does the token come from?
Questions about the controller:
Which (Prestashop default functions) can or do need to use? For
example:
if (Tools::isSubmit('name')){
etc.
if (Tools::getValue('create_account')){
etc.
Can I use that functions anywhere or maybe only in an Init function?
A lot of questions, feel free to answer only a part of it, I just need a good push in the right direction, searching and reading in the online documentation and on the internet doesn't brought me the solution and brainwashed me a little.
EDIT:
I made a little progress by myself:
Where does the token come from?
What is the url of the controller? Also the url when I use
With the tools getAdminTokenLite and the controller name I generated the controller url:
$token = '?controller=AdminEvents&token='.Tools::getAdminTokenLite('AdminEvents');
The url to post to is the token plus the domain, admin directory and index.php.
With the tool getValue I get the POST data like in PHP with $_POST["name"].
Tools::getValue('event_name')
So its working but I guess it can be better with other Presta default tools.
I know that it's very late to answer you, but for sure it will help other mates with same problem.
Here is an example about how to implement ajax calls in Prestashop 1.6 on Admin panel using ANY Controller from BackOffice (if you want also, you can use ajax.php controller, but I'm using for this AdminImportController() )
tpl part:
$('#mybtn').click(function(e) {
var data = $('#datalist').val();
// Ajax call with secure token
$.post( "{$current|escape:'html':'UTF-8'}&token= {$token|escape:'html':'UTF-8'}",
{ ajax: true, action: "MyFunction", mydata: data } );
});
And in admin controller side:
public function ajaxProcessMyFunction()
{
// Get param
$mydata = (int)Tools::getValue('mydata');
$answer = 0;
if( $mydata > 0 ) {
$this->importProfList = Db::getInstance()->executeS(
"SELECT * FROM .... LIMIT 1"
);
...
$answer = $someOperationResult;
}
// Response
die(Tools::jsonEncode(array(
'answer' => htmlspecialchars($answer)
)));
}
Tested and working like a charm.
Regards
Normally one posts an ExtJS form to the backend using form.submit({...}). I want to make my form submission synchronous now, so I'm switching to using Ext.Ajax.request({async: false, ...}). The form property of Ext.Ajax.request() usually looks like so:
Ext.Ajax.request({
url: 'formsubmit',
form: 'formid',
method:'POST',
success: function(response, opts) {
alert("successfull");
},
failure:function(res,opt) {
alert("request failed");
}
});
I'm dealing with a bunch of anonymous forms right now. Is there any way around this?
Given a var form = {xtype: 'form', items: [...]}
I've tried replacing 'formid' with form.getEl(), form.getForm(), and form.getForm().getFieldValues() which all don't work.
There's no other way around this other than assigning a generated id to each of my anonymous forms, is there.
Thanks for any input
It looks like you could just do this as an alternative to the form attribute:
var form = this.down('form');
Ext.Ajax.request({
url: 'test.xyz',
params: form.getValues()
// etc...
});
getValues gives you the name/value pairs you need for your submission.
It looks like the ExtJS forms do not actually use form elements in the markup. When the submit function is called on an ExtJS form, an HTML form element is crafted as part of the process, and that's the form that is used for the submission.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.form.action.Submit-method-buildForm
Ideally, you could modify the options that are used in the Ajax request called within the doSubmit function. Since you can't, you might want to consider overriding Ext.form.action.Submit such that you can, then calling the form.submit() function you mentioned in your question.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.form.action.Submit-method-doSubmit
My issue is for some strange reason it seems stuck in the page controller so instead of getting out and going into the ajax controller I have it trying to go down that route in the page controller
1st try
http://localhost:2185/Alpha/Ajax/GetBlah_Name/?lname=Ge&fname=He
2nd try
http://localhost:2185/Patient/~/Ajax/GetBlah_Name/?lname=Ge&fname=He
Objective
http://localhost:2185/Ajax/GetBlah_Name/?lname=Ge&fname=He
Page button to call jquery
<a style="margin-left: 310px;" href="javascript:void(0)" onclick="getBlah()"
class="button"><span>Lookup</span></a>
Jquery code
1st try
{
$.getJSON(callbackURL + 'Ajax/GetBlah_Name/?lname=' + $('#Surname').val() + '&fname=' + $('#FirstName').val(), null, GetResults)
}
2nd try
{
$.getJSON(callbackURL + '~/Ajax/GetBlah_Name/?lname=' + $('#Surname').val() + '&fname=' + $('#FirstName').val(), null, GetResults)
}
In summary I don't know why it won't break out of the controller and go into the Ajax controller like it has done so in all the other projects I've done this in using the 1st try solution.
It seems you want to cal a controller at ~/Ajax. Is it? If yes, you should use this code:
$.getJSON(callbackURL + '/Ajax/GetBlah_Name/?lname=' + $('#Surname').val() + '&fname=' + $('#FirstName').val(), null, GetResults)
UPDATE:
This will work for your Q, but the complete solution is #Darin Dimitrov's answer. I suggest you to use that also.
UPDATE2
~ is a special character that just ASP.NET works with it! So http doesn't understand it. and if you start your url with a word -such as Ajax-, the url will be referenced from where are you now (my english is not good and I can't explain good, see example plz). For example, you are here:
http://localhost:2222/SomeController/SomeAction
when you create a link in this page, with this href:
href="Ajax/SomeAction"
that will be rendered as
http://localhost:2222/SomeController/Ajax/SomeAction
But, when url starts with /, you are referring it to root of site:
href="/Ajax/SomeAction"
will be:
http://localhost:2222/Ajax/SomeAction
Regards
There are a couple of issues with your AJAX call:
You are hardcoding routes
You are not encoding query string parameters
Here's how I would recommend you to improve your code:
// Always use url helpers when dealing with urls in an ASP.NET MVC application
var url = '#Url.Action("GetBlah_Name", "Ajax")';
// Always make sure that your values are properly encoded by using the data hash.
var data = { lname: $('#Surname').val(), fname: $('#FirstName').val() };
$.getJSON(url, data, GetResults);
Or even better. Replace your hardcoded anchor with one which will already contain the lookup url in its href property (which would of course be generated by an url helper):
<a id="lookup" href="Url.Action("GetBlah_Name", "Ajax")" class="button">
<span>Lookup</span>
</a>
and then in a separate javascript file unobtrusively AJAXify it:
$(function() {
$('#lookup').click(function() {
var data = { lname: $('#Surname').val(), fname: $('#FirstName').val() };
$.getJSON(this.href, data, GetResults);
return false;
});
});
Now how your urls will look like will totally depend on how you setup your routes in the Application_Start method. Your views and javascripts are now totally agnostic and if you decide to change your route patterns you won't need to touch jaavscript or views.
I am in a bit of a pickle right now. I am building a web page that will get data from a CGI backend. I have no control over the CGI backend, nor the server (so no mod_headers or mod_expires). Also, because of the parameters to the script, I cannot append a unique value (like '&089u0af0d98) to each request. The requests are AJAX using the XmlHttpRequest object. I have tried to set the 'If-Modified-Since' and 'Cache-Control' request headers unsuccessfully. Does anybody have any other ideas for how I can prevent the AJAX response from being cached by the browser?
You can send random parameters using POST, while sending the important vars using GET if you need to.
If you have problems with IE, I know that sending something with POST makes it to stop caching server responses
I use this javascript function ( which in turn uses jquery.ajax function )
the cache: false would do the trick.
This works perfectly for me , may be you can give it a try
function ajax_call(urlString)
{
ret_val="";
$.ajax
(
{
type: "GET",
url: urlString,
async:false,
cache:false,
dataType: 'html',
success: function(msg)
{
ret_val=msg;
},
error:function (xhr, textStatus, thrownError)
{
ret_val=xhr.readyState;
alert("status=" +xhr.status);
}
}
);
return ret_val;
}
I used $.ajaxSetup({ cache: false }); somewhere in my base html-page (default.aspx) in a non-frequent web-system and it worked fine. No pain-in-the-neck caching problems anymore.
I ran into this today, and found that if you want to keep to using get, you can add a hidden form element to the page and have JS set it's value to the current timestamp before submitting the query to ajax.
I add a form element something like this:
<input type="hidden" name="ie_sucks" id="ie_sucks", value="1" />
Then, in the function to submit the form via AJAX I set this hidden input to the current timestamp with something like this:
$('#ie_sucks').val(new Date().getTime());
The above code uses JQuery, so in pure JS it would be something like:
document.getElementById('ie_sucks').value = new Date().getTime();
This is not a pretty solution, but it does work.
I know jQuery's .ajax() call has a parameter called 'cache' which, if set to false, will force requested pages not to be cached by the browser. It's probably worth checking the jQuery source to see how they do it.
(I'm checking it now and will update if I find anything, but posting this answer early in case you or anybody else has better luck finding it.)