Wordpress Ajax call only works with console.log debugging - php

So I am building a user profile section in front-end Wordpress, and loading different content dynamically in jQuery tabs to break up the UI a bit. I early on switched from loading this all in on page load to using ajax to call in the php files for the user profile only on demand.
This was not working so I added a console.log to the success action to see what is going on. Funnily this function works to load in the php files, but ONLY IF I have console.log enabled. To be clear, when I check the network tab under XHR requests, both with console.log and without console.log I get a 200 status back from the server, it just doesn't render if I am not declaring that success action to the console.
Any ideas why?
$('.profileTabs ul li a').click(function(e) {
e.preventDefault();
var tab_id = $(this).attr('id');
$.ajax({
type: "GET",
url: cyberAjax.ajaxurl,
dataType: 'html',
data: ({
action: 'ajax_load_tabs', id: tab_id
}),
success: function(data){
$('#tab'+tab_id).html(data);
console.log( $('#tab-'+tab_id).html(data) );
},
error: function(data)
{
alert("Error!");
return false;
}
});
});
For reference, my approach was influenced by this article.
So I have the below in my functions.php - this all works with console.log so I don't think the cause lies here:
function ajax_load_tabs() {
$tab_id = $_GET['id'];
if ($tab_id == 'ui-id-7') {get_template_part( '/page-templates/dashboard/broker-dashboard', 'onboarding' );}
elseif ($tab_id == 'ui-id-8') {get_template_part( '/page-templates/dashboard/broker-dashboard', 'tasks' );}
elseif ($tab_id == 'ui-id-9') {get_template_part( '/page-templates/dashboard/broker-dashboard', 'incidents' );}
die();
}
add_action('wp_ajax_ajax_load_tabs', 'ajax_load_tabs');
add_action('wp_ajax_nopriv_ajax_load_tabs', 'ajax_load_tabs');

Related

send data by Jquery ajax to same php

i need help because i'm stuck and don't know what's wrong ,i try to send user clicked button "id" to php to get related data from database in the same page
$(".button_class").on("click", function() {
ToEditId = $(this).attr('id');
console.log(ToEditId ); //to check clicked id is Ok
$.ajax({
type: "POST",
url: same/php/page/path,
data: {
ToEditId: ToEditId
},
success: function(res, data) {
console.log(res, data);
},
error: function(err) {
alert(err);
}
});
});
the ajax print success in console log ,here is php code to get the value if clicked id
<?php
if(isset($_POST['ToEditId'])){
$to_edit_id=$_POST['ToEditId'];
var_dump($to_edit_id);
}
but nothing happen in php file !!
Which is the expected behaviour.
PHP is not dynamic. It doesn't "update".
PHP only runs once. This means that once your page is rendered, you cannot use PHP to change it again. You actually would have to use javascript to change the page, like so;
PHP side:
<?php
if(isset($_POST['ToEditId'])){
echo $_POST['ToEditId'];
$to_edit_id=$_POST['ToEditId'];
var_dump($to_edit_id);
die(); // prevent entire page from re-rendering again.
}
JS side:
$(".button_class").on("click", function() {
ToEditId = $(this).attr('id');
console.log(ToEditId ); //to check clicked id is Ok
$.ajax({
type: "POST",
url: same/php/page/path,
data: {
ToEditId: ToEditId
},
success: function(res, data) {
//Add your PHP file's response to the body through javascript.
$('body').append(res);
},
error: function(err) {
alert(err);
}
});
});
As #IncredibleHat mentioned, you should make sure your page doesn't render any of its usual HTML, so it won't return the entire page back to your ajax call. So put the PHP all the way above your html!

jQuery ajax request awkward issue

