Disable downlaod link after 5 time clicks Wordpress | Javascripts | Ajax - javascript

I am creating a custom wordpress theme and what i want is that; there is a download link, what i want is that users can download only 5 times when the user clicks that link only for 5 times, if the user tries to click the link for the 6th time it automatically hides. I dont have any idea how to do this, also didn't find any relevant solution on google.
here below is my testing code:
<script type="text/javascript">
function myFunction() {
$(document).ready(function(){
$(".gotocls").click(function(){
alert("Hello! I am an alert box!!");
});
});
}
</script>
<a class="dkpdf-button gotocls" onclick="myFunction()" href="downlaod/image.com" target="_blank"><span class="dkpdf-button-icon"><i class="fa fa-file-pdf-o"></i></span> <?php echo $pdfbutton_text;?></a>
i think this might be done with ajax, but i dont have much knowledge of ajax

you don't need onClick in this code I add document.getElementsByClassName('gotocls')[0].style.display = 'none'; when i equals 5 .
$(document).ready(function(){
var i = 0
$(".gotocls").click(function(){
i++
if(i == 5)
document.getElementsByClassName('gotocls')[0].style.display = 'none';
alert("Hello! I am an alert box!!" + i);
});
});
</script>
<a class="dkpdf-button gotocls" id="myLink" href="downlaod/image.com" target="_blank"><span class="dkpdf-button-icon"><i class="fa fa-file-pdf-o"></i></span> <?php echo $pdfbutton_text;?></a>

If you only want to hide the download link in the current session, then simple javascript should do your job.
<script type="text/javascript">
var counter = 0;
function myFunction() {
if(counter === 5){
document.getElementsByClassName('gotocls')[0].style.display = 'none';
}
counter = counter +1;
}
</script>
However when the user refreshes the site, then the download link will be visible again. If you want to store information permanently then you have to use a database.

I wrote the code needed real quick with no tests but it should give you a starting point at least, in your PHP:
/**
* Enqueue a JS file using WP proper action and functions
* 'my-custom-script' can be any name of your fantasy, prepend it with your vendor name and you are good to go
* 'url_to_js_file' MUST be a full URL to your .JS file containing the ajax you need
*/
function our_custom_scripts() {
wp_register_script( 'my-custom-script', 'url_to_js_file.js', array( 'jquery' ), false, true );
wp_localize_script( 'my-custom-script', 'myJsVarName', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ), // Used to make ajax call in WP
) );
wp_enqueue_script( 'my-custom-script' );
}
// Load script
add_action( 'wp_enqueue_scripts', 'our_custom_scripts' );
/**
* What the ajax call will actually trigger thanks to WP AJAX handle
*/
function my_ajax_action() {
/** #var wpdb $wpdb */
global $wpdb;
$clickedLink = $_POST["clicked_link"];
$userId = get_current_user_id();
/*
* Query for the pressed link, that's up to you on how to store data in the database, im going with an easy one
* saving the full link (i would really NOT recommend this :D, its just to show)
*/
$sql = "SELECT * FROM {$wpdb->prefix}my_table_name WHERE link = %s";
$res = $wpdb->get_row( $wpdb->prepare( $sql, array( $clickedLink ) ) );
if ( $canClick = $res["num_pressed"] < 5 ) {
$wpdb->update(
$wpdb->prefix . "my_table_name",
array(
'num_pressed' => ( $res["num_pressed"] + 1 ),
'string_col' => 'val2', //example string col
'int_col' => 3, //example int col
),
array( "user_id" => $userId ), // Where condition
array( "%d", "%s", "%d" ), // updated values format. %s are for strings, %d for integers
array( "%d" ) );// Where condition format
wp_send_json_success();
} else {
wp_send_json_error();
}
}
add_action( 'wp_ajax_my_ajax_action', array( $this, 'my_ajax_action' ) );
add_action( 'wp_ajax_nopriv_my_ajax_action', array( $this, 'my_ajax_action' ) );
Then in your .js file add this:
$(document).ready(function () {
$(".gotocls").click(function (evt) {
var $pressedLink = $(this);
evt.preventDefault(); // Stop doing w/e the browser was trying to do
$.ajax({
url: myJsVarName.ajaxurl,
type: 'POST',
data: {
action: 'my_ajax_action',
clicked_link: $pressedLink.attr("href")
},
timeout: 5000
dataType: 'json',
success: function (response) {
console.log('Your response content', response);
if (response.success) {
window.location.href = $pressedLink.attr("href"); // Proceed with click
}
},
error: function (jqXHR, textStatus, errorThrown) {
}
});
});
});
})(jQuery);
This should cover the PHP and the JS side of your stuff. The rest is up to you, stackoverflow is not a coding factory, it's a community for advices :D

