Ajax call locally in jQueryMobile and Phonegap, JSON objects - ajax

I have very simple jQueryMobile application. I want to submit a form and to call ajax. On my desktop PC this works fine and looks like this:
application on my PC
When i press the button "Save" the text below appers. The HTML code for the interface is in the script accountAdd.html. At my PC It works as expected, but i need this app for my mobile device. Here is the screenshot from my device when i try to do the same thing that is showed at the first figure.
application on my mobile device
So here is the part of the script that calls ajax.
accountAdd.html
<script>
$( document ).ready(function() {
$(document).on('submit', '#formDetails', function() {
var theName = $("#accountName").val();
if($('#accountName').val().length > 0) {
$.ajax({
url: 'accountAdd.php',
data: $('#formDetails').serialize(),
type: 'post',
dataType: 'json',
timeout: 5000,
success: function (result, status) {
$("#resultLog").html("accountName: " + result.accountName);
},
error: function (request,error) {
alert('Network error has occurred please try again! Error: ' + error);
}
});
} else {
alert('Please fill all necessary fields');
}
return false;
});
});
</script>
.
.
.
HTML code
Here is my other script that contains code that is executed in back-end.
accountAdd.php
<?php
header('Access-Control-Allow-Origin: *');
$return['accountName'] = $_POST['accountName'];
$return['accountType'] = $_POST['accountType'];
$return['accountBalance'] = $_POST['accountBalance'];
$return['accountDate'] = $_POST['accountDate'];
echo json_encode($return);
?>
So the ajax call on my mobile device is not working as expected and as you can see at the second figure is giving parseerror. The code is completely the same at both devices. I'am converting the scripts with phonegap. I think that the problem is related with JSON objects (I think that ajax call in phonegap need to pass JSON obejects but I'm not sure). I need help, how to modify the code, so that can work at the PC and at my mobile device at the same time.

Ok, you have <access origin="*"/> so it is not a CORS issue.
I think maybe your problem is that you do not set the datatype to json in your php but expect it in the javascript side. Try adding the following line in your php file :
header('Content-Type: application/json');
Edit
I see the url to your php uses local path (should have noticed earlier but didn't know if you removed the server address on purpose), so it seems you put the .php files in the phonegap app.
That is not how it works. Either you need to do things locally and you do it in javascript, or you want to communicate with a server and you
do not put any php page in the www folder of your local page
provide the url of your server to each ajax calls.

Make sure your config.xml file is in the same folder as your index.html file and then use the (Or whatever domain you are on)

Related

AJAX response returns current page

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

Prestashop: How to submit data from adminpanel template to Admin Controller?

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

Ajax username and date Instagram API

Currently, I'm trying to create a page using instagram's api, showing recent pictures with a specific tag, as well as the user who posted it and the date posted. I'm also trying to have the infinite loading functionality, with ajax loading in more instagram posts as the page reaches the bottom.
Heres a link to the live site http://www.laithazzam.com/work/nukes/indexnew.php
Clicking the red yes will skip the video, and go straight to the instagram feed.
I'm currently using Christian Metz's solution found here, https://gist.github.com/cosenary/2961185
I am also having an issue with posting the date, in the first initial load, as well in the ajax loads. I was previously able to use this following code, before trying to implement Christian's php/ajax solution.
var date = new Date(parseInt(data.data[i].created_time) * 1000);
<p class='date'>"+(date.getMonth()+1)+"/"+date.getDate()+"/"+date.getFullYear()+"</p>
I guess what I don't understand, is how the ajax loading function, is actually functioning. How would I also pull the name, and date through the ajax loading success function as well?
$.ajax({
type: 'GET',
url: 'ajax.php',
data: {
tag: tag,
max_id: maxid
},
dataType: 'json',
cache: false,
success: function(data) {
// Output data
$.each(data.images, function(i, src) {
$("#instafeed").append('<img src="' + src + '">');
});
// Store new maxid
$('#more').data('maxid', data.next_id);
}
});
});
The data parameter of the success handler function is populated from whatever JSON ajax.php returns and the structure will match accordingly. It looks like the images attribute of that object only has an array of URLs for the images and no other data.
You'll need to update this section of the PHP script to return more than just the array of URLs for the images and also include the additional data retrieved from the Instagram API.
Try updating the last part to this:
echo json_encode(array(
'next_id' => $media->pagination->next_max_id,
'images' => $media->data
));
Then you'll have full access to all the media data, not just the URL.

How to Use Relative URL in Ajax Post in MVC3

I have an Ajax post call written in a separate ".js" file which I call in multiple pages.
My code looks like this:
$.ajax({
url: '/MyVirtualDirectory/Controller/Action',
type: 'POST',
dataType: 'json',
....
....
})
Each time I change my virtual directory in my server, I'm required to change the code in "URL" to make my Ajax call working.
Is there any method that can make my code independent of my "Virtual Directory" name in IIS ..?
My application is MVC3.
Description
You should use the Url.Action method. But in your case, a seperate js file, you cant access this method. So i would create a javascript variable for each url in your view. Then you can use this variable in your js file.
UrlHelper.Action Method - Generates a fully qualified URL to an action method.
Sample
Your View
<script type="text/javascript">
var myUrl = '#Url.Action("actionName", "controllerName")';
</script>
<script type="text/javascript" src="yourJsFile.js"/>
Your js file
$.ajax({
url: myUrl,
....
})
Update
Another way is to store your url in a hidden field inside your view and get the hidden fields value inside your js file.
More Information
MSDN - UrlHelper.Action Method
I finally found a partial work around.
In my .js file i did some dirty coding like this:
var Path = location.host;
var VirtualDirectory;
if (Path.indexOf("localhost") >= 0 && Path.indexOf(":") >= 0) {
VirtualDirectory = "";
}
else {
var pathname = window.location.pathname;
var VirtualDir = pathname.split('/');
VirtualDirectory = VirtualDir[1];
VirtualDirectory = '/' + VirtualDirectory;
}
$.ajax({
url: VirtualDirectory/Controller/Action,
....})
The basic idea is I check the URL for localhost and port number. If both are there, it means that then I'm debugging in my local machine and so I don't need virtualdirectory in URL. If I'm running a hosted version then there won't be localhost and port number in my URL(provided I'm hosting on port 80).
And by this way when I run on my local machine while debugging the url will be only Controller/Action and while I host the URL will be VirtualDirectory/Action/Controller. It works fine for me now.
But please post if there is any other simple method.
I think it would be safer to declare a global Javascript variable and then set the variable for the first time, maybe when Home/Index fires. and then reuse it in every ajax calls like so:
$.ajax({... url: GlobalVariablePath + "Controller/Action/RouteValues" ...})
if you already designed your WebApp and every thing works fine and stuck when site is deployed, then you can manipulate the all ajax URLs like so:
$.ajaxSetup({
beforeSend: function (jqXHR, settings) {
settings.url = GlobalVariablePath + settings.url;
}
});
Using this way, you can safely use the existing js codes and leave the rest without change.

Disable AJAX Caching

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.)

Resources