So I have this ajax request. When the user clicks an edit link, I fetch the ID of the entry and refresh the page with the data of that entry loaded into a form.
Here's my problem: This only works with the alert showing before the ajax call. When I leave out the alert, I get an ajax error (though the id is being posted) and the PHP page just reloads. Moreover, it only works when I put the newDoc stuff as a success callback. The exact same lines as a complete callback and the page reloads. Moreover, this occurs in Firefox only.
jQuery('a.edit').on('mousedown', function (e) {
e.preventDefault();
var id = jQuery(this).attr('data-title');
alert('test');
jQuery.ajax({
url: document.location,
data: {
id: id
},
success: function (data) {
var newDoc = document.open("text/html", "replace");
newDoc.write(data);
newDoc.close();
},
error: function () {
alert('error');
}
});
});
What can I do?
EDIT: This must be a timing issue. I just noticed that when I click and hold the edit link for a second or so, everything works fine. When I do a short click, it doesn't. So I tried wrapping the ajax in setTimeout(), but that didn't help. Any other ideas?
Try to use location.href in place of document.location,
jQuery.ajax({
url: location.href,
data: {
id: id
},
success: function (data) {
var newDoc = document.open("text/html", "replace");
newDoc.write(data);
newDoc.close();
},
error: function () {
alert('error');
}
});
location is a structured object, with properties corresponding to the parts of the URL. location.href is the whole URL in a single string.
Got it!
The problem is the way Firefox handles the mousedown event. It seems to abort the ajax call as soon as you relase the mouse button. I changed the event to click and everything is fine now.
jQuery('a.edit').on('click', function () {
var id = jQuery(this).attr('data-title');
jQuery.ajax({
url: document.location,
data: {
id: id
},
success: function (data) {
var newDoc = document.open("text/html", "replace");
newDoc.write(data);
newDoc.close();
}
});
});

Issue with using a value in JQuery/Javascript