Related

Remove item from Woocommerce minicart using ajax

I'm using Woocommerce and I'm trying to remove item from the mini cart using ajax.
By looking at woocommerce minicart.php file I have found the relevant functionality to removing item:
<?php
echo apply_filters( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'woocommerce_cart_item_remove_link',
sprintf(
'×',
esc_url( wc_get_cart_remove_url( $cart_item_key ) ),
esc_attr__( 'Remove this item', 'woocommerce' ),
esc_attr( $product_id ),
esc_attr( $cart_item_key ),
esc_attr( $_product->get_sku() )
),
$cart_item_key
);
?>
But I can't figure out how to run the command through ajax instead of refreshing the page. I have tried to modify code I found about adding to cart using ajax.
Didn't work, the page still refreshes.
Here is what I have tried:
$(document).on('click', '.remove1', function (e) {
e.preventDefault();
var $thisbutton = $(this),
$form = $thisbutton.closest('form.cart'),
id = $thisbutton.val(),
product_qty = $form.find('input[name=quantity]').val() || 1,
product_id = $form.find('input[name=product_id]').val() || id,
variation_id = $form.find('input[name=variation_id]').val() || 0;
var data = {
action: 'woocommerce_cart_item_removed',
product_id: product_id,
product_sku: '',
quantity: product_qty,
variation_id: variation_id,
};
$.ajax({
type: 'post',
url: wc_add_to_cart_params.ajax_url, // What params should I use?
data: data,
beforeSend: function (response) {
$thisbutton.removeClass('added').addClass('loading');
},
complete: function (response) {
$thisbutton.addClass('added').removeClass('loading');
},
success: function (response) {
if (response.error && response.product_url) {
window.location = response.product_url;
return;
}
},
});
});
functions.php
add_action( 'woocommerce_remove_cart_item', 'update_cart', 10, 2 );
function update_cart(){
//What to do here?
}
No debugging errors.
Few important things I haven't found information online for:
Which ajax url url: wc_add_to_cart_params.ajax_url should I use to remove item from mini cart?
How to handle the data transferred from the ajax to functions.php?
How can I remove item from Woocommerce mini cart using ajax?
First of all, please check your WooCommerce settings to see if Ajax enables the add-to-cart button. If not, Enable it from the admin panel. Check out the screenshot click here to see the screenshot of admin panel setting for ajax
Then try to remove the product from the cart.

Woocommerce live calculation : qty x get_meta('_value') = final value

