Surely, someone must have an idea of how t get this to work...
My blog is currently set where I have a custom page that displays only posts in a given category. Each post has a toggle button. When the toggle button is pressed, the post hides (the ENTIRE div is hidden with title and all post content). This works as desired.
The page is also set to display 10 posts per page. If I have 11 posts, the 11th is pushed to page 2. This works as desired.
The problem is that when a post is toggled (let's say post 3), I am left with a total of 9 posts on this page, with post 11 remaining on page 2. What I want to have happen is that when post 3 is toggled, post 11 should carry onto page 1, with page 2 essentially disappearing (since there are no posts to display there).
For illustration purposes:
Page 1 displays Posts 1,2,3,4,5,6,7,8,9,10
Page 2 displays Posts 11...and so on.
If Post 3 is toggled:
Page 1 displays Posts 1,2,4,5,6,7,8,9,10,11
Page 2 disappears (unless there is a post 12,13, etc)
Would anyone know how to implement this?
page.php:
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'category_name' => 'post',
'paged' => $paged,
'posts_per_page' => 10
);
query_posts($args);
while (have_posts()) : the_post();
?>
..........the posts are displayed.............
<?php endwhile; ?>
<script type="text/javascript">
var pager = new Imtech.Pager();
$(document).ready(function() {
pager.paragraphsPerPage = 5; // set amount elements per page
pager.pagingContainer = $('#paginate'); // set of main container
pager.paragraphs = $('div.z', pager.pagingContainer); // set of required containers
pager.showPage(1);
});
</script>
toggle.js
$(document).on("click", ".toggle", function(){
postID = $(this).attr('id').replace('toggle_', '');
// Declare variables
value = '0';
myajax();
return false;
});
function myajax(){
// Send values to database
$.ajax({
url: 'check.php',
//check.php receives the values sent to it and stores them in the database
type: 'POST',
data: 'postID=' + postID + '&value=' + value,
success: function(result) {
$('#post_' + postID).toggle();
}
});
}
pagination.js
var Imtech = {};
Imtech.Pager = function() {
this.paragraphsPerPage = 3;
this.currentPage = 1;
this.pagingControlsContainer = '#pagingControls';
this.pagingContainerPath = '#contained';
this.numPages = function() {
var numPages = 0;
if (this.paragraphs != null && this.paragraphsPerPage != null) {
numPages = Math.ceil(this.paragraphs.length / this.paragraphsPerPage);
}
return numPages;
};
this.showPage = function(page) {
this.currentPage = page;
var html = '';
this.paragraphs.slice((page-1) * this.paragraphsPerPage,
((page-1)*this.paragraphsPerPage) + this.paragraphsPerPage).each(function() {
html += '<div>' + $(this).html() + '</div>';
});
$(this.pagingContainerPath).html(html);
renderControls(this.pagingControlsContainer, this.currentPage, this.numPages());
}
var renderControls = function(container, currentPage, numPages) {
var pagingControls = 'Page: <ul>';
for (var i = 1; i <= numPages; i++) {
if (i != currentPage) {
pagingControls += '<li>' + i + '</li>';
} else {
pagingControls += '<li>' + i + '</li>';
}
}
pagingControls += '</ul>';
$(container).html(pagingControls);
}
}
So, any ideas?
My Answer would be to reload the current page with posts through ajax.
there is no problem with generating pagination through javascript and php
you have same behaviour for initial load and subsequent loads(when user hides a post)
you can make the pagination work with jquery pretty easy
Related
A newbie here...I am trying to apply a system that allows readers to "infinitely" scroll down to the next posts after finishing a single post so that they don't have to manually click them.
(Like this website does:
https://dancingastronaut.com/2020/12/maceo-plex-confronts-racism-and-diversity-in-latest-single-cinemax/)
I tried the “auto load next post” plugin, but it didn’t work on my theme :(.
I’m currently using the Amphibious theme developed by templatepocket.
https://wordpress.org/themes/amphibious/
This is the biggest part I’m having a struggle with, and I think my website is good to go once it’s applied. I hope someone can help me out here!
Thanks!
You would first need to edit your single post template, usually single.php, and add a trigger when a user scrolls past that point.
<?php $gpNextPost = get_next_post(); ?>
<div class="gp-infinite-scroll" style="display: none;"><?php echo $gpNextPost->ID; ?></div>
Then call an AJAX function to load next post's content and also replace the URL in the browser's address bar.
Here's a rough example:
function gp_infinite_scroll($pid){
if (is_single()) { ?>
<script type="text/javascript" >
jQuery(document).ready(function($) {
$(window).scroll(function() {
var footerPos = $('footer').last().position().top;
var pos = $(window).scrollTop();
if (pos+(screen.height*4) > footerPos) {
if ($(".gp-infinite-scroll").first().hasClass('working')) {
return false;
} else {
$(".gp-infinite-scroll").first().addClass('working');
}
var gpNextPostId = $(".gp-infinite-scroll").first().text();
var data = {
'action': 'gp_is',
'gpNextPostId': gpNextPostId
};
$.post(ajaxurl, data, function(response) {
$(".gp-infinite-scroll").first().replaceWith(response);
}, 'html');
}
// Update new URL
var currUrl = $(".gp-post-header").first().attr("url");
var currTitle = $(".gp-post-header").first().attr("title");
if ($(".gp-post-header").length > 1 && history.pushState) {
for (var i=0; i<$(".gp-post-header").length; i++) {
var trigger = $(".gp-post-header").eq(i).next().position().top;
if (pos+(screen.height/2) >= trigger) {
currUrl = $(".gp-post-header").eq(i).attr("url");
currTitle = $(".gp-post-header").eq(i).attr("title");
}
}
}
if (location.href != currUrl) {
history.pushState({}, currTitle, currUrl);
}
});
});
</script>
<?php }
}
add_action( 'wp_head', 'gp_infinite_scroll' );
function gp_infinite_scroll_callback() {
if (isset($_POST['gpNextPostId']) && $_POST['gpNextPostId']) {
$the_query = new WP_Query(array('p'=>$_POST['gpNextPostId']));
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
// Change to your own Single Post template file
get_template_part( 'template-parts/content', 'single' );
}
}
wp_reset_postdata();
}
wp_die();
}
add_action( 'wp_ajax_gp_is', 'gp_infinite_scroll_callback' );
add_action( 'wp_ajax_nopriv_gp_is', 'gp_infinite_scroll_callback' );
This code is untested but it should get you going. If the above seems too much for you then you migh try some of the related plugins.
Let me explain clearly i have created one table in database with columns( bed_type, dimensions*thickness, price, ).refer image by default single is selected with dimension and thickness as shown in image now user can select select any bed type,dimension and thickness so according to that price will change I am sending ajax request to database if condition matched then i am getting price in this paragraph
<p class='prices' id='demo' style='margin-left:22%;'></p>
now i want to pass the calculated price in cart how can i achieve this. I am trying this task from last week but not getting any result. please guide me
Ajax for Bed Type
function price()
{
var current_id=this.id;
var dimension = document.getElementById(current_id).value; // dimension
var thickness = document.getElementById("thickness").value;
var res = dimension.concat('x'+thickness);
jQuery.ajax({
url: "/Mattressbox/price",
data: {price: res},
type: "POST",
success:function(data){
$("#result").html(data);
},
error:function (){}
});
}
price.php code
global $wpdb;
if(isset($_POST['price']))
{
$price_value = $_POST["price"];
$result = $wpdb->prepare("SELECT price FROM wp_single WHERE size='".$price_value ."'",$id,null);
$row = $wpdb->get_row($result);
$price = $row->price;
if($price > 0)
{
echo '<script>';
echo 'var name = ' . json_encode($price) . ';';
echo 'document.getElementById("demo").innerHTML ="₨ " + name;';
echo '</script>';
}
else
{
//echo "failed";
}
}
in this paragraph i am getting dynamic price using ajax
<p class='prices' id='demo' style='margin-left:22%;'></p>
now i am trying to pass this paragraph in place of custom price like this
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {
$custom_price = "<p class='prices' id='demo' style='margin-left:22%;'></p>"; // This will be your custom price
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = $custom;
}
}
only static price is going in cart but this is not working please suggest something...thank you..
I currently have a wordpress site setup using woocommerce and gravity forms plugins. I am selling bike wheels and on my product page I use gravity forms to display different customization options. the options are different if they select one wheel or two wheels.
What I'm trying to achieve
I want to add a 5% discount if two wheels are selected and 10% if four+ are selected. This discount is applied to the product as it is added to the cart.
I am attempting to create a custom plugin that uses javascript to get the value from the gravity forms input, and hooks into woocommerce to edit the total price before adding it to the cart.
What I have so far
custom.js
jQuery(document).ready(function () {
jQuery('.cart').submit(function () {
var noOfWheels = jQuery(".rdoWheel input[type='radio']:checked").val();
console.log(noOfWheels)
var data = {
action: 'my_discount',
wheels: noOfWheels
};
jQuery.ajax({
type: 'POST',
url: discountAjax.ajax_url,
data: data,
success: function (data) {
//do nothing
},
});
return false;
});
});
discount.php
add_action('wp_enqueue_scripts', 'load_script');
function load_script() {
wp_enqueue_script('discount', plugin_dir_url( __FILE__ ) . 'custom/custom.js', array( 'jquery' ) );
wp_localize_script('discount', 'discountAjax', array('ajaxurl' => admin_url('admin-ajax.php')));
}
add_action('wp_ajax_woocommerce_discount', 'calculate', 10);
add_action('wp_ajax_nopriv_woocommerce_discount', 'calculate', 10);
function calculate() {
if (isset($_POST['wheels'])) {
global $woocommerce;
$wheels = $_POST['wheels'];
if ($wheels === "1") {
$val = 0;
} elseif ($wheels === "2"){
$val = 10;
}
session_start();
$_SESSION['val'] = $val;
}
}
add_action('woocommerce_before_calculate_totals', 'add_discount');
function add_discount( $cart_object) {
#session_start();
if (isset($_SESSION['val'])) {
$wheels = $_SESSION['val'];
foreach ( $cart_object->cart_contents as $key => $value ) {
$c_price = $value['data']->price;
$discountAmount = $c_price * $wheels/100;
$value['data']->price = $value['data']->price - $discountAmount;
}
//for testing purpose
echo $_SESSION['val'];
echo 'completed';
unset($_SESSION['val']);
}
}
whats happening
It seems the woocommerce function is not firing at all. when i check with firebug I see my ajax request go through okay then nothing else. If i remove everything except for the add_discount function then it goes through and applies the discount. I cant seem to get it to work with javascript/ajax.
in WP 4.2 opening Add New Post page and without editing any fields, clicking on "Publish" button page is submitted and reopened, but no any of fields are marked with red background color as required.
How to make it? Seems, that is original behauvior of this page.
I want it to work like editor of categories, when in similar situation field name is marked with red background color as required.
Also I added several fields to New Post page using register_post_type function and I aslo want to marked with red background color as required. Which is the best way for this?
Thanks!
You can call your jquery validation by your self using below code,
Add this code in theme's functions.php and custom.js in your theme js folder
add_action( 'admin_print_scripts-post-new.php', 'custom_admin_script', 11 );
add_action( 'admin_print_scripts-post.php', 'custom_admin_script', 11 );
function custom_admin_script() {
global $post_type;
// Post type = "post" or "page" you can load script wheater it is post or page , if page then change 'post' to 'page' in below condition
if( 'post' == $post_type )
wp_enqueue_script( 'custom-admin-script', get_stylesheet_directory_uri() . '/js/custom.js' );
}
custom.js
jQuery(document).ready(function ($) {
if ($("#post").length > 0) {
var frm = true;
$("#publish").click(function () {
var title = $("#title").val();
var excerpt = $("#excerpt").val();
// your custom field variable goes here
if (jQuery.trim(title) == "" || jQuery.trim(excerpt) == "") {
frm = false;
}
if (frm == false) {
$("#publish").prop('disabled', true);
} else {
$("#publish").prop('disabled', false);
}
});
}
});
I have added a widget to a Page with a class of Page. The widget php code returns a PaginatedList and it is successfully rendering in my Page.ss template using the $SidebarView tag.
How can I hijack the pagination click to have the widget rendered with a new template? I assume that testing for is_ajax on the index method and doing a $this->renderWith('myTemplate') is not going to work since I only want to render the widget with the new template, not the whole page.
Here is my current Page.php code drawing from Zauberfisch's original answer:
public function index( SS_HTTPRequest $request ) {
$page = $this->data();
if ( $request->isAjax() ) {
$widgetArea = $page->Sidebar();
$widget = $widgetArea->Widgets()->filter( 'ClassName', 'ScbWidget' );
return $widget->renderWith( 'ScbTemplate' );
} else {
return array();
}
}
and here is my widget php code that returns the paginated list to my template:
public function ScbList() {
$list = new PaginatedList( CatalogItem::get()->filter( array( 'SchoolChoirRelease' => 1 ) ), Controller::curr()->getRequest() );
$list->setPageLength( $this->ShowPerPage );
return $list;
}
When the paginated list is returned to the template without ajax, everything works as expected - ?start=2 returns the list offset by 2 items. When I hijack the link and render the widget using the new template, my list is not being rendered in the new template. Here is my js:
ajaxify = function( href, callback ) {
$.ajax( {
url: href,
success: function( data ) {
callback( data );
}
});
};
hijackSubmit = function() {
jqueryMap.$pagination.on( 'click', 'a', function( e ) {
e.preventDefault();
var href = $( this ).attr( 'href' );
ajaxify( href, function( data ) {
jqueryMap.$container.html( data );
} );
});
};
In SilverStripe any object of type ViewableData can be rendered. Page is a subclass of ViewableData, but so is Widget. A lot of objects in SilverStripe extend ViewableData.
This means you are already on the right track.
I am assuming you have 2 variables:
$request a request object of type SS_HTTPRequest
(if you are in a Controller, you can get it like this: $request = $this->getRequest())
$page a page object of type Page or subclass.
(if you are in a Controller, you can get it like this: $page = $this->data())
now you should be able to do:
if ($request->isAjax()) {
$widgetArea = $page->SideBar();
$widget = $widgetArea->Widgets()->filter('ClassName', 'MyWidget')->First();
return $widget->renderWith('MyWidgetTemplate');
}
// do something else
NOTE: if $request->isAjax() is never true, add ?ajax=1 to the URL when you call it in javascript. ?ajax=1 will let SilverStripe know that this is an ajax request.