I'm using Dojo 1.7.2 and I try the following code
var request = xhr.get({
url: location,
content : content,
load : function( data ){
for( var x in data )
{
alert ( x + data[x] );
}
},
error : function()
{
alert( 'Had an eror' );
},
handleAs : 'json'
});
Then in php i do the following to try and detect the xmlhttprequest
function isAjax(){
$ajax = (isset( $_SERVER[ 'HTTP_X_REQUESTED_WITH' ] ) ) &&
( strtolower( $_SERVER[ 'HTTP_X_REQUESTED_WITH' ] ) == 'xmlhttprequest' );
return $ajax;
}
But the isAjax function returns false.
If I do xhr.post then it works fine. I'm thinking this is just a side effect of using GET instead of POST? Is that it or is it something else that I'm not checking for.
This solution is based on Zend Framework version.
function isAjax() {
$header = 'X_REQUESTED_WITH';
// Try to get it from the $_SERVER array first
$temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
if (isset($_SERVER[$temp])) {
return $_SERVER[$temp] == 'XMLHttpRequest';
}
// This seems to be the only way to get the Authorization header on
// Apache
if (function_exists('apache_request_headers')) {
$headers = apache_request_headers();
if (isset($headers[$header])) {
return $headers[$header] == 'XMLHttpRequest';
}
$header = strtolower($header);
foreach ($headers as $key => $value) {
if (strtolower($key) == $header) {
return true;
}
}
}
return false;
}
It is not a standard that this header is appended - as it is an unnescesary overhead in most cases.
You need to set the header yourself - and can call it whatever you please really. What you want is headers: { "X-Requested-With": "XMLHttpRequest" }:
var request = xhr.get({
url: location,
content : content,
headers: { "X-Requested-With": "XMLHttpRequest" }, // << < add this
load : function( data ){
for( var x in data )
{
alert ( x + data[x] );
}
},
error : function()
{
alert( 'Had an eror' );
},
handleAs : 'json'
});
Related
I'm using datatables in my administration panel
but I realized that the sort functionality is not working properly. The specific table that we're talking about is with server-side rendering. The specific column "Status" that we're talking about has the following contents
if($record->claimed == 1) {
$claimed = '<span class="badge badge-primary">CLAIMED</span>';
} else {
$claimed = '<span class="badge badge-secondary">NOT CLAIMED</span>';
}
How can I make this sort work properly? I tried this
if($record->claimed == 1) {
$claimed = '<span class="d-none">1</span><span class="badge badge-primary">CLAIMED</span>';
} else {
$claimed = '<span class="d-none">0</span><span class="badge badge-secondary">NOT CLAIMED</span>';
}
but it doesn't work as expected. Maybe some kind of a data-sort attribute or....? Any ideas?
I was faced the same issue when you populate your table cell with HTML tags, it creates issues for searching / sorting. A very simple TRICK to define your dataType as "JSON" will fix this issue. Below is my sample code for Datatable (Server-Side-Processing with pipelined) in my production server and working perfectly.
<script type="text/javascript" language="javascript" class="init">
$.fn.dataTable.pipeline = function ( opts ) {
// Configuration options
var conf = $.extend( {
pages: 5, // number of pages to cache
url: '', // script url
data: null, // function or object with parameters to send to the server
// matching how `ajax.data` works in DataTables
method: 'GET' // Ajax HTTP method
}, opts );
// Private variables for storing the cache
var cacheLower = -1;
var cacheUpper = null;
var cacheLastRequest = null;
var cacheLastJson = null;
return function ( request, drawCallback, settings ) {
var ajax = false;
var requestStart = request.start;
var drawStart = request.start;
var requestLength = request.length;
var requestEnd = requestStart + requestLength;
if ( settings.clearCache ) {
// API requested that the cache be cleared
ajax = true;
settings.clearCache = false;
}
else if ( cacheLower < 0 || requestStart < cacheLower || requestEnd > cacheUpper ) {
// outside cached data - need to make a request
ajax = true;
}
else if ( JSON.stringify( request.order ) !== JSON.stringify( cacheLastRequest.order ) ||
JSON.stringify( request.columns ) !== JSON.stringify( cacheLastRequest.columns ) ||
JSON.stringify( request.search ) !== JSON.stringify( cacheLastRequest.search )
) {
// properties changed (ordering, columns, searching)
ajax = true;
}
// Store the request for checking next time around
cacheLastRequest = $.extend( true, {}, request );
if ( ajax ) {
// Need data from the server
if ( requestStart < cacheLower ) {
requestStart = requestStart - (requestLength*(conf.pages-1));
if ( requestStart < 0 ) {
requestStart = 0;
}
}
cacheLower = requestStart;
cacheUpper = requestStart + (requestLength * conf.pages);
request.start = requestStart;
request.length = requestLength*conf.pages;
// Provide the same `data` options as DataTables.
if ( $.isFunction ( conf.data ) ) {
// As a function it is executed with the data object as an arg
// for manipulation. If an object is returned, it is used as the
// data object to submit
var d = conf.data( request );
if ( d ) {
$.extend( request, d );
}
}
else if ( $.isPlainObject( conf.data ) ) {
// As an object, the data given extends the default
$.extend( request, conf.data );
}
settings.jqXHR = $.ajax( {
"type": conf.method,
"url": conf.url,
"data": request,
"dataType": "json", // **IMPORTANT POINT**
"cache": false,
"success": function ( json ) {
cacheLastJson = $.extend(true, {}, json);
if ( cacheLower != drawStart ) {
json.data.splice( 0, drawStart-cacheLower );
}
if ( requestLength >= -1 ) {
json.data.splice( requestLength, json.data.length );
}
drawCallback( json );
}
} );
}
else {
json = $.extend( true, {}, cacheLastJson );
json.draw = request.draw; // Update the echo for each response
json.data.splice( 0, requestStart-cacheLower );
json.data.splice( requestLength, json.data.length );
drawCallback(json);
}
}
};
// Register an API method that will empty the pipelined data, forcing an Ajax
// fetch on the next draw (i.e. `table.clearPipeline().draw()`)
$.fn.dataTable.Api.register( 'clearPipeline()', function () {
return this.iterator( 'table', function ( settings ) {
settings.clearCache = true;
} );
} );
</script>
I'm trying to learn php and WP developing. My goal is to mark posts done/read on button click. I found this great ajax tutorial plugin. Here is the link of the tutorial, and for the plugin. I have successfully manage to edit the plugin form my needs. On click it checks if there is already that id in the array, if it is it deletes that element from the array. If there is not id in the array, or the array is empty it adds post id into the array. Afterwards the array is updated into db.
Here is the code for the button, that is added after the post content:
public function rml_button( $content ) {
$rml_post_id = get_the_id();
// Show read me later link only when user is logged in
if( is_user_logged_in() && get_post_type() == post ) {
if( get_user_meta( wp_get_current_user()->ID, 'rml_post_ids', true ) !== null ) {
$value = get_user_meta( wp_get_current_user()->ID, 'rml_post_ids', true );
}
if( $value ) {
if (in_array($rml_post_id, $value)) {
$html .= 'DONE';
$content .= $html;
}
else {
$html .= 'MARK AS DONE';
$content .= $html;
}
}
else {
$html .= 'MARK AS DONE';
$content .= $html;
}
}
return $content;
}
Here is the code for updating the db:
public function read_me_later() {
check_ajax_referer( 'rml-nonce', 'security' );
$rml_post_id = $_POST['post_id'];
$echo = array();
if( get_user_meta( wp_get_current_user()->ID, 'rml_post_ids', true ) !== null ) {
$value = get_user_meta( wp_get_current_user()->ID, 'rml_post_ids', true );
}
if( $value ) {
if (in_array($rml_post_id, $value)) {
foreach (array_keys($value, $rml_post_id, true) as $key) {
unset($value[$key]);
}
$echo = $value;
}
else {
$echo = $value;
array_push( $echo, $rml_post_id );
}
}
else {
$echo = array( $rml_post_id );
}
update_user_meta( wp_get_current_user()->ID, 'rml_post_ids', $echo );
// Always die in functions echoing Ajax content
die();
}
Finally, here is the .js for the ajax call:
jQuery(document).ready( function(){
jQuery('#content').on('click', 'a.rml_bttn', function(e) {
e.preventDefault();
var rml_post_id = jQuery(this).data( 'id' );
jQuery.ajax({
url : rml_obj.ajax_url,
type : 'post',
data : {
action : 'read_me_later',
security : rml_obj.check_nonce,
post_id : rml_post_id
},
success : function( response ) {
jQuery('.rml_contents').html(response);
}
});
//jQuery(this).hide();
});
});
What I cannot figure out, and sorry if it is a stupid question, is how to change button text after the ajax? From "MARK AS DONE" to "DONE" and vice versa. How to call this function rml_button(), inside read_me_later() so that button text will be changed after the db update.
Thank you.
Added if else statements inside ajax success function to be able to change a tag text from MARK AS DONE to DONE and vice versa.
Try:
jQuery(document).ready( function(){
jQuery('#content').on('click', 'a.rml_bttn', function(e) {
e.preventDefault();
var rml_post_id = jQuery(this).data( 'id' );
var ts = jQuery(this);
jQuery.ajax({
url : rml_obj.ajax_url,
type : 'post',
data : {
action : 'read_me_later',
security : rml_obj.check_nonce,
post_id : rml_post_id
},
success : function( response ) {
if(ts.html()=="DONE") { ts.html("MARK AS DONE"); } // ts.html()=="DONE" - maybe changed based on response
else { ts.html("DONE"); }
jQuery('.rml_contents').html(response);
}
});
//jQuery(this).hide();
});
});
I've created an Arduino project wich sends the coordinates to an URL. The URL does some ajax calls. In the browser it works fine, but when I'm trying it with the Arduino it doesn't work. So I tried to do the same thing with an iOS app, but I got the same problem. This is the code on the page that the Arduino and iOS app request.
var directionsService = new google.maps.DirectionsService();
var base_url = window.location;
var received_data = <?php echo json_encode($received_data); ?>;
$.ajax({
url: 'http://gps-tracker.domain.nl/_api/handler.php',
data: { action: 'post', device_id: received_data['device_id']},
type: 'GET',
dataType:"jsonp",
jsonp:"callback",
success: function (response){
var error = [];
var total = response.length;
for (var type in response) {
if(response[type].types == 'area'){
var x = checkInsideCircle(response[type].longitude, response[type].latitude, received_data['longitude'], received_data['latitude'], response[type].reach / 1000);
if(x == false){
// Outside
error.push(true);
}else{
// Inside
error.push(false);
}
}else if(response[type].types == 'route'){
// Check route
checkOnRoute(response[type].start_latitude, response[type].start_longitude, response[type].end_latitude, response[type].end_longitude, response[type].type, response[type]['reach'], type, function(result) {
error.push(result);
if(error.length == total){
if(error.indexOf(false) >= 0){
// Device is inside route or area
outside = false;
}else{
// Send data to database
$.ajax({
url: 'http://gps-tracker.domain.nl/_api/handler.php',
data: { action: 'post', device_id: received_data['device_id'], longitude: received_data['longitude'], latitude: received_data['latitude']},
type: 'GET',
dataType: 'json',
success: function (response){
console.log('good');
},error: function(jq,status,message) {
alert('A jQuery error has occurred. Status: ' + status + ' - Message: ' + message);
}
});
}
}
});
}
}
},error: function(jq,status,message) {
alert('A jQuery error has occurred. Status: ' + status + ' - Message: ' + message);
}
});
Here is the code from the handler.php file, that the ajax request requests.
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : false;
// Switch actions
switch($action) {
case 'get':
$callback ='callback';
if(isset($_GET['callback'])){
$callback = $_GET['callback'];
}
$routes = ORM::for_table('gps_tracker_route')
->inner_join('gps_tracker_device', array('gps_tracker_device.device_id', '=', 'gps_tracker_route.device_id'))
->where('gps_tracker_route.device_id', $_GET['device_id'])
->where('gps_tracker_device.device_id', $_GET['device_id']);
if($routes = $routes->find_many()){
foreach($routes as $k=>$v){
$v = $v->as_array();
if($v['status'] == 'on' or strtotime(date('Y-m-d H:i:s')) > strtotime($v['start_time']) and strtotime(date('Y-m-d H:i:s')) < strtotime($v['end_time'])){
$response1[$k] = $v;
$response1[$k]['types'] = 'route';
}
}
}
$area = ORM::for_table('gps_tracker_area')
->inner_join('gps_tracker_device', array('gps_tracker_device.device_id', '=', 'gps_tracker_area.device_id'))
->where('gps_tracker_area.device_id', $_GET['device_id'])
->where('gps_tracker_device.device_id', $_GET['device_id']);
if($area = $area->find_many()){
foreach($area as $k=>$v){
$v = $v->as_array();
if($v['status'] == 'on' or strtotime(date('Y-m-d H:i:s')) > strtotime($v['start_time']) and strtotime(date('Y-m-d H:i:s')) < strtotime($v['end_time'])){
$response2[$k] = $v;
$response2[$k]['types'] = 'area';
}
}
}
if(isset($response1) and isset($response2)){
$response = array_merge($response1, $response2);
}elseif(isset($response1)){
$response = $response1;
}else{
$response = $response2;
}
if ( isset($response) ) {
if ( is_array($response) ) {
if (function_exists('json_encode')) {
header('Content-Type: application/json');
echo $callback.'(' . json_encode($response) . ')';
} else {
include( ABSOLUTE_PATH . '/classes/json.class.php');
$json = new Services_JSON();
echo $json->encode($response);
}
} else {
echo $response;
}
exit(0);
}else{
exit();
}
break;
case 'post':
$_GET['timestamp'] = date("Y-m-d H:i:s");
$record = ORM::for_table('gps_tracker_device_logging')->create($_GET);
$record->save();
$item = ORM::for_table('gps_tracker_device_logging')
->where('id', $record->id);
if($item = $item->find_one()){
$item = $item->as_array();
echo json_encode($item);
}
break;
default:
die('invalid call');
}
Can someone help me?
EDIT
I think it is something with Javascript. I don't know if it's possible to use javascript when a device, like Arduino, makes a http request to a server. Someone know?
I think that it's because you need a Web Browser that supports JavaScript.
I don't work with Arduino, but from what I know it does not have a "real" Web Browser - it can only pull/download data but can't execute the JS part.
For JS to work you need something to run it. That is why it works in a the browser.
I searched on google, and there are so much question about this topic on stackoverflow. Such as 'data not being sent on post method', etc.
But seem not asnwer my question
The case is almost the same with other questions. These are the error msg:
Firefox (v21) :
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable.
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
Chrome (v27) :
Uncaught Error: InvalidStateError: DOM Exception 11
When the request is sent by GET, there is no error. And all GET data received well.
But when sent by POST + setRequestHeader, itu occurs error like above. When setRequestHeader removed, the error is gone. No error, but the POST data is not received. i print_r($_POST); then the array is empty
Question Updated. Here is the caller:
goServer({
url : 'users/sign-in.php',
method : 'POST',
data : 'randomId=' + randomId + '&name=' + name + '&password=' + password,
done : function(response) {
alert(response);
},
fail : function(response) {
alert(response);
}
});
And here is the functions (sorry, long lines ):
function randomString() {
var str = new Date().getTime(),
str2 = Math.random();
str = str.toString();
str2 = str2.toString();
str2 = str2.substring(2,7);
str += str2;
return str;
}
function goServer(opts) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = requestComplete;
function requestComplete() {
if ( xhr.readyState === 4 ) {
if ( xhr.status === 200 ) {
opts.done(xhr.responseText);
} else {
opts.fail(xhr.responseText);
}
}
}
if ( !opts.method || opts.method === undefined ) {
opts.method = "GET";
}
if ( !opts.cache || opts.cache === undefined ) {
opts.cache = false;
}
if ( opts.cache === false ) {
opts.url += '?nocache=' + randomString();
} else {
opts.url += '?nocache=false';
}
if ( opts.method === "GET" ) {
if ( opts.data !== '' && opts.data !== undefined ) {
opts.url += '&' + opts.data;
}
opts.data = '';
} else {
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
xhr.open(opts.method, opts.url, true);
xhr.send(opts.data);
}
Note, the data parameter (opts.data) is set to the url when it sent by GET. When sent by POST, the paramater is set to the xhr.send(opts.data);
Question : How to get the POST data correctly?
Thank you
Call xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); after you call xhr.open
Also opts.data should be a string containing key/value pairs. e.g. key=value&method=post
Baffled... I have a file "api.php" shown below. This is called in the jquery ajax call. When I run it from the command line I get a response that appears correct (ie not empty). When I run it in the ajax call it appears to come back empty. NOW... when I comment out the "if( $td < $lessthan )" and the two braces it all works correctly (i.e., the ajax success gets correct data.
Here is my "api.php" function:
$basedir = "calls/";
$now = time();
$lessthan = 20 * 60;
$ret = array();
$dir = opendir( $basedir );
while(($currentFile = readdir($dir)) !== false)
{
if ( preg_match( '/(.*).txt/', $currentFile, $match) )
{
$tt = #file_get_contents($basedir.$currentFile);
$td = ($now - #strtotime( $tt ));
if( $td < $lessthan )
{
$ret[] = $match[1];
}
}
}
closedir($dir);
echo json_encode(implode(',', $ret));
?>
Here is my jquery ajax call:
$.ajax({
url: 'api.php',
data: "",
dataType: "json",
type: "POST",
success: function(data, textStatus, jqXHR)
{
console.log(data + ':' + previous + ' ' + textStatus );
if( data != null && data != previous && data != "" )
{ previous = data;
$('#other').hide(); //Set output element html
$('#loaddiv').fadeOut('fast').load('reload.php?q='+data).fadeIn("fast"); //Set output element html
}
if( (data == null || data == "" ) && previous != null ) {
//$('#loaddiv').fadeOut('fast').html('No Active Calls').fadeIn("fast"); //Set output element html
$('#loaddiv').fadeOut('fast'); //Set output element html
$('#other').show();
$('#other').fadeOut('fast').load('default.php').fadeIn("fast");
previous = null;
}
},
error: function(m) { alert('error'); }
});
Any ideas on why the commenting out the "if" statement in the api.php makes the whole thing work? Or better yet, how can I leave the if statement in and for it to work.