I have a PHP populated table from Mysql and I am using JQuery to listen if a button is clicked and if clicked it will grab notes on the associated name that they clicked. It all works wonderful, there is just one problem. Sometimes when you click it and the dialog(JQuery UI) window opens, there in the text area there is nothing. If you are to click it again it will pop back up. So it seems sometimes, maybe the value is getting thrown out? I am not to sure and could use a hand.
Code:
$(document).ready(function () {
$(".NotesAccessor").click(function () {
notes_name = $(this).parent().parent().find(".user_table");
run();
});
});
function run(){
var url = '/pcg/popups/grabnotes.php';
showUrlInDialog(url);
sendUserfNotes();
}
function showUrlInDialog(url)
{
var tag = $("#dialog-container");
$.ajax({
url: url,
success: function(data) {
tag.html(data).dialog
({
width: '100%',
modal: true
}).dialog('open');
}
});
}
function sendUserfNotes()
{
$.ajax({
type: "POST",
dataType: "json",
url: '/pcg/popups/getNotes.php',
data:
{
'nameNotes': notes_name.text()
},
success: function(response) {
$('#notes_msg').text(response.the_notes)
}
});
}
function getNewnotes(){
new_notes = $('#notes_msg').val();
update(new_notes);
}
// if user updates notes
function update(new_notes)
{
$.ajax({
type: "POST",
//dataType: "json",
url: '/pcg/popups/updateNotes.php',
data:
{
'nameNotes': notes_name.text(),
'newNotes': new_notes
},
success: function(response) {
alert("Notes Updated.");
var i;
$("#dialog-container").effect( 'fade', 500 );
i = setInterval(function(){
$("#dialog-container").dialog( 'close' );
clearInterval(i);
}, 500);
}
});
}
/******is user closes notes ******/
function closeNotes()
{
var i;
$("#dialog-container").effect( 'fade', 500 );
i = setInterval(function(){
$("#dialog-container").dialog( 'close' );
clearInterval(i);
}, 500);
}
Let me know if you need anything else!
UPDATE:
The basic layout is
<div>
<div>
other stuff...
the table
</div>
</div>
Assuming that #notes_msg is located in #dialog-container, you would have to make sure that the actions happen in the correct order.
The best way to do that, is to wait for both ajax calls to finish and continue then. You can do that using the promises / jqXHR objects that the ajax calls return, see this section of the manual.
You code would look something like (you'd have to test it...):
function run(){
var url = '/pcg/popups/grabnotes.php';
var tag = $("#dialog-container");
var promise1 = showUrlInDialog(url);
var promise2 = sendUserfNotes();
$.when(promise1, promise2).done(function(data1, data2) {
// do something with the data returned from both functions:
// check to see what data1 and data2 contain, possibly the content is found
// in data1[2].responseText and data2[2].responseText
// stuff from first ajax call
tag.html(data1).dialog({
width: '100%',
modal: true
}).dialog('open');
// stuff from second ajax call, will not fail because we just added the correct html
$('#notes_msg').text(data2.the_notes)
});
}
The functions you are calling, should just return the result of the ajax call and do not do anything else:
function showUrlInDialog(url)
{
return $.ajax({
url: url
});
}
function sendUserfNotes()
{
return $.ajax({
type: "POST",
dataType: "json",
url: '/pcg/popups/getNotes.php',
data: {
'nameNotes': notes_name.text()
}
});
}
It's hard to tell from this, especially without the mark up, but both showUrlInDialog and sendUserfNotes are asynchronous actions. If showUrlInDialog finished after sendUserfNotes, then showUrlInDialog overwrites the contents of the dialog container with the data returned. This may or may not overwrite what sendUserfNotes put inside #notes_msg - depending on how the markup is laid out. If that is the case, then it would explains why the notes sometimes do not appear, seemingly randomly. It's a race condition.
There are several ways you can chain your ajax calls to keep sendUserOfNotes() from completing before ShowUrlInDialog(). Try using .ajaxComplete()
jQuery.ajaxComplete
Another ajax chaining technique you can use is to put the next call in the return of the first. The following snippet should get you on track:
function ShowUrlInDialog(url){
$.get(url,function(data){
tag.html(data).dialog({width: '100%',modal: true}).dialog('open');
sendUserOfNotes();
});
}
function sendUserOfNotes(){
$.post('/pcg/popups/getNotes.php',{'nameNotes': notes_name.text()},function(response){
$('#notes_msg').text(response.the_notes)
},"json");
}
James has it right. ShowUrlInDialog() sets the dialog's html and sendUserOfNotes() changes an element's content within the dialog. Everytime sendUserOfNotes() comes back first ShowUrlInDialog() wipes out the notes. The promise example by jeroen should work too.

Keep jQuery accordion state on postback with PHP

I am using jQuery UI's accordion as a subnav on a site I am building. The problem is that I haven't been able to find a good way to maintain state between pages. I'm wondering what the best way to do this is.
I've thought of storing the index of the accordion in the database, but that seems overly complicated for a problem like this. Is there a better way? Obviously cookies and session but that is equally complicated for just a subnav...any ideas?
EDIT: Here's my code
$.post(
accordion_ajax.ajaxurl,
{
type : 'GET',
action : 'accordion_ajax'
},
function(data){
$(".accordion-main").accordion('option', 'collapsible', true);
$(".accordion-main").accordion('option', 'active', 0);
// the accordion just does not work inside this ajax call, but if I put it outside the ajax call it works fine. Any thoughts?
}
);
$(".accordion-main").accordion({
change: function(event, ui){
$.post(
accordion_ajax.ajaxurl,
{
type : 'SET',
action : 'accordion_ajax',
data : $(".accordion-main").accordion('option', 'active')
}
);
}
});
Here's what I would do:
In the change() handler for the accordion, I would send the index of the current accordion section to the server via an AJAX call:
$( "#AccordionID" ).accordion({
change: function(event, ui) {
$.ajax({
type:'POST',
url: 'urlToPhpScript.php',
data:'function=setAccordion&selectedAccordionSection='+ $("#AccordionID").accordion('option', 'active')
});
}
});
On the server side I would store this value in the users session:
<?php
// urlToPhpScript.php
session_start();
if($_GET['function']=='getAccordion') {
if(isset($_SESSION['currentAccordion'])) {
return $_SESSION['currentAccordion'];
} else {
return 0;
}
}
if($_POST['function']=='setAccordion') {
$_SESSION['currentAccordion'] = $_POST['AccordionID'];
}
Then on each page load I would send an AJAX call to the server that would query the accordion section from the users session:
$(document).ready(function () {
$.ajax({
type: 'GET',
url: 'urlToPhpScript.php',
data: 'function=getAccordion',
success: function(data) {
$('#AccordionID').accordion('activate', data);
}
});
});
This way it wouldn't matter how you're navigating from one page to the next, and you wouldn't need to worry about burying a 'currentAccordion' type hidden field on each page of your site.

AJAX call not firing

In the below code from my .js file, the first function save_audition is working great. The second one, which I just copy/pasted and changed some variables is not,f or some reason. I've done some troubleshooting and ruled out my .php file (which works fine when called manually) as well as the .html and determined that this script just isn't firing for some reason.
This is my first ever project using AJAX, so it could be something very simple, not sure. FYI, I'm working within Wordpress's AJAX framework using admin-ajax.php
EDIT: Here is a pastebin to the main plugin file: http://pastebin.com/AaJ6QqTx
Here is the code from the .js file. The first on('click') event (save_audition) is working fine, the 2nd (hide_audition) is working in the sense the return false; works to prevent the link from firing, but the actual AJAX click event isn't happening.
//Save (or remove) an audition from the user's saved auditions meta using ajax
$('.save-audition').on('click', function() {
var post_id = $(this).attr('data-post_id');
var nonce = $(this).attr('data-nonce');
var clicked = $(this);
$.ajax({
type : 'post',
dataType : 'json',
url : myAjax.ajaxurl, //we can use this value because in our php file we used wp_localize_script
data : {action: 'tps_save_audition', post_id : post_id, nonce: nonce},
success: function(response) {
$('#alerts').append('<div class="alert"><div class="alert-icon"><i class="fa fa-exclamation"></i></div><div class="alert-message">'+response.message+'</div><div class="close"><i class="fa fa-close"></i></div></div>');
$('#alerts .alert').fadeIn(400);
if(response.type == 'success') {
clicked.children('span').children('.fa-stack-2x').addClass('fa-check');
clicked.children('span').children('.fa-stack-1x').addClass('saved');
} else if (response.type = 'removed') {
clicked.children('span').children('.fa-stack-2x').removeClass('fa-check');
clicked.children('span').children('.fa-stack-1x').removeClass('saved');
} else {
alert(response.message);
}
}
})
return false;
});
//Hide an audition from the user's view by saving it as user_meta
$('.hide-audition').on('click', function() {
var post_id = $(this).attr('data-post_id');
var nonce = $(this).attr('data-nonce');
var clicked = $(this);
$.ajax({
type : 'post',
dataType : 'json',
url : myAjax.ajaxurl, //we can use this value because in our php file we used wp_localize_script
data : {action: 'tps_hide_audition', post_id : post_id, nonce: nonce},
success: function(response) {
$('#alerts').append('<div class="alert"><div class="alert-icon"><i class="fa fa-exclamation"></i></div><div class="alert-message">'+response.message+'</div><div class="close"><i class="fa fa-close"></i></div></div>');
$('#alerts .alert').fadeIn(400);
if(response.type == 'success') {
clicked.children('i').css('color', 'red');
} else {
alert(response.message);
}
}
})
return false;
});
OK well, as usual it comes down to a stupid coder error. In my html I had TWO elements with the class "hide-audition" by accident and that was breaking it.
I guess I'll leave this question up for others as a reminder to comb through every piece of code carefully while troubleshooting.

Categories