Iam trying to trigger a popup by simulating a button click with a simple JS function when a product from a specific category is added to the woocommerce cart. I have seen some do it in simmilair functions, but I cant figure this one to work.
I have composed the following function that runs if the category is in cart and if the page is the checkout page:
add_action( 'woocommerce_before_checkout_form', 'check_category_in_cart' );
function check_category_in_cart() {
$cat_in_cart = false;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( has_term( 'test', 'product_cat', $cart_item['product_id'] ) ) {
$cat_in_cart = true;
break;
}
}
if ( $cat_in_cart ) {
<script>
jQuery(document).ready(function($) {
$('#pop-up').trigger('click');
});
</script>
}
}
This function makes my website not function. Anyone has an idea how I can get this to work?
use setTimeout(). try the below code.
add_action( 'woocommerce_before_checkout_form', 'check_category_in_cart' );
function check_category_in_cart() {
$cat_in_cart = false;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( has_term( 'test', 'product_cat', $cart_item['product_id'] ) ) {
$cat_in_cart = true;
break;
}
}
if ( $cat_in_cart ) { ?>
<script>
jQuery(document).ready(function($) {
setTimeout(function(){
$('#pop-up').trigger('click');
}, 10);
});
</script>
<?php }
}
jQuery(document).ready(function($) {
setTimeout(function(){
$('#pop-up').trigger('click');
}, 10);
jQuery(document).on('click','#pop-up',function(){
alert('trigger');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="pop-up">popup</button>
PHP waits for a php valid code in <?php ?> tags, but you are placing JavaScript, so you have to close the PHP tag before <script> and open a new one after the </script>. Otherwise your jQuery code is fine.
if ( $cat_in_cart ) {
?>
<script>
jQuery(function() {
$('#pop-up').trigger('click');
});
</script>
<?php
}
Reason need to check.
Maybe Because your id (pop-up) is not placed in your HTML.
Maybe your jQuery is not loaded.
Check in the console what kind of error you found.
your PHP function should properly closed.
if ( $cat_in_cart ) {
?>
<script>
jQuery(document).ready(function($) {
$('#pop-up').trigger('click');
});
</script>
<?php
}
if all is good then you can try.
jQuery(document).ready(function($) {
var timeInterVal = setInterval(CheckId, 1000);
CheckId function(){
var id = $("#pop-up");
if(id.length!=0){
$('#pop-up').trigger('click');
clearInterval(timeInterVal);
}
}
});
This will work if your Id not found once your id placed then this will stop the timer and trigger pop-up.
Thanks.
Related
I am using wordpress and have a function like this, how to redirect to the corresponding url only happens onclick, for now the "en" language page is automatically redirecting after the page load, but the "zh-hant" redirecting after click, anyone can help me to check the code?
Thanks.
add_action( 'wp_head', 'redirect_after_booking' );
function redirect_after_booking() {
if ( in_category('teachers') ) {
if(ICL_LANGUAGE_CODE=='en'){
?>
<script>
window.beforeConfirmedBooking = function() {
window.location.href = "https://aaa.com";
};
</script>
<?php
}
if(ICL_LANGUAGE_CODE=='zh-hant'){
?>
<script>
window.beforeConfirmedBooking = function() {
window.location.href = "https://aaa.com/zh-hant";
};
</script>
<?php
}
}
}
You should be doing all of it in one function itself
add_action( 'wp_head', 'redirect_after_booking' );
function redirect_after_booking() {
if ( in_category('teachers') ) {
$url_endpoint = '';
if(ICL_LANGUAGE_CODE=='en'){
} else if (ICL_LANGUAGE_CODE=='zh-hans') {
$url_endpoint = '/zh-hans';
}else if (ICL_LANGUAGE_CODE=='zh-hant') {
$url_endpoint = '/zh-hant';
}
?>
<script>
window.beforeConfirmedBooking = function() {
window.location.href = "https://aaa.com<?php echo $url_endpoint; ?>";
};
const btn = document.querySelector('.el-button .el-button--primary .redirect-link');
btn.addEventListener('click', beforeConfirmedBooking);
</script>
<?php
}
}
You can also do it just using php and no js at all
add_action( 'wp_head', 'redirect_after_booking' );
function redirect_after_booking() {
if ( in_category('teachers') ) {
$url_endpoint = '';
if(ICL_LANGUAGE_CODE=='en'){
} else if (ICL_LANGUAGE_CODE=='zh-hans') {
$url_endpoint = '/zh-hans';
}else if (ICL_LANGUAGE_CODE=='zh-hant') {
$url_endpoint = '/zh-hant';
}
}
}
// The following will redirect you to where ever you want
header('Location: https://aaa.com' . $url_endpoint);
/* Make sure that code below does not get executed when we redirect. */
One method would be to do the below using a switch statement.
This allows for easy growth and in the event you end up with a LOT of languages easy to just repeat and falls back to the site URL in the event there isn't a match.
add_action( 'wp_head', 'redirect_after_booking' );
function redirect_after_booking() {
if ( in_category('teachers') ) {
switch (CL_LANGUAGE_CODE) {
case 'zh-hant':
wp_redirect( trailingslashit( get_site_url() ) . CL_LANGUAGE_CODE );
exit;
break;
default:
wp_redirect( get_site_url() );
exit;
}
}
}
I am creating a plugin to track courier order via button in shop order page. This is my code
// add Tracking button in shop order admin column
add_action( 'manage_shop_order_posts_custom_column', 'dvs_add_tracking_admin_list_column_content' );
function dvs_add_tracking_admin_list_column_content( $column ) {
<button type="button" class="woocommerce-Button button mark-as-read" >Track Order</button>
<?php
}
?>
<script type="text/javascript">
jQuery(function($){ // use jQuery code inside this to avoid "$ is not defined" error
$('.mark-as-read').click(function(){
console.log('The function is hooked up');
jQuery.ajax({
type: "POST",
url: "/wp-admin/admin-ajax.php",
data: {
action: 'mark_message_as_read'
},
success: function (output) {
console.log(output);
}
});
});
});
</script>
<?php
add_action('wp_ajax_mark_message_as_read', 'mark_message_as_read');
add_action('wp_ajax_nopriv_mark_message_as_read', 'mark_message_as_read');
function mark_message_as_read() {?>
<script>
alert("Hello! I am an alert box!!");
</script>
<?php
wp_send_json_success([/* some data here */]);
wp_send_json_error([/* some data here */]);
}
This is screenshot
But when I click the Track Order button nothing happens, it should display the alert-box as defined in a function, please help me what I did wrong?
There are multiple mistakes in your codeā¦ Here is the correct way to make it work:
add_action( 'manage_shop_order_posts_custom_column', 'add_tracking_admin_list_column_content' );
function add_tracking_admin_list_column_content( $column ) {
if ( $column === 'wc_actions') {
?><button type="button" class="woocommerce-Button button mark-as-read" ><?php _e('Track'); ?></button><?php
}
}
add_action( 'admin_footer', 'admin_footer_tracking_js' );
function admin_footer_tracking_js() {
global $pagenow;
if ( $pagenow === 'edit.php' && isset($_GET['post_type']) && 'shop_order' === $_GET['post_type'] ) :
?>
<script type="text/javascript">
jQuery( function($){
$('.mark-as-read').on('click', function(){
$.ajax({
type: 'POST',
url: '<?php echo admin_url('/admin-ajax.php'); ?>',
data: {
'action': 'mark_message_as_read',
'track_order': 'yes'
},
success: function (response) {
console.log(response);
if ( response == 'yes' ) {
alert("Hello! I am an alert box!!"); // => alert box
}
}
});
});
});
</script>
<?php
endif;
}
add_action('wp_ajax_mark_message_as_read', 'get_mark_message_as_read');
function get_mark_message_as_read() {
if ( isset($_POST['track_order']) ) {
//wp_send_json_success([/* some data here */]);
//wp_send_json_error([/* some data here */]);
echo $_POST['track_order']; // Send data back to JS
die();
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
I use the Add to cart Ajax callback, but I miss how I can get the post Id there.
MY GOAL: I want to use the add_filter only on a specific page.
PHP in functions.php
add_filter( 'woocommerce_add_cart_item_data', 'iconic_add_engraving_text_to_cart_item' , 10, 3 );
function iconic_add_engraving_text_to_cart_item( $cart_item_data, $product_id, $variation_id ) {
global $post;
if ( $post->ID === 54214 ) {
$engraving_text = 'test';
$cart_item_data['iconic-engraving'] = $engraving_text;
return $cart_item_data;
} else {
return $cart_item_data;
}
}
This is NOT WORKING because $post is NULL (because of the Ajax woocommerce_add_cart_item_data hook).
So I tried the following code in the JS to get the post id in JS (working).
function get_current_page_id() {
var page_body = $('body.page');
var id = 0;
if(page_body) {
var classList = page_body.attr('class').split(/\s+/);
$.each(classList, function(index, item) {
if (item.indexOf('page-id') >= 0) {
var item_arr = item.split('-');
id = item_arr[item_arr.length -1];
return false;
}
});
}
return id;
}
Now, how can I handover the id to my Ajax Callback to work with it?
Any advice?
EDIT:
I forgot to tell that I am planning to use the add to cart action on other pages but not a single product page.
For that, I am using a third party plugin which gives me the button for my desired product, so I am not using default $product or $post Object (like in single product pages).
I have finally found a solution for this "simple" problem. I can work with a session:
add_action( 'wp_head', 'set_session' );
add_filter( 'woocommerce_add_cart_item_data', 'iconic_add_engraving_text_to_cart_item' , 10, 3 );
function set_session() {
session_start();
// add post id
global $post;
$post_id = $post->ID;
$_SESSION['post_id'] = $post_id;
}
function iconic_add_engraving_text_to_cart_item( $cart_item_data, $product_id, $variation_id ) {
session_start();
if( $_SESSION['post_id'] == 54214 ) {
$engraving_text = 'test';
$cart_item_data['iconic-engraving'] = $engraving_text;
return $cart_item_data;
} else {
return $cart_item_data;
}
}
I'm trying to get the value 3 from this link: index.php?subtopic=example&id=3
Normally I would use the $_REQUEST['id'] but I'm facing another situation here.
I got the example1.php:
<script type="text/javascript" src="js/chatbox.js"></script>
...
<div id="chat_box"></div>
And then the chatbox.js:
setInterval( function() {
$('#chat_box').load('chatbox.php');
} , 100 );
And finally the chatbox.php:
echo $_REQUEST['id'];
but I can't get the id value here :/ Please Help!!!
Basically you want to parse the id out of the URL and send it to the chat - let's do this:
<script type="text/javascript">
function getID() {
var tmp=location.href.split('?');
if (tmp.length!=2) return -2;
tmp=tmp[1].split('&');
for (i=0;i<tmp.length;i++) {
var param=tmp[i].split('=');
if (param.length!=2) continue;
if (param[0]!="id") continue;
return parseInt(param[1]);
}
return -3;
}
var chaturl='chatbox.php?id='+getID();
</script>
<script type="text/javascript" src="js/chatbox.js"></script>
...
<div id="chat_box"></div>
...
setInterval( function() {
$('#chat_box').load(chaturl);
} , 100 );
I solved it here:
example1.php
echo "<script type='text/javascript'>
setInterval( function() {
$('#chat_box').load('chatbox.php?id=".$_GET['id']."');
} , 100 );
</script>";
echo '<div id="chat_box"></div>';
and chatbox.php:
echo $_GET['id'];
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...