I'm going a little crazy here as I'm at a real loss for words what is happening. After a lot of digging around, I believe I am doing everything as should be.
Situation
I'm trying to send a user creation form to the server via AJAX and codeIgniter fails to even get past this part
if($this->input->post('blnAjax')) { // do something }
I have successfully incorporated the AJAX side of things in to the client as it fetches content from the server with very little problem. Here are some of the details involved in the call:
Ajax code
The ajax code is part of a much larger framework beyond the scope of this question but in terms of the actual call function, the event has event.preventDefault(); event.stopImmediatePropagation(); to stop it running off. The URL is reachable and the post values have been serialized with request type set to POST
requestpage: function(){
var strURL = params.strBaseURL + params.strRequestURL;
$.ajax({
type: params.strRequestMethod,
url: strURL,
data: params.strRequestParameters,
dataType: 'json',
success: function(json) {
methods.postrequestprocedure(json);
}
});
},
Ajax request
Everything runs smoothly on the client making the XMLHttpRequest with json as expected return. I don't even get to this point when the form has been submitted however. Codeigniter will never think the form has been set if using AJAX
Parameters application/x-www-form-urlencoded
blnAjax 1
user_login_name[] fred
user_login_name[] ted
user_name[] Fred Flintstone
user_name[] Ted bear
usergroup_id[] 16
usergroup_id[] 16
Controller
On the controller, with regard to the action, I have included alall code up to the point of fail. Please note that I have tested the other aspects of the code and they run fine
public function user_add() {
/* Include extra script files needed for form handling */
$this->view['aryScript'][] = 'jquery.validate.min';
$this->view['aryScript'][] = 'jquery.validate.additional-methods';
/* Include extra CSS files */
$this->view['aryCSS'][] = 'form';
/* First check if the user has correct access rights */
if($this->view['intAccessLevel'] < INT_SUPER_USER_ACCESS_LEVEL) {
$aryResponse['notifications'][] = array('strType' => 'permanent',
'strMessage' => 'Denied!');
}
/* Import extra libraries and helpers */
$this->load->library(array('PasswordHash'));
$this->load->model('UserAdminModel');
$this->view['strTitle'] = 'Add User';
$this->view['aryButtons']['user_add_another'] = array(
'strDisplay' => $this->lang->line('user_add_another')
'strURL' => '#',
'strID' => 'user_add_another',
'aryData' => array('action' => 'form-clone')
);
if($this->input->post('blnAjax')) {
echo 'Big sigh of relief';
Thank you kindly for taking the time to read my problem
The answer is never as simple as it seems! My client is using a CodeIgniter mod that rewrites the URI and thus dumping the data passed from the ajax query. It hadn't been a problem when performing gets and "real" POST queries.
So if you are ever using Wiredesignz - Language Identifier beware that it can affect your queries
How I fixed it, I use a custom page controller but the theory is the same:
Be sure that you have $this->config->item('language_abbr'); available to your javascript functions maybe through a constant or echo it directly in to the javascript if on the same page
Modify the URL before sending it with something similar to params.strBaseURL + params.strLanguage + '/' + params.strRequestURL;
You should now find things work just fine. I hope this helps and noone else has to spend a mini eternity to find this out
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
I'm creating a webproject in pyramid where I'd like to update a table every few secondes. I already decided to use ajax, but I'm stuck on something.
On the client side I'm using the following code:
function update()
{
var variable = 'variable ';
$.ajax({
type: "POST",
url: "/diagnose_voorstel_get_data/${DosierID}",
dataType: "text",
data: variable ,
success: function (msg) {
alert(JSON.stringify(msg));
},
error: function(){
alert(msg + 'error');
}
});
}
Pyramid side:
#view_config(route_name='diagnose_voorstel_get_data', xhr=True, renderer='string')
def diagnose_voorstel_get_data(request):
dosierid = request.matchdict['dosierid']
dosieridsplit = dosierid.split
Diagnoses = DBSession.query(Diagnose).filter(and_(Diagnose.code_arg == str(dosieridsplit[0]), Diagnose.year_registr == str(dosieridsplit[1]), Diagnose.period_registr == str(dosieridsplit[2]), Diagnose.staynum == str(dosieridsplit[3]), Diagnose.order_spec == str(dosieridsplit[4])))
return {'Diagnoses ' : Diagnoses }
Now I want to put this data inside a table with zpt using the tal:repeat statement.
I know how to use put this data in the table when the page loads, but I don't know how to combine this with ajax.
Can anny1 help me with this problem ? thanks in adance.
You can do just about anything with AJAX, what do you mean "there's no possibility"? Things become much cleaner once you clearly see what runs where and in what order - as Martijn Pieters points out, there's no ZPT in the browser and there's no AJAX on the server, so the title of the question does not make much sense.
Some of the options are:
clent sends an AJAX request, server does its server-side stuff, in the AJAX call success handler the client reloads the whole page using something like window.location.search='ts=' + some_timestamp_to_invalidate_cache. The whole page will reload with the new data - although it works almost exactly like a normal form submit, not much sense using AJAX like this at all.
client sends an AJAX request, server returns an HTML fragment rendered with ZPT which client then appends to some element on your page in the AJAX success handler:
function update()
{
var variable = 'variable ';
$.post("/diagnose_voorstel_get_data/${DosierID}")
.done(function (data) {'
$('#mytable tbody').append(data);
});
}
client sends an AJAX request, server returns a JSON object which you then render on the client using one of the client-side templating engines. This probably only make sense if you render your whole application on the client and the server provides all data as JSON.
This issue is very likely codeigniter specific.
I have a controller called redirect.php that redirects from and to views. This controller for the most part has one public _remap function that does all the redirecting with a case statement. Everything has been working great until I sent a $.POST from a view back to the controller. I want it to hit the _remap and look for the fact that the request is coming from AJAX then do it’s case.
I have a IS_AJAX constant I’m checking against.
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
but whenever I hit the page it’s always remapping to the default and sending my request to that page where it’s basically returning me that pages data back when I’m echoing and alerting the data to and fro.
Any insights?
for reference,
redirect.php (there is more code to define variables and 2 more cases but it's not hitting those, it's hitting 'index' / default)
public function _remap($method)
{
switch ($method) {
case $method == 'index':
$this->load->view('main');
break;
case $method == 'IS_AJAX':
var_dump($_POST);
break;
default:
$this->load->view('main');
}
}
tweetview.php (view loaded by redirect controller in another case within redirect.php, json_tweets send is a JSON variable)
//jquery
$.post("http://localhost/2fb/index.php/redirect", {'json_tweets': json_tweets},
function(data) {
alert(data);
});
Instead of doing all this you can rely on $this->input->is_ajax_request() from http://codeigniter.com/user_guide/libraries/input.html. If you are not interested in loading a library, here is somewhat similar code I have in production for last two years at least.
$ajax = ($_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest')? true : false;
Look at the string, its XMLHttpRequest and the jQuery is the frontend JS toolkit
Just to add more, I usually have one entry point for Ajax calls, so obviously I have one controller for ajax and route all my calls through it. Why would I do that? Simple reason, I make sure all my forms submit to a simple non ajax form handler at server if JS is turned off. If JS is on, jQuery/prototype/YUI takes control and sends data to my ajax controller. The end handler which actually does all the validation/verification/db interaction is common code.
case $method == 'IS_AJAX':
Your $method is not IS_AJAX with this url:
http://localhost/2fb/index.php/redirect
This would bring you to the redirect controller without a method (will default to "index"). You literally would need:
http://localhost/2fb/index.php/redirect/IS_AJAX
...to step into that case. You seem to be confusing your constant IS_AJAX with the method requested, which you seem to be using correctly when checking for index (although this is the same as the default case, so it's redundant).
$method, or whatever you name the first parameter in _remap(), will always be the routed controller function that is called.
EDIT: I failed to mention this earlier, but the switch block evaluates the expression you pass to it, so there is no need to do the comparison manually. Example:
switch ($method) {
// case $method === 'index':
case 'index':
$this->load->view('main');
break;
}
try this ,
$.ajax({
type: "POST",
url: "your function url goes here",
data: data,
success: function(html){
window.location = 'redirect url goes here';
}
});
I have a html page that I need to call another asp page to get the date/hour via an ajax call. Which method would be better or best, Post or Get?
Since I am only retrieving a few bits of data and not sending any data to the page info is one method better or proper than the other?
This is the simple ASP page.
<%#LANGUAGE="VBSCRIPT"%>
<% Option Explicit %>
<%=Weekday(Date)%>
<%=Hour(Now)%>
And this is the Ajax call to the asp page above.
jQuery.ajax({
url: '/v/timecheck.asp',
type: 'GET',
cache: false,
success: function(data){
// do something with the data
},
error: function() {
//do something on error
return false;
}
})
The reason I have to make the Ajax call to this ASP page is I cannot query the server direct from this page.
My rule of thumb when deciding either one is:
The interaction involve database, POST
The interaction involve sensitive information, POST
Requesting simple data, GET
Sending user input, POST
Sending/requesting large data, POST
Clean URL, POST
As you can see, most cases involve POST for many reason. Such as in your case, you could use GET or POST. Either way, jQuery make calling both function easy.
A simpler $.POST
$.post("/v/timecheck.asp", function (data) {
if (data.time != "") {
//retrieve success
{
else
{
//retrieve fail
};
});
or simpler $.GET
$.get("/v/timecheck.asp", function(data) {
if (data.time != "") {
//retrieve success
{
else
{
//retrieve fail
};
});
I would use POST, I think there is a secirity reason in ASP.NET to use POST, but not sure if this relates to IIS (and possibly ASP)
The W3C have a paper with guidelines on when to use GET or POST at: http://www.w3.org/2001/tag/doc/whenToUseGet-20040321#checklist
Using a GET request allows the result to be cached by the browser whereas a POST request won't be cached and the page will be re-retrieved every time.
In your code example you are not changing any data as a result of the request and are only providing the day and hour, so using a GET and setting the cache HTTP headers to 1 hour would give you the best performance and reduce load on your server.