Here we are talking about selling products (especially pastry or food) in bulk unit / unit / or kg.
All measurements are known weight and quantity,Therefore we must be able to estimate which product in kg will have how many units.
So I created an example of products just to test in woocommerce,
I managed to realize my idea to estimate minimum qty of pieces (or any unit) per kg using a useful piece of code found here.
(1) I put it in a Snippet.
After that I started reading and trying to understand and follow the logic behind the code.
(2) Add some fonctions. just duplicated a few lines.. some copy / paste..
(3) Try to put the same functions in product page (in progress no solution found)
Update 09/12/2019
Code revised no more internal error
// Backend: Add and display a custom field for simple and variable products
add_action( 'woocommerce_product_options_general_product_data', 'add_custom_price_field_to_general_product_data' );
function add_custom_price_field_to_general_product_data() {
global $product_object;
echo '<div class="options_group hide_if_external">';
woocommerce_wp_text_input(array(
'id' => '_min_unit_price',
'label' => __('Min Unit price', 'woocommerce') . ' (' . get_woocommerce_currency_symbol() . ')',
'description' => __('Enter the minimum unit price here.', 'woocommerce'),
'desc_tip' => 'true',
'value' => str_replace('.', ',', $product_object->get_meta('_min_unit_price') ),
'data_type' => 'price'
));
// My custom field "Min price unit prefix"
woocommerce_wp_text_input(array(
'id' => '_min_unit_prefix',
'label' => __('Min Unit prefix', 'woocommerce'),
'description' => __(' Enter prefix unit price here.', 'woocommerce'),
'desc_tip' => 'true',
'value' => str_replace('.', ',', $product_object->get_meta('_min_unit_prefix') ),
'data_type' => 'texte'
));
// My custom field "Estimated quantity"
woocommerce_wp_text_input(array(
'id' => '_estimated_quantity',
'label' => __('Estimated Quantity', 'woocommerce'),
'description' => __('Enter the quantity here.', 'woocommerce'),
'desc_tip' => 'true',
'value' => str_replace('.', ',', $product_object->get_meta('_estimated_quantity') ),
'data_type' => 'price'
));
echo '</div>';
}
// Backend: Save the custom field value for simple and variable products
add_action( 'woocommerce_admin_process_product_object', 'save_product_custom_price_field', 10, 1 );
function save_product_custom_price_field( $product ) {
if ( isset($_POST['_min_unit_price']) ) {
$product->update_meta_data( '_min_unit_price', wc_clean( wp_unslash( str_replace( ',', '.', $_POST['_min_unit_price'] ) ) ) );
}
if ( isset($_POST['_min_unit_prefix']) ) {
$product->update_meta_data( '_min_unit_prefix', wc_clean( wp_unslash( str_replace( ',', '.', $_POST['_min_unit_prefix'] ) ) ) );
}
if ( isset($_POST['_estimated_quantity']) ) {
$product->update_meta_data( '_estimated_quantity', wc_clean( wp_unslash( str_replace( ',', '.', $_POST['_estimated_quantity'] ) ) ) );
}
}
// Frontend variable products: Display the min price with "From" prefix label
add_filter( 'woocommerce_variable_price_html', 'custom_min_unit_variable_price_html', 10, 2 );
function custom_min_unit_variable_price_html( $price, $product ) {
if( $min_unit_price = $product->get_meta('_min_unit_price') ){
$price = wc_price( wc_get_price_to_display( $product, array( 'price' => $min_unit_price ) ) );
$price .= $product->get_meta('_min_unit_prefix');
}
return $price;
}
// Frontend simple products: Display the min price with "From" prefix label
add_filter( 'woocommerce_get_price_html', 'custom_min_unit_product_price_html', 10, 2 );
function custom_min_unit_product_price_html( $price, $product ) {
if( $product->is_type('simple') && $min_unit_price = $product->get_meta('_min_unit_price') ){
$price = wc_price( wc_get_price_to_display( $product, array( 'price' => $min_unit_price ) ) );
$price .= $product->get_meta('_min_unit_prefix');
}
return $price;
}
// Display the cart item weight in cart and checkout pages
add_filter( 'woocommerce_get_item_data', 'display_custom_item_data', 10, 2 );
function display_custom_item_data( $cart_item_data, $cart_item ) {
if ( $cart_item['data']->get_weight() > 0 ){
$cart_item_data[] = array(
'name' => __( 'Weight subtotal', 'woocommerce' ),
'value' => ( $cart_item['quantity'] * $cart_item['data']->get_weight() ) . ' ' . get_option('woocommerce_weight_unit')
);
}
// Display the cart item "estimated quantity" in cart and checkout pages
if ( $cart_item['data']->get_meta('_estimated_quantity') ){
$cart_item_data[] = array(
'name' => __( 'Estimated quantity ', 'woocommerce' ),
'value' => ( $cart_item['quantity'] * $cart_item['data']->get_meta('_estimated_quantity') )
);
}
return $cart_item_data;
}
// Save and Display the order item weight (everywhere)
add_action( 'woocommerce_checkout_create_order_line_item', 'display_order_item_data', 20, 4 );
function display_order_item_data( $item, $cart_item_key, $values, $order ) {
if ( $values['data']->get_weight() > 0 ){
$item->update_meta_data( __( 'Weight subtotal', 'woocommerce' ), ( $item['quantity'] * $values['data']->get_weight() ) . ' ' . get_option('woocommerce_weight_unit') );
}
}
Now, I need help to understand how
Estimated quantity: <? Php echo get_post_meta (get_the_ID (), '_estimated_quantity', true); ?>
can Update in real time with the quantity of add_to_cart.
the formula must be extremely simple in jQuery or javascript ?
_estimated_quantity * quantity.
That all I need now. To show to costumer how much they can get piece of cakes (or any others things) in 1 or xx kg
So I put a 15 or xx (approximate value) in backend.
I hope it makes sense for you.
For information I use clean install wordpress + elementor + elementor hello theme + woocommerce.
update 09/12/2019
I corrected the last php error.
I would like to thank Snuwerd for his support and considerable help without him I will not have the courage to throw myself into the world of php code I learned a lot.
Thank you again
Welcome to Stack Overflow!
To answer your questions:
"Verify that the code is valid"
The code looks quite good (especially if this is really your first time messing with PHP)
"and (code) does not create problems in future woocommerce updates."
This question is really hard to answer.
"Now I am trying to put these two lines of information in the product page. via shortcode? or php again ?"
Probably with more filters/actions, like you have done in the current code. And if that doesn't seem possible, maybe by altering/overriding some template(s). Shortcodes don't necessarily make much sense, unless you want to insert the data into content area's in the backend when adding/editing products.
"Also improve the code"
This doesn't seem necessary.
"and add a prefix to Estimated Quantity."
Can you elaborate on what you mean by this?
ps. I am probably off to bed soon, so I'll check again tomorrow.
Update
I send qty and product_id to the server with AJAX and then the server gives back qty * _estimated_quantity;
To get qty from the box on your screen and to set the right value in Estimated quantity, I need you to make a screenshot of their code. Open the page in Google Chrome, right click > inspect element on the quantity box and then make a screenshot of the code in the Elements tab. Also do the same for the Estimated quantity box (that has 15 in it in the screenshot).
I also assume your website is located on the root of your domain. So on www.example.com and not on www.example.com/wordpress/ (The Ajax call needs the right location).
You can add this PHP to your functions.php
<?php
add_action("wp_ajax_product_get_estimated_quantity", "product_get_estimated_quantity"); // calls our function if user is logged in
add_action("wp_ajax_nopriv_product_get_estimated_quantity", "product_get_estimated_quantity"); // calls our function if user is not logged in, we do not do any security checks on which user etc though, but I don't think it's relevant in our case.
function product_get_estimated_quantity () {
error_log('Snuwerd: Ajax call for estimated quantity is being called correctly.');
$product_id = $_REQUEST["product_id"];
if (!is_numeric($product_id)) { // check if really a number, for security purposes
die();
}
$qty = $_REQUEST["qty"];
if (!is_numeric($qty)) { // check if really a number, for security purposes
die();
}
// No need to get product object, can get metadata directly with get_post_meta
// // get estimated_quantity per kg by product_id
// $args = array(
// 'include' => array( $product_id ),
// );
// $products = wc_get_products( $args );
// foreach ($products as $product) {
// }
// echo $product->get_id();
$estimated_quantity_per_kg = get_post_meta( $product_id, '_estimated_quantity', true);
// $estimated_quantity_per_kg = 15; // this line is only for my local testing, since my products dont have _estimated_quantity meta
echo ((int) $estimated_quantity_per_kg) * ((int) $qty);
error_log('Snuwerd: Ajax call for estimated quantity returned to single-product page.');
die();
}
?>
And add this javascript/jquery anywhere you can (assuming that you know how to, its also easy to find out with google (How to add javascript to Wordpress)).
console.log('Snuwerd: Code planted in document.ready');
jQuery(document).ready(function($) {
console.log('Snuwerd: JS code is being loaded.');
if( $('body.single-product').length) { // if on a single product page
console.log('Snuwerd: We are on the single product page');
$( document ).on( 'change', '.quantity input[type=number]', function() { // selector for the qty box is probably already correct
var qty = $( this ).val();
// var product_id = $(this).closest('.product').attr('id');
// product_id = product_id.split('-');
// product_id = product_id[1];
var product_id = get_current_post_id();
console.log('Snuwerd: quantity changed. Sending ajax call with qty'+qty+' and product_id'+product_id);
jQuery.ajax({
type : "post",
dataType : "json",
url : '/wp-admin/admin-ajax.php', // only works if Wordpress is installed in root of your domain. if you installed in www.example.com/wordpress/, then add /wordpress/ before this
data : {action: "product_get_estimated_quantity", product_id : product_id, qty: qty},
success: function(response) {
console.log('Snuwerd: Ajax call returned succesfully');
// right click -> inspect element to find the right selector for estimated quantity (the 15 from your photoshop)
response = parseInt(response);
console.log('Snuwerd: Ajax call returned succesfully with value '+response);
$('#snuwerd > div').html('Estimated quantity: ' + response);
}
});
return false;
});
}
function get_current_post_id() {
var page_body = $('body');
var id = 0;
if(page_body) {
var classList = page_body.attr('class').split(/\s+/);
$.each(classList, function(index, item) {
if (item.indexOf('postid') >= 0) {
var item_arr = item.split('-');
id = item_arr[item_arr.length -1];
return false;
}
});
}
return id;
}
});
In case you want to know how I added the javascript, i made a file in child-theme-directory/js/child.js.
Then added the Jquery to it. And then I added this to functions.php:
function theme_enqueue_child_scripts() {
error_log('Snuwerd: js script being added in theme_enqueue_child_scripts.');
$file = '/js/child.js';
$cache_buster = date("YmdHis", filemtime( get_stylesheet_directory() . $file )); // no uri
wp_enqueue_script( 'child', get_stylesheet_directory_uri() . $file, array( 'jquery' ), $cache_buster, true ); // true = footer
}
add_action( 'wp_enqueue_scripts', 'theme_enqueue_child_scripts' );
Update
I added the selector for the Estimated quantity field in the javascript, and the quantity selector was already correct, so please re-copy the javascript.
I looked at the screenshot where you add in JS and PHP, but the way you add PHP is not good enough for this PHP. Where you add PHP in the screenshot, it only counts for that page and it needs to be sidewide. The Ajax call will not be able to access PHP that is added to a specific page. If Elementor doesn't have a side wide place to add PHP and if you don't want to change the functions.php of your theme, then maybe you can use this plugin: https://wordpress.org/plugins/my-custom-functions/ . Also, don't forget to actually add the PHP I provided, I didn't see it in your JS/PHP screenshot.
Update
I added some debug messages to find out what parts work. Can you enter the PHP code that is meant for functions.php into your site again and also the JS code.
After this open your product page in Google Chrome and press ctrl+shift+i to open developer tools window. Now change the quantity by pressing the arrows in the number box on the page. There should be a few messages in the Console tab in the developer tools window. Can you paste a screenshot of the console here?
If nothing appears in this console, please check that you're not having cache problems > go to Network Tab in developer tools window and check the disable cache checkbox and then refresh the page and try again.
Next, also check the PHP error log, if you don't know how to check it, please learn about PHP error logging here: https://www.loggly.com/ultimate-guide/php-logging-basics/
In the error log search for Snuwerd and show those lines to me as well.

