Update the DOM using One AJAX Call in WordPress - javascript

I update vote count on the content of a post, but I also have a widget that has counts of votes on each post. When the user clicks on the vote on a post, the vote counts
in each post of the widget does not get updated.
I wrote an AJAX function that calls function through actions like so
// AJAX function file ajax-vote-on-post.js
function voteOnPost(postId) {
jQuery.ajax({
type: 'POST',
url: voteonpostajax.ajaxurl,
data: {
action: 'addvote-to-post',
postid: postId
},
success: function(data, textStatus, XMLHttpRequest) {
var votecontainerid = '#vote-count-' + postId;
jQuery(votecontainerid).html('');
jQuery(votecontainerid).append(data);
},
error: function(MLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
}
I properly registered the ajax file to be called by WP in a Widget file that contains other functions and PHP codes.
...
// function in the PHP file that is called.
function addvote-to-post(){
$result = '';
// get vote count from DB
$post_ID = $_POST['postid'];
$votepostcount = get_post_meta($post_ID, '_votepostcount', true) != '' ? get_post_meta($post_ID, '_votepostcount', true) : '0';
// Code that updates the DB in WordPress does other things
...
// Output count on the DOM
$votecountnew = $votepostcount + 1;
$result = '<div class="vote-count-'.$post_ID.'" >'.$votepostcountNew.'</div>'
// update_all_count_for_post($post_ID, $votecountnew);
die($result);
}
The page load slowly and how best to update the DOM without using an extra function.
class MyVotePostWidget extends WP_Widget {
// Widget Front End
public function widget {
// HTML code to display posts with votes
}
}

Related

Chance ACF Field with Javascript over a php function

I want to write the dropdown-change into to an ACF field.
i have a ninja table with a dropdown and i added this code on dropdown:
<?php
wp_register_script( 'custom-acf-js', get_template_directory_uri() . '/library/scripts/script-js.js', ['acf-input'], '1.0.0', true);
wp_enqueue_script('custom-acf-js');
function feldUpdate($selector,$value,$post_id){
update_field('bewerber_einstufen', $value , $post_id );
};
//feldUpdate('bewerber_notiz','eingeladen', 192);
?>
<script type="text/javascript">
// Ninja Table Loaded initially
jQuery(document).on('ninja_table_loaded', function (event, $table, settings) {
console.log('ninja_table_loaded');
let changeButton = document.querySelectorAll('select');
var acfVersion = acf.get('acf_version');
//alert(acfVersion);
for(let i=0; i < changeButton.length; i++){
changeButton[i].addEventListener("change",function(){
let rowidparent = this.parentElement.parentElement;
let rowid = (rowidparent.querySelector("p").innerHTML);
console.log(rowid);
//feldUpdate('bewerber_notiz','eingeladen', rowid);
});
};
});
</script>
So how can i write the javascript code (variables) into my php function.
Kind regards, Daniel
You cannot call a PHP function directly with JavaScript like that. PHP is executed by the server and JavaScript is executed by the browser (in this context anyway)
To achieve what you want here you need to use Ajax. Which is the front-end making a http request to the server and then the server will call your PHP function and return an appropriate response.
Creating the Ajax endpoint for WordPress
<?php
// functions.php
add_action('wp_ajax_call_feld_update', 'feldUpdateCallback');
add_action('wp_ajax_nopriv_call_feld_update', 'feldUpdateCallback'); // nopriv for unauthenticated users
/**
* Ajax call for updating bewerber_einstufen field
*
* #return void
*/
function feldUpdateCallback(): void {
}
So now you have an ajax endpoint you can call from your JavaScript. Now you need to setup the front end and have WordPress create a nonce for you, which is essentially the way you ensure the request came from the front-end of your own website.
<script type="text/javascript">
var wp_nonce = '<?= wp_create_nonce('updating-field-nonce'); ?>';
var ajax_url = '<?= admin_url('admin-ajax.php'); ?>';
// Ninja Table Loaded initially
jQuery(document).on('ninja_table_loaded', function (event, $table, settings) {
// your code was here
});
</script>
Now the JavaScript variable wp_nonce will have have the nonce stored in it and the ajax_url will have the url for ajax stored in it. This is normally achieved with wp_localize_script however this is a simplified example for you.
Now you can create your ajax request like so
jQuery(document).on('ninja_table_loaded', function (event, $table, settings) {
console.log('ninja_table_loaded');
let changeButton = document.querySelectorAll('select');
var acfVersion = acf.get('acf_version');
//alert(acfVersion);
for(let i=0; i < changeButton.length; i++){
changeButton[i].addEventListener("change",function(){
let rowidparent = this.parentElement.parentElement;
let rowid = (rowidparent.querySelector("p").innerHTML);
console.log(rowid);
// ajax request
jQuery.ajax({
type: "POST",
url: ajax_url,
data: {
action: 'call_feld_update', // the action is set when you added wp_ajax_ at the beginning of this answer.
postId: rowid,
value: 'eingeladen',
nonce: wp_nonce
},
success: function (response) {
console.log(response);
},
error: function (jqxhr, textStatus, errorThrown) {
console.log(errorThrown);
}
});
});
};
});
With that, WordPress will call the feldUpdateCallback function when the ajax request is sent. Now we update the PHP function that was created before so it can deal with that request...
// functions.php
/**
* Ajax call for for updating bewerber_einstufen field
*
* #return void
*/
function feldUpdateCallback(): void {
// nonce - The key you set when sending the request from ajax
// updating-field-nonce - The parameter for the wp_create_nonce function
if (!wp_verify_nonce($_REQUEST['nonce'], 'updating-field-nonce')) {
// The string we received does not match the nonce that was set on the front by WP
die('nonce validation failed');
}
// now you can deal with the request...
feldUpdate(
'bewerber_notiz',
sanitize_text_field($_REQUEST['value']), // https://developer.wordpress.org/reference/functions/sanitize_text_field/
sanitize_text_field($_REQUEST['postId'])
);
die('successful');
}

AJAX + PHP function inside class

I'm using MVC pattern in my project and I have controller product with method delete($slug)
On my page (~/show/basket) I have products that user wants to buy. There's a 'delete' button and when he clicks on that button I want to delete that product from SESSION and remove from current page.
I was trying with jquery ajax function:
$(document).ready(function() {
$('.on-delete').on('click', function() {
var path = '/ITAKADEMIJA_zavrsni_rad/3-itcomm/';
var slug = $(this).data('slug');
$.ajax({
url: $(location).attr('host') + path + 'product/delete/' + slug,
success: function(res) {
console.log(res);
},
error: function(err) {
console.log('ERROR!');
}
});
});
});
and then I have a method delete inside product controller
public function delete($slug)
{
$cardModel = $this->model('Card');
if ($slug === null) {
header("Location:" . BASE_ROOT . '/show/products');
} else if ($cardModel->getProduct($slug)) {
$product = $cardModel->getProduct($slug);
$cardModel->removeProduct($product);
header("Location: " . BASE_ROOT . '/show/basket');
}
}
public function removeProduct($product)
{
if (isset($_SESSION['products'][$product->slug]))
{
unset($_SESSION['products'][$product->slug]);
}
}
Now the problem is:
I'm getting this error:
Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'App\Controllers\Show' does not have a method 'index' in C:\Users\nikol\Dropbox\www\ITAKADEMIJA_zavrsni_rad\3-itcomm\app\Core\App.php on line 50
Nothing happens, that product is still in session. It looks like that function wasn't even called.
I would like to call the function, that function should remove product from session and from that page.

how can I trigger javascript css action?

I have a memory game code, using javascript, php and css.
I would like to register somehow the event when the game is finished by php so that I can save the results in database.
In other words I would like to place php code inside <div id="player_won"> </div> and trigger that winning event properly.
css
#player_won{
display: none;
}
javascript
$(document).ready(function(){
$(document).bind("game_won", gameWon);
}
function gameWon(){
$.getJSON(document.location.href, {won: 1}, notifiedServerWin);
var $game_board = $("#game_board");
var $player_won = $("#player_won");
$game_board.hide();
$player_won.show();
$game_board = $player_won = null;
};
You'll want to create an ajax call that sends some information from the page and tells the php file below if the player has won or lost. After which you can deal with the logic needed for the player inside foo.php and send back Json to the success function inside the ajax call and update your page accordingly.
index
$(document).ready(function () {
//look for some kind of click below
$(document).on('click', '#SomeId', function () {
//Get the information you wish to send here
var foo = "test";
$.ajax({
url: "/foo.php",
type: 'POST',
cache: false,
data: {Info: foo},
dataType: 'json',
success: function (output, text, error)
{
//here is where you'll receive the son if successfully sent
if(ouput.answer === "yes"){
$("#player_won").show();
} else {
// Do something else
}
},
error: function (jqXHR, textStatus, errorThrown)
{
//Error handling for potential issues.
alert(textStatus + errorThrown + jqXHR);
}
})
})
});
foo.php
<?php
if(isset($_POST['Info'])){
//figure out if what was sent is correct here.
if($_POST['Info'] === "test"){
$data['answer'] = "yes";
echo json_encode($data);
exit;
} else {
// do something else
}
}
?>

"Long Polling" simulation holding up entire web page

Brief Overview
I have a turn-based web app that puts a 60 second limit per turn, unless they end their turn before 60 seconds, whereby the next user's turn begins.
It works by preventing the production of data on the PHP page by way of a while statement which checks for new data, produces it if it exists, or sleeps and resets if it doesn't:
while($olddata === $newdata){
sleep(2);
/* get new data and repeat */
}
I got this concept from these StackOverflow questions:
How do I implement basic "Long Polling"?
Ajax push system
Issue
However, once the callout begins, the page becomes relatively unresponsive; doing something simple such as refreshing the page will not work until the timeout is complete or new data is received.
How can I configure this code so that the page remains responsive while awaiting new data?
AJAX/jQuery code
function draftPing(){
//This $holder element holds the data including the
//row ID, which is used to determine which turn number
//we are on
var $holder = $("#data-holder");
var currID = $holder.attr("data-currID");
$.ajax({
type: "POST",
url: "../inc/draft-ping.php",
data: { currID : currID },
async: true,
cache: false,
timeout: 60000,
success: function(data) {
var jsonData = $.parseJSON(data);
//Update $holder with new turn ID
$holder.attr("data-currID", jsonData[0]);
/* Do stuff with data */
updateDeadline(jsonData[1]);
updateTeam(jsonData[3]);
updateDraft(jsonData[4]);
/* Begin the next call for new information (wait 1s)*/
setTimeout(
draftPing,
1000
);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Draft retrieve error: ", textStatus + " (" + errorThrown + ")");
setTimeout(
draftPing, /* Try again after 5s*/
5000);
}
});
}
PHP Code
<?php
session_start();
require_once("../config.php");
require_once("classes.php");
require_once("functions.php");
$postedID = $_POST["currID"];
$draft = new Draft($user->getLeagueID());
$currID = $draft->getCurrDraftRow();
//This is the "long polling" simulation...
//the AJAX callback won't produce any information
//until the current ID is different to the ID
//on the page with the AJAX post function
while($currID == $postedID){
sleep(2);
$currID = $draft->getCurrDraftRow();
}
/* Get all the data - redacted because it's not important (and it works) */
//Output all the data as one JSON object
exit(json_encode(array($nid, $ndeadline, $nuserid, $fteam, $fdraft)));
If you opened a session with session_start() better close it with session_write_close() before you start waiting, or access to the session will be blocked in all other requests.
<?php
session_start();
require_once("../config.php");
require_once("classes.php");
require_once("functions.php");
$postedID = $_POST["currID"];
$draft = new Draft($user->getLeagueID());
$currID = $draft->getCurrDraftRow();
//This is the "long polling" simulation...
//the AJAX callback won't produce any information
//until the current ID is different to the ID
//on the page with the AJAX post function
while($currID == $postedID){
session_write_close(); //added
sleep(2);
session_start(); //if needed, doesn't look like it is though
$currID = $draft->getCurrDraftRow();
}
/* Get all the data - redacted because it's not important (and it works) */
//Output all the data as one JSON object
exit(json_encode(array($nid, $ndeadline, $nuserid, $fteam, $fdraft)));

how to get ajax return id in hidden variable....on request page

I need to get last insert id from controller to ajax success function......
I want to customize product and when user press add to cart ajax is executed and design is going to insert on database....
And after inserting in database i m getting last insert id.....on insert...
but need last insert id....when user press on add to cart button in hidden field...
here is my Ajax code.
$('#store').click(function(){
$.ajax({
type: "POST",
url: ajax_url_store,
data: {action: 'store', views: JSON.stringify(thsirtDesigner.getProduct()) },
success: function(data) {
if(parseInt(data) > 0) {
//successfully added..here i am getting last insert id...
// and i want to pass that in hidden variable.....
// on view page.....
}
else {
document.getElementById('succes-message').innerHTML = 'You Design has not Been Saved';
}
},
error: function() {
//alert('some error has occured...');
},
start: function() {
//alert('ajax has been started...');
}
});
});
my CI controller
public function saveData(){
if($this->input->post('action') == 'store') {
$views = $this->input->post('views');
$id = $this->product_model->save($views);
$data = array('cust_id'=>$id);
$this->session->set_userdata($data);
if($id !=''){
header('Content-Type: application/json');
echo json_encode($id);
}
}
}
$this->db->insert_id() returns the last id.
After your insertion operation in model, use following code
$this->db->insert_id();
this will give you id where last insert done.
Documentation

Categories