I've got a problem which I can't seem to solve.
I'm currently implementing a an AJAX-function similar to the one Twitter uses - that fetch new posts on scrolling.
The jQuery looks something like this:
$(window).scroll(function(){
if($(window).scrollTop() == $(document).height() - $(window).height()){
$('div#ajaxloader').show();
$.ajax({
url: "loader.php?lastid=" + $(".container:last").attr("id"),
success: function(html){
if(html){
$("#main").append(html);
$('div#ajaxloader').hide();
}else{
$('div#ajaxloader').html('No more posts to show.');
}
}
});
}
});
Now the problem; if the user scrolls really fast and the database is doing it's work quickly - the jQuery doesn't seem to be able to send the correct id as a query fast enough - which results in double-posts.
Anyone have a good idea on how to prevent this?
Try This:
var runningRequest = 0;
$(window).scroll(function(){
if(runningRequest <1){
if($(window).scrollTop() == $(document).height() - $(window).height()){
runningRequest++;
$('div#ajaxloader').show();
$.ajax({
url: "loader.php?lastid=" + $(".container:last").attr("id"),
success: function(html){
runningRequest--;
if(html){
$("#main").append(html);
$('div#ajaxloader').hide();
}else{
$('div#ajaxloader').html('No more posts to show.');
}
}
error: function(){runningRequest--;}
});
}
}
});
I would set a boolean to true right before making my request, and whenever the request completes I'd set it back to false. Then I'd wrap the code that makes the request in a check for whether that value is true or false. I'd also add a bool that tells me whether I should even bother making a request--no sense in requesting if the last request came back empty (unless, perhaps, the data set could change since the last request). Either way, here's the code I'd start with:
( function( global )
{
var $ = global.jQuery,
$win = $( global ),
$doc = $( global.document ),
$ajaxLoader = $( 'div#ajaxloader' ),
$main = $( '#main' ),
requestInProgress = false,
outOfPosts = false;
$win.scroll( function()
{
if( ! requestInProgress &&
! outOfPosts &&
$win.scrollTop() === $doc.height() - $win.height()
)
{
requestInProgress = true;
$ajaxLoader.show();
$.ajax( {
url: 'loader.php',
data: {
lastid: $( '.container:last' ).attr( 'id' )
},
success: function( html )
{
if( html )
{
$main.append( html );
$ajaxLoader.hide();
}
else
{
outOfPosts = true;
$ajaxLoader.html( 'No more posts to show.' );
}
},
complete: function()
{
requestInProgress = false;
}
} );
}
} );
}( window ) );
Related
I am adding a function that should be called when a button is clicked, i have a js file with the following jquery code and the ajax call :
jQuery(document).ready( function() {
function getUrlParameter(sParam){
var sPageURL = window.location.search.substring(1);
var sURLVariables = sPageURL.split('&');
for (var i = 0; i < sURLVariables.length; i++) {
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == sParam) {
return sParameterName[1];
}
}
}
jQuery('#upload_btn').click( function(e) {
e.preventDefault();
var flag = true;
var postId = getUrlParameter('preview_id');
var files = jQuery('#file_tool').prop('files');
console.log(files);
var dataS = {
'action': 'upload_button',
'preview_id': postId,
'files': files,
'set': flag
}
jQuery.ajax({
type : 'post',
url : diario.upload,
processData: false,
contentType: false,
data : dataS,
success: function(response) {
if(response.type == "success") {
console.log('jquery works');
} else console.log(response);
}
});
});
});
When i click the button the console.log shows the files obj so at least the onClick works, but just after that it shows up jquery.js:4 POST custom/wp-admin/admin-ajax.php 400. This is how my functions.php looks like :
add_action( 'wp_enqueue_scripts', 'enqueue_onClick_upload' );
//custom_js_enqueuer
function enqueue_onClick_upload() {
wp_register_script( 'onClick_upload', WP_CONTENT_URL.'/themes/microjobengine/onClick_upload.js', array('jquery') );
wp_localize_script( 'onClick_upload', 'diario', array( 'upload' => admin_url( 'admin-ajax.php' )));
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'onClick_upload' );
}
add_action('wp_ajax_upload_button', 'upload_button');
add_action('wp_ajax_nopriv_upload_button', 'upload_button');
// upload button function
function upload_button() {
$postID = $_POST['preview_id'];
if ($_POST['set']) {
if($_POST['files']['size'] === 0 )
echo "<script>console.log('There's no images.');</script>";
}
$result['type'] = 'success';
echo json_encode($result);
wp_die();
}
I have no idea why it doesn't find the action, it's all done as wp says it should, I hope somone could give a hand, thanks.
--EDIT--
Okay so now i tried to only pass 'action': 'upload_button', the error does not appear but the response doesn't get success, I did this with all the code inside my function commented and just leaving the las 3 lines, in order to return the success, but it doesn't, so it might find the function but for some reason it doesn't get performed, and of course that means something wrong happens when i pass the extra data, any thoughts about why this happens?
Sorry i wasn't getting the right thing to get feedback from the functions, i just had to delete all echos and save everything i needed into an array and returne it json encoded.
Hi all the following function will work and do exactly as I want it to but I want this to be a .post not a .get can anyone see a problem with the following? its pretty much straight from another answer on stack overflow and should work fine.
jQuery(document).ready(function() {
//This function adds a development.
jQuery('#add_dev').bind('submit', function(e) {
e.preventDefault();
var data = {
action: 'AjaxAddDev',
security: AjaxHandler.ajaxnonce,
name: jQuery('#dev_name').val(),
desc: jQuery('#dev_desc').val()
};
//alert(data['name']+data['desc']);
jQuery.get(
AjaxHandler.ajaxurl,
data,
function(response) {
// ERROR HANDLING
if (!response.success) {
// No data came back, maybe a security error
if (!response.data) {
//$('#my-answer').html('AJAX ERROR: no response');
alert("Problem adding Development");
} else {
//$('#my-answer').html(response.data.error);
alert(response.data);
}
} else {
//$('#my-answer').html(response.data);
alert("Problem adding Development");
}
}
);
});
});
The error I get when I set it to .post is:
l.send(n.hasContent && n.data || null), r = function (e, i) {
Which is line 2963 of an un-minified version of jquery
/*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license */
Can anyone point me in the right Direction?
Updated Code:
jQuery(document).ready(function() {
//This function adds a development.
jQuery('#add_dev').bind('submit', function(e) {
e.preventDefault();
var data = {
action: 'AjaxAddDev',
security: AjaxHandler.ajaxnonce,
name: jQuery('#dev_name').val(),
desc: jQuery('#dev_desc').val()
};
//alert(data['name']+data['desc']);
jQuery.ajax({
url: AjaxHandler.ajaxurl,
type: "POST",
data: data,
success:function(data) {
// This outputs the result of the ajax request
alert(data);
},
error: function(errorThrown){
alert(errorThrown['error']);
}
});
});
});
I am using firefox latest version,
I got the following returned as an errotThrowen['error']
function () {
if (l) {
var t = l.length;
(function i(t) {
x.each(t, function (t, n) {
var r = x.type(n);
"function" === r ? e.unique && p.has(n) || l.push(n) : n && n.length && "string" !== r && i(n)
})
})(arguments), n ? o = l.length : r && (s = t, c(r))
}
return this
}
if you want to ajax on change
$("#yourid").change(function () {
var p = {
postfieldname: value,
postfieldname: value,
postfieldname: value,
postfieldname: value,
postfieldname: value,
postfieldname: value,
postfieldname: value,
}
$.ajax({
url: "library/test.php",
type: "POST",
data: p,
success: function (e) {
var t = jQuery.parseJSON(e);
$("#id").val(t['a']);
}
})
})
and on test.php
$array = array("a" => "test", "b" => "array");
$encode = json_encode($aray);
echo $encode;
OK this was kind of an odd one,
To get it working I simply had to add the following as the post URL.
url: AjaxHandler.ajaxurl+"&security="+AjaxHandler.ajaxnonce,
If I left the security out of the url it would fail, I don't know why but this had me going around in circles for hours.
I would like to know the best way to send this array of favorites to php, Im trying to use ajax, but I keep getting a 403 forbidden error. The path is correct, I must be doing something wrong here, any help would be greatly appreciated.
$(function(){
var favorite = localStorage.getItem( 'favorite' );
if (favorite !== null){
favorite = JSON.parse(favorite) || [];
}
$('.favorites' ).each(function() {
var petid = $(this).attr('data-petid');
if(favorite.indexOf(petid) !== -1){
$(this).css('background-image', 'url(../assets/img/heart-red.svg)');
$(this).css('background-color', '#fefefe');
}
});
// This function changes the color of the heart on the landing page and stores the values into local storage
$(".favorites").click(function() {
var favorite = localStorage.getItem( 'favorite' );
var petid = $(this).attr('data-petid');
var index;
favorite = JSON.parse(favorite) || [];
if ((index = favorite.indexOf(petid)) === -1) {
favorite.push(petid);
$(this).css('background-image', 'url(../assets/img/heart-red.svg)');
$(this).css('background-color', '#fefefe');
}else {
$(this).css('background-image', 'url(../assets/img/heart-full.svg)');
$(this).css('background-color', '#25aae3');
favorite.splice(index, 1);
}
localStorage.setItem('favorite', JSON.stringify(favorite) );
$.ajax({
type: "POST",
url: '/petlist/fuel/app/views/site/favorites.php',
data: favorite,
success: function(response){
console.log(response);
}
});
});
});
For ajax calls in Fuel, use a controller that extends Controller_Rest
Your ajax request should look like this.
$.post('/petlist/fuel/app/views/site/favorites.php', { "favorite" : favorite }, function(data) {
console.log(data);
});
Then in PHP, you can access the data via
print_r($_POST['favorite']);
I am sure this is probably something simple that i am not doing. Running livevalidation.js jquery plugin (livevalidation.com). It provides for custom function callbacks. I am trying to check for username availability. The server side is working fine and I am getting the proper responses back in my data var...
Here is my JS:
Validate.Username = function(value, paramsObj) {
var paramsObj = paramsObj || {};
var message = paramsObj.failureMessage || "Username is not available";
var isSuccess = true;
$.post("<?php echo fURL::getDomain(); ?>/ajax/username",
function(data) {
if (data.status === 'notavailable')
{
Validation.fail('oops, not available.');
}
});
};
I am calling it using:
var username = new LiveValidation('username', { validMessage: curr_username + "is available!" });
username.add( Validate.Presence, { failureMessage: "Choose a username" });
username.add( Validate.Username, { failureMessage: "Username is not available." } );
The problem I am getting is:
Uncaught ReferenceError: Validation is not defined
If I put the Validation.fail() outside of my .post() function it works fine. So am pretty sure it is because it's not able to be referenced inside the .post() function.
I've tried using a callback function
if (data.status === 'notavailable')
{
status_not_available();
}
I get the same error.
I realize this is something probably extremely simple, but any help would be appreciated. Thank you in advance.
i am having the same issue.
Ive found the following, http://forum.jquery.com/topic/ajax-return-value-on-success-or-error-with-livevalidation but have not been able to get it working.
BUT YES! At this very moment i made som (crappy) javascript addon that made it behave, i think :)
This is what i use.
function check_avail(name, id, postUrl)
{
var dataVal = name+'='+$(id).val();
var isaccepted = ''
$(id).next('div').remove();
$(id).after("Undersøger om "+name+" er ledigt");
$.ajax({
url: postUrl,
cache: false,
type: 'post',
dataType: 'json',
data: dataVal,
async: false,
success: function(data) {
if( data.success == 'true' )
{
$('#'+name+'-availability').remove();
//return false;
isaccepted = false;
}
if( data.success == 'false' )
{
$('#'+name+'-availability').remove();
// name.destroy();
isaccepted = true;
}
}
});
if (isaccepted == false) {
return false;
} else{
return true
};
}
And
f1.add( Validate.Custom, { against: function() {
return check_avail( 'brugernavn', '#ft001', 'usernamecheck.asp' );
}, failureMessage: 'Brugernavnet er optaget' } );
Hope it helps you :)
The json query you can read about on the link in the begining :)
(I am not at all skilled at javascript, and the "isaccepted" solution could problalby be made a lot better)
try to change it from Validation.fail to Validate.fail
try wrapping it in another function and try putting your validateStatus(status) function both inside and outside your Validate.Username function. example below is inside
Validate.Username = function(value, paramsObj) {
var paramsObj = paramsObj || {};
var message = paramsObj.failureMessage || "Username is not available";
var isSuccess = true;
$.post("<?php echo fURL::getDomain(); ?>/ajax/username",
function(data) {
validateStatus(data.status);
});
function validateStatus(status){
if (status === 'notavailable'){
Validate.fail("not available");
}
}
};
Basically I was trying to replicate one of the things that xajax gave me with Jquery -> The ability to define what my response modifies server side without setting anything up client side. Works perfectly as is, but each time I want to call a different Jquery function, I have to add it to my if statements.
Each element in the response array contains something to be changed client side.
I should be able to take out almost all of the this.action == 'blah' if statements and replace with some clever javascript, but apparently I'm not clever enough. :)
$.showMessage is simply my replacement for alert, with a timeout and sticky bit.
My client Jquery function:
$.doAjax = function(func,values) {
$.ajax({ data: values, url: '/time/ajax/' + func, type: 'POST', dataType: 'json', timeout: 5000,
error: function(xhr, ajaxOptions,thrownError){ $.showMessage('Error processing request: ' + func,10000);$('#debug').html(xhr.responseText); },
success: function(data){
if(data){
$.each(data, function(){
if ( this.action == 'attr' ) $(this.target).attr(this.content);
if ( this.action == 'removeAttr' ) $(this.target).removeAttr(this.content);
if ( this.action == 'addClass' ) $(this.target).addClass(this.content);
if ( this.action == 'removeClass' ) $(this.target).removeClass(this.content);
if ( this.action == 'html' ) $(this.target).html(this.content);
if ( this.action == 'text' ) $(this.target).text(this.content);
if ( this.action == 'val' ) $(this.target).val(this.content);
if ( this.action == 'eval' ) {
try {
eval(this.content);
}
catch(err) {
$.showMessage(err,5000);
};
};
});
}
}
});
return this;
};
My server side code:
header("Content-type: text/plain");
$response = array();
$response[] = array('action'=>'html','target'=>'#booked_time_group_unbilled','content'=>get_booked_time_group_unbilled());
$response[] = array('action'=>'html','target'=>'#booked_time_my_unbilled','content'=>get_booked_time_my_unbilled());
$response[] = array('action'=>'eval','target'=>'','content'=>"$.showMessage('The selected time has been deleted',5000,true)");
echo json_encode($response);
This should work:
$(this.target)[this.action](this.content);
I'm not exactly sure what you're asking? Stylistically, I would write it like this:
var handlers = {
attr: function() { $(this.target).attr(this.content) },
removeAttr: function() { $(this.target).removeAttr(this.content) },
// etc.
};
$.each(data,function() {
handlers[this.action].call(this);
});
If you just want to execute whatever the server sends back, which not just always send back an eval action?