I tried to make a Like button for Posts so i found this tutorial with a lot of searching
tutorial : https://www.atomicsmash.co.uk/blog/create-like-post-button-in-wordpress/
but not worked to me !
my code in functions.php
add_action( 'rest_api_init', function () {
register_rest_route( 'example/v2', '/likes/(?P<id>\d+)', array(
'methods' => array('GET','POST'),
'callback' => 'example__like',
) );
});
function example__like( WP_REST_Request $request ) {
// Custom field slug
$field_name = 'postlike';
// Get the current like number for the post
$current_likes = get_field($field_name, $request['id']);
// Add 1 to the existing number
$updated_likes = $current_likes + 1;
// Update the field with a new value on this post
$likes = update_field($field_name, $updated_likes, $request['id']);
return $likes;
}
in ajax
<script type="text/javascript">
$('.like__btn').on('click', function(){
// AJAX call goes to our endpoint url
$.ajax({
url: 'http://192.168.1.8/p-test/wp-json/example/v2/likes/7',
type: 'post',
success: function() {
console.log('works!');
},
error: function() {
console.log('failed!');
}
});
// Change the like number in the HTML to add 1
var updated_likes = parseInt($('.like__number').html()) + 1;
$('.like__number').html(updated_likes);
// Make the button disabled
$(this).attr('disabled', true);
});
</script>
in HTML
<button class="like__btn">
<span class="like__number"><?php the_field('postlike'); ?></span>
</button>
Which part of the tutorial did I make a mistake?
Thanks for any help
Related
I'm using this method to load more posts with Ajax.
I'm also using Masonry for the posts layout.
Masonry works fine for the first set of posts, but not for the next set of posts that are appended after clicking load more posts.
How can I make Masonry work after loading more posts?
Screen before click
Screen after click
Source Code:
index.php
<!-- Post Layout -->
<div class="posts <?php echo $home_style; ?>">
<!-- Normal Post -->
<?php
if (have_posts()) :
/* Start the Loop */
while (have_posts()) : the_post();
/* Home Layout */
if ($home_style === 'standard') {
get_template_part('inc/posts/content');
} else {
get_template_part('inc/posts/content', 'grid');
}
endwhile;
else :
get_template_part('template-parts/content', 'none');
endif;
?>
<?php
global $wp_query; // you can remove this line if everything works for you
// don't display the button if there are not enough posts
if ($wp_query->max_num_pages > 1)
// you can use <a> as well
echo '<div class="misha_loadmore grid-post">More posts</div>';
?>
</div>
<!-- Post Layout / END -->
Ajax Code
jQuery(function ($) {
$('.misha_loadmore').click(function () {
var button = $(this),
data = {
'action': 'loadmore',
'query': misha_loadmore_params.posts,
'page': misha_loadmore_params.current_page
};
$.ajax({
url: misha_loadmore_params.ajaxurl, // AJAX handler
data: data,
type: 'POST',
beforeSend: function (xhr) {
// change the button text, you can also add a preloader image
button.text('Loading...');
},
success: function (data) {
if (data) {
button.text('More posts').prev().before(data); // insert new posts
misha_loadmore_params.current_page++;
if (misha_loadmore_params.current_page == misha_loadmore_params.max_page)
button.remove(); // if last page, remove the button
// you can also fire the "post-load" event here
// if you use a plugin that requires it
// $( document.body ).trigger( 'post-load' );
} else {
button.remove(); // if no data, remove the button as well
}
}
});
});
});
Masonry script.js
/* Masonary Grid */
$('.home-grid').masonry({
itemSelector: '.grid-post',
percentPosition: true,
gutter: 33
});
In most javascript libraries, if you change the DOM (HTML) after initializing the plugin, you will have to tell the library that changes have been made. Most libraries will include a function or listen to an event that tells it to update. In the case of Masonry, it looks like this function is reloadItems.
In your case, it looks like you will have to call $('.home-grid').masonry('reloadItems'); directly after you do button.text( 'More posts' ).prev().before(data);.
Full code:
jQuery(function ($) {
$('.misha_loadmore').click(function () {
var button = $(this),
data = {
'action': 'loadmore',
'query': misha_loadmore_params.posts,
'page': misha_loadmore_params.current_page
};
$.ajax({
url: misha_loadmore_params.ajaxurl, // AJAX handler
data: data,
type: 'POST',
beforeSend: function (xhr) {
button.text('Loading...');
},
success: function (data) {
if (data) {
button.text('More posts').prev().before(data); // insert new posts
$('.home-grid').masonry('reloadItems');
misha_loadmore_params.current_page++;
if (misha_loadmore_params.current_page == misha_loadmore_params.max_page)
button.remove(); // if last page, remove the button
} else {
button.remove(); // if no data, remove the button as well
}
}
});
});
});
I want to test a conroller which generates a page with a field that changes dynamically with ajax.
Here is the code of ajax:
<script>
var $groupeCompetence = $('#requete_prestataire_groupeCompetence');
// When sport gets selected ...
$groupeCompetence.change(function() {
// ... retrieve the corresponding form.
var $form = $(this).closest('form');
// Simulate form data, but only include the selected sport value.
var data = {};
data[$groupeCompetence.attr('name')] = $groupeCompetence.val();
// Submit data via AJAX to the form's action path.
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(html) {
// Replace current position field ...
$('#requete_prestataire_competence').replaceWith(
// ... with the returned one from the AJAX response.
$(html).find('#requete_prestataire_competence')
);
// Position field now displays the appropriate positions.
}
});
});
</script>
How can I call this code from phpunit using client or crawler?
I tried :
$this->client->request(
'POST',
'/',
array('requete_prestataire[groupeCompetence]' =>2),
array(),
array(),
array('HTTP_X-Requested-With' => 'XMLHttpRequest',
));
But it doesn't work.
Thanks a lot !
I found the solution :
you have to disable validation, and send the form as it was generated :
$crawler = $this->client->request('GET', '/');
$form = $crawler->selectButton('requete_prestataire_Rechercher')->form();
$form['requete_prestataire[groupeCompetence]'] = 2;
$form['requete_prestataire[competence]']->disableValidation()->select(50);
$crawler = $this->client->submit($form);
here is the explanation in doc :
doc symfony dom crawler component
Im trying to use ajax to sent request. I have CartsController and a method add. Please help!
<?php
echo $this->Html->link('Add', array('controller'=>'carts',
'action'=>'add', 'product_id'=>$product['Product']['id']),
array('class'=>'btn btn-primary col-md-offset-4',
'data-product-id'=>$product['Product']['id']));
?>
$('a.btn').on('click', function(e){
var this = $(this);
var product_id = this.data('product-id');
this.html('Item Added');
$.ajax({
url: '/cartphp_cart/carts/add/',
type: 'POST',
data: {product_id: product_id},
success: function(count) {
$('#number-of-items').text(' ' + count);
console.log(count);
}
});
e.preventDefault();
});
If the ajax request is OK, than in your add method of CartsController
you can get it by
if ($this->request->is('post') || $this->request->is('put')) {
debug($this->request->data['product_id'])
}
You should be able to access the data you've put in your ajax request by
if( $this->request->is('ajax') ) {
pr($this->request->data['product_id']);
// Or try printing the whole $this->request->data if you need other items.
}
I am try to upload file on woocommerce checkout page but I am not able to upload file. I have also try to get value using print_r($_FILES) in create_order function in class-wc-checkout.php file but it will return blank array
When I have remove class checkout from checkout form then it will working fine (without ajax submit)
I want to submit form without ajax but I need ajax remain on checkout page because I have add some extra price using ajax (update price without refresh)
My ajax call to add extra fee.
jQuery('#PageCount').change(function () {
var state = jQuery('#PageCount').val();
var current_price = jQuery('#carttot').val();
var data = {
action: 'woocommerce_apply_state',
security: wc_checkout_params.apply_state_nonce,
state: state,
current_price: current_price
};
jQuery.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: data,
success: function (code) {
console.log(code);
if (code === '0') {
jQuery('body').trigger('update_checkout');
}
},
dataType: 'html'
});
return false;
});
and php code or woocommerce hooks to add extra fee
add_action('wp_ajax_woocommerce_apply_state', 'calculate_per_page', 10);
add_action('wp_ajax_nopriv_woocommerce_apply_state', 'calculate_per_page', 10);
function calculate_per_page() {
if (isset($_POST['state'])) {
global $woocommerce;
$weight = WC()->cart->cart_contents_weight;
$state = $_POST['state'];
$current_price = $_POST['current_price'];
$val = $current_price * $state -$current_price;
session_start();
$_SESSION['val'] = $val;
}
}
add_action('woocommerce_cart_calculate_fees', 'woo_add_cart_fee');
function woo_add_cart_fee() {
session_start();
$extracost = $_SESSION['val'];
WC()->cart->add_fee('Per page charges:', $extracost);
}
And my function to upload file..
add_action('woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta');
function custom_checkout_field_update_order_meta( $order_id ) {
if ($_FILES['avatar']['name']) {
if ( ! function_exists( 'wp_handle_upload' ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
}
$upload_dir = wp_upload_dir();
$path = $upload_dir['path'];
$fileName = $_FILES["avatar"]["name"];
$fileTmpLoc = $_FILES["avatar"]["tmp_name"];
$pathAndName = $path."/".$fileName;
$moveResult = move_uploaded_file($fileTmpLoc, $pathAndName);
update_post_meta( $order_id, 'uploaded_file_to_translate', $_FILES['avatar']['name']);
if ($_POST['billing_output_to_send'])
update_post_meta( $order_id, 'How do you want your translation sent to you?', esc_attr(htmlspecialchars($_POST['billing_output_to_send'])));
if ($_POST['PageCount'])
update_post_meta( $order_id, 'How many pages are in your documents?', esc_attr(htmlspecialchars($_POST['PageCount'])));
}
}
How it will possible?
$_FILES you can not get it at woocommerce_checkout_update_order_meta hook because of woocommerce serialize the form and submit form throw ajax,
as we know that form serialize can not submit files requests. but I have two solutions for doing this may be it work for you.
You can use a plugin woocommerce upload file in the checkout. you can easily find it on google
But if you want to upload custom files then you can use this
when onchange file fire an ajax and push file array in session when user checkout, get the files from the session and upload to the directory, and then destroy your session.
$('.fileupload').change(function(e){
var action = 'update_session_files';
e.preventDefault();
var fd = new FormData();
fd.append('action', action);
var files = $('input[name="file"]')[0].files[0];
fd.append('billing_artist_headshot', files);
$.ajax({
url: my_ajax_object.ajax_url,
type: 'post',
data: fd,
contentType: false,
processData: false,
success: function(response){
},
});
});
and ajax action
add_action( 'wp_ajax_nopriv_update_session_files', 'update_session_function' );
add_action( 'wp_ajax_update_session_files', 'update_session_function' );
function update_session_function(){
session_start();
$_FILES['billing_artist_headshot'];
// upload your file here with Wordpress and get the id.
}
Trying to use the built in AJAX functions with the Wordpress Admin. I've been following this tutorial, but when I run the jQuery script, the data isn't being saved to the user meta.
<?php
add_action( 'admin_footer', 'ring_jquery' );
function ring_jquery() {
?>
<script type="text/javascript">
jQuery('.ring-submit').on('click', function(){
var u = jQuery(this).attr('user'),
c = jQuery('.agt_ringc[user="'+u+'"]').val(),
x = jQuery('.agt_ringx[user="'+u+'"]').val(),
formData = 'ringu='+u+'&ringc='+c+'&ringx='+x;
jQuery.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: formData,
success: function(e){
jQuery('.success[user="'+u+'"]').fadeIn(400).delay(400).fadeOut(400);
},
error: function(){
jQuery('.fail[user="'+u+'"]').fadeIn(400).delay(400).fadeOut(400);
}
});
});
</script>
<?php
} //End ring_jquery()
add_action('wp_ajax_my_action', 'ring_callback');
function ring_callback() {
global $wpdb; // this is how you get access to the database
$ringu = $_POST['ringu'];
$ringc = $_POST['ringc'];
$ringx = $_POST['ringx'];
update_user_meta($ringu,'agt_ringc',$ringc);
update_user_meta($ringu,'agt_ringx',$ringx);
die(); // this is required to return a proper result
}
?>
You will need to have action : my_action in the data string , or as per codex :
var data = {
action: 'my_action',
whatever: 1234
};
Issue was, as #ObmerkKronen pointed out was that I was missing an action definition in the data string (which tells the AJAX page which function to run).
formData = 'action=ring_callback&ringu='+u+'&ringc='+c+'&ringx='+x;
I also changed the name of the action hook to match the name of the function. I don't know if this was necessary, but some other things I found did it and I wanted to fit in.
add_action('wp_ajax_ring_callback', 'ring_callback');