Update Woocommerce product gallery with Ajax

I'm trying to do a dynamic product gallery based on colours in woocommerce product page. When I click on one colour, example on red, i should see Red Gallery's photos.
To do this i replaced all woocommerce gallery block with a new one created by ajax ( who have same classes of old gallery).
The loading of new photos work fine and I get gallery photos based on colour.
But when ajax load new gallery the slider don't work, I think because the woocommere js, who create the slider, is read only on page load.
I think I should reload some Woocommerce JS Function to recreate slider with his functions, but I don't know how.
This is the php file, which one I create a new gallery, called from ajax:
global $product;
$current_id = "";
if(isset($_POST['prodid']) && $_POST['prodid'] != "" ) {
$current_id = $_POST['prodid'];
$product = new WC_Product($current_id);
}
$columns = apply_filters( 'woocommerce_product_thumbnails_columns', 4 );
$post_thumbnail_id = $product->get_image_id();
$wrapper_classes = apply_filters( 'woocommerce_single_product_image_gallery_classes', array(
'woocommerce-product-gallery',
'woocommerce-product-gallery--' . ( $product->get_image_id() ? 'with-images' : 'without-images' ),
'woocommerce-product-gallery--columns-' . absint( $columns ),
'images',
) );
?>
<figure class="woocommerce-product-gallery__wrapper">
<?php
if ( $product->get_image_id() ) {
$html = wc_get_gallery_image_html( $post_thumbnail_id, true );
} else {
$html = '<div class="woocommerce-product-gallery__image--placeholder">';
$html .= sprintf( '<img src="%s" alt="%s" class="wp-post-image" />', esc_url( wc_placeholder_img_src( 'woocommerce_single' ) ), esc_html__( 'Awaiting product image', 'woocommerce' ) );
$html .= '</div>';
}
echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', $html, $post_thumbnail_id ); // phpcs:disable WordPress.XSS.EscapeOutput.OutputNotEscaped
do_action( 'woocommerce_product_thumbnails' );
?>
</figure>
This is the ajax function called on box colour click
function changeGallery(selected_gallery, productID) {
jQuery(function($) {
var select_color = selected_gallery;
var xhttp;
$.ajax({
url : 'https://mysite.it/wp-admin/admin-ajax.php', // AJAX handler
data : { action : 'load_gallery', gallery : select_color, prodid : productID },
type : 'POST',
beforeSend: function() {
},
success : function( result ){
if( result ) {
$('.woocommerce-product-gallery').html(result);
//Reload here some woocommerce JS functions?
}
}
});
});
}
The way to solve issues like this is to look at the WooCommerce source code to see how the plugin initialises the gallery to begin with. Based on this, I think you need to do something like:
jQuery( '.woocommerce-product-gallery' ).each( function() {
jQuery( this ).wc_product_gallery();
} );
See Github: single-product.js for reference.
I had same problem. The dafoxuk answer is correct, you need to reinitialize ProductGallery class on the .woocomorce-product-gallery. The problem was that this element already has a flexslider entity attached to it. To solve this, just remove that element (.woocomorce-product-gallery) and create a new identical one. (Flexslider doesn't have a way to detach itself from the element as far as I know)

global variable and ajax request - Why is my global variable not inscreased as i'm using async:false mode?

With this wonderful website, i could learn how to set ajax requests in wordpress, but failed to use global variables. I'm still new in wordpress and ajax programming.
My problem is as follows: I made a query to store 100 wp_posts in a global $stmts['getCriteriasposts'] array, and displayed the 4 first items in a grid. $wpdb_position is a global variable giving the current position in this stmts array. When a user clicks an item in the grid, i want to replace the current post by the next item to be read in the array, at the same position in the grid.
As four items have been displayed, before clicking any post, $wpdb_position = 4.
But when i send the Ajax Request to increase the global variable $wpdb_position = 0, even though the ajax request is in synchronous mode, and the request works for local data. I don't see where i'm wrong.
Any help will be really useful.
Thanks a lot.
THe json output is
Object
position: "2"
wpdb_position: 1
Below the code:
// Functions.php
add_action( 'template_redirect', 'ajax_script_enqueuer' );
function ajax_script_enqueuer() {
$nonce = wp_create_nonce("my_action_callback");
wp_enqueue_script( 'ajax-script', get_template_directory_uri() . '/../../../js/epointplus/epointplusevalframe.js', array('jquery') );
wp_localize_script( 'ajax-script', 'ajax_object', array( 'ajax_url' => admin_url('admin-ajax.php') ) );
}
add_action( 'wp_ajax_my_action', 'my_action_callback' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );
add_action( 'admin_post_nopriv_my_action', 'manage_callback_loadnext' );
add_action( 'admin_post_my_action', 'manage_callback_loadnext' );
function my_action_callback() {
global $wpdb;
global $stmts;
global $wpdb_position;
$wpdb_position = $wpdb_position + 1;
//$criteria = $stmts['getCriteriasposts'][$wpdb_position];
$result['wpdb_position'] = $wpdb_position;
$result['position'] = $_POST["position"];
echo json_encode($result);
die(); // may not work, in this case, use start_session() and $_SESSION to access the cache
}
// in the '/../../../js/epointplus/epointplusevalframe.js
$(document).ready( function() {
$(".EvalFrame").click( function() {
$.ajax({
type : "post",
dataType : "json",
async: false, // Mode : synchrone
url : ajax_object.ajax_url,
data : {
action: 'my_action',
nonce : jQuery(this).attr("data-nonce")
},
})
.fail(function() {
console.log('something went wrong');
//$('#EvalFrame_'+ position).empty();
})
.done(function(data) {
console.log(data);
//$('#EvalFrame_'+position).html(data);
});
Once again, the help of this website has proven really efficient. I saw the use of global $wpdb often in examples that i thought global variables could be used. I was wrong. Using Patrick's comment, I modified the code. Now it works good! Thanks so much, i was stuck for a while on this!!!
function my_action_callback() {
// toujours le meme souci, les variables globales ne fonctionnent pas.
global $wpdb;
if (!session_id()) {session_start();}
//global $wpdb_position;
if (count($_SESSION['criteriasCache']) > 0 )
{
$newCriteria = array_pop($_SESSION['criteriasCache']);
}
//$stmts['getCriteriasposts'][$wpdb_position];
$result['ccount'] = count($_SESSION['criteriasCache']);
$result['criteria'] = displayfromunderlyingsupport($newCriteria,$_POST["position"]);
$result['position'] = $_POST["position"];
//$result['type'] = "success";
//echo displayfromunderlyingsupport($newCriteria,$position);
echo json_encode($result);
die(); // may not work, in this case, use start_session() and $_SESSION to access the cache
}

How do I assign jQuery event handlers properly?

I am still learning how to use AJAX so would display a novice code here...
I got this div (which repeats itself as a list of checkbox):
<div class="updateTask fs11">
<input type="checkbox" name="taskStatusRadio" id="taskStatus" value="<?php echo $taskId; ?>" <?php echo $done; ?> >
<?php _e('Task Done', 'sagive'); ?>
</div>
Which activates this:
jQuery(function($){
$('.updateTask').click(function () {
$.post(ajax_object.ajaxurl, {
action: 'action_update_task',
task_id: $("input[name=taskStatusRadio]:checked").map(function () {return this.value;}).get()
}, function(data) {
// USE DATA RETURNED //////////
var $response = $(data);
var message = $response.filter('div#message').html();
var taskid = $response.filter('div#taskid').html();
// SUCCESS RESPOND //////////
setTimeout(function(){
$('#success ul li').append(message + taskid);
$('#success').fadeIn();
$('#success').css("display", "block");
}, 1000);
setTimeout(function(){
$('#success ul li').empty();
$('#success').fadeIn();
$('#success').css("display", "none");
}, 30000);
hideTask = "#" + taskid;
$(hideTask).hide("slow");
hideTask = '';
});
});
});
And uses this php file:
wp_enqueue_script( 'ajax-update-task', get_stylesheet_directory_uri().'/ajaxLoops/ajax-update_task.js', array('jquery'), 1.0 ); // jQuery will be included automatically
wp_localize_script( 'ajax-update-task', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); // setting ajaxurl
add_action( 'wp_ajax_action_update_task', 'ajax_update_task' ); // ajax for logged in users
function ajax_update_task() {
global $current_user;
get_currentuserinfo();
$task_user = $current_user->display_name;
if($taskUser == '') {$taskUser = $current_user->user_login;}
$task_id = $_POST["task_id"];
$task_id = $task_id[0];
$task_status = 'done';
$task_title = get_the_title($task_id);
$task_title = mb_substr($task_title, 0 ,35).'...';
update_post_meta($task_id, '_sagive_task_radio_selector', $task_status);
update_post_meta($task_id, '_sagive_task_user_changed', $task_user);
echo '<div id="message">'.__('The task: ', 'sagive').$task_title.__('Was Marked Completed!', 'sagive').'</div>';
echo '<div id="taskid">'.$task_id.'</div>';
die(); // stop executing script
}
It all works fine the first time. But the second checkbox I mark after the first one disappears as expected does nothing. It doesn't activate the php script and doesn't return a response.
Since I'm still new using AJAX, I would appreciate an example using my code or a good example with explanation.
Revision 1:
This is the structure of the page where the checkboxes are at
I think your problem comes from your selector :
$("input[name=taskStatusRadio]:checked").map(function () {return this.value;}).get();
which returns all the taskStatusRadio input checked and not just the one you click.
Your php script receive all the taskid checked in an array an pick the first one to treat it and send a response.
So the first time, it's ok, you just have one checkbox checked. But when you check a second checkbox, all checked taskid will be send and only the $_POST["task_id"][0] will be treated.
Same response from your php script and no change in the front view.
So, i think, you just have to modify a little bit your code, to post only taskid of the checkbox you click on it.
jQuery(function($) {
// we listen only the checkbox, not the div click action
$(':checkbox', '.updateTask').click(function () {
// if the checkbox is checked
if ($(this).attr('checked') == "checked") {
$.post(ajax_object.ajaxurl, {
action: 'action_update_task',
task_id: $(this).val() },
function(data) {
// SUCCESS RESPOND //////////
setTimeout(function() {
$('#success ul li').append( $(data).html());
$('#success').fadeIn();
$('#success').css("display", "block");
}, 1000);
setTimeout(function() {
$('#success ul li').empty();
$('#success').fadeIn();
$('#success').css("display", "none");
}, 30000);
// we hide the checkbox
$(this).hide("slow");
});
}
});
});
And because of this change in the front javascript, we have to simplify your php script like this :
wp_enqueue_script( 'ajax-update-task', get_stylesheet_directory_uri().'/ajaxLoops/ajax-update_task.js', array('jquery'), 1.0 ); // jQuery will be included automatically
wp_localize_script( 'ajax-update-task', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); // setting ajaxurl
add_action( 'wp_ajax_action_update_task', 'ajax_update_task' ); // ajax for logged in users
function ajax_update_task() {
global $current_user;
get_currentuserinfo();
$task_user = $current_user->display_name;
if($taskUser == '') {$taskUser = $current_user->user_login;}
$task_id = $_POST["task_id"];
$task_status = 'done';
$task_title = get_the_title($task_id);
$task_title = mb_substr($task_title, 0 ,35).'...';
update_post_meta($task_id, '_sagive_task_radio_selector', $task_status);
update_post_meta($task_id, '_sagive_task_user_changed', $task_user);
// Note : now we send the message directly well-formed with the task_id
echo __('The task: ', 'sagive').$task_title.__('Was Marked Completed!', 'sagive'). $task_id;
die(); // stop executing script
}
I hope my answer will solve your problem ;)
ps: i apologize for my poor english...

Categories