In a custom Woocommerce products page I filter posts_per_page with a dropdown menu. It works well and the table is updated with the new value.
But then if I click on the 'Next' button, next_posts_link doesn't post the new posts_per_page value, and the second page starts from record #11, as default.
Any solution?
<?php
$prodNum = $_POST['num_prods'];
?>
<!-- SELECT POST PER PAGES -->
<form id="numProdsForm" method="POST">
<select name="num_prods" id="num_prods" onchange="this.form.submit()">
<option value="10" <?php if ($prodNum==10){ ?> selected <?php } ?>>10</option>
<option value="20" <?php if ($prodNum==20){ ?> selected <?php } ?>>20</option>
<option value="30" <?php if ($prodNum==30){ ?> selected <?php } ?>>30</option>
<option value="50" <?php if ($prodNum==40){ ?> selected <?php } ?>>50</option>
<option value="100" <?php if ($prodNum==50){ ?> selected <?php } ?>>100</option>
</select>
</form>
<!-- CUSTOM TABLE -->
<table>
<?php if ( woocommerce_product_loop() ) { ?>
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => $prodNum,
'orderby'=>'title',
'order' => 'ASC'
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
global $product;
?>
<tr>
<td class="flex-row" role="cell"><?php echo $product->get_attribute( 'color' ); ?></td>
</tr>
<?php endwhile; ?>
<?php wp_reset_query(); ?>
<?php
} else {
do_action( 'woocommerce_no_products_found' );
}
?>
</table>
<div class="products-pagination">
<?php previous_posts_link( '« PREV', $loop->max_num_pages) ?>
<?php next_posts_link( 'NEXT »', $loop->max_num_pages) ?>
</div>
I've tried to put the pagination before wp_reset_query();, or to use get $paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1; but nothing changes.
You could try using a "GET" rather than "POST" for the form, and pass the offset and number of posts to show as URL params. Then you can add the offset attribute to the query. You can also optimize some of your code by using selected selected function definition rather than your if statements for the options.
<?php
$product_number = ( isset( $_GET['num_prods'] ) ) ? absint( $_GET['num_prods'] ) : 0;
$existing_offset = ( isset( $_GET['offset'] ) ) ? absint( $_GET['offset'] ) : 0;
$offset = $product_number + $existing_offset;
?>
<!-- SELECT POST PER PAGES -->
<form id="numProdsForm" method="GET">
<input type="hidden" name="offset" value="<?php echo esc_attr( $offset ); ?>">
<select name="num_prods" id="num_prods" onchange="this.form.submit()">
<option value=""> - - Choose Number of Products to Show -- </option>
<option value="10" <?php selected( 10, $product_number ); ?>>10</option>
<option value="20" <?php selected( 20, $product_number ); ?>>20</option>
<option value="30" <?php selected( 30, $product_number ); ?>>30</option>
<option value="50" <?php selected( 50, $product_number ); ?>>50</option>
<option value="100" <?php selected( 100, $product_number ); ?>>100</option>
</select>
</form>
<!-- CUSTOM TABLE -->
<table>
<?php if ( woocommerce_product_loop() ) { ?>
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => $product_number,
'offset' => $offset, // the offset.
'orderby' => 'title',
'order' => 'ASC',
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) :
$loop->the_post();
global $product;
?>
<tr>
<td class="flex-row" role="cell"><?php echo $product->get_attribute( 'color' ); ?></td>
</tr>
<?php endwhile; ?>
<?php wp_reset_postdata(); // use wp_reset_postdata(). ?>
<?php
} else {
do_action( 'woocommerce_no_products_found' );
}
?>
</table>
<div class="products-pagination">
<?php previous_posts_link( '« PREV', $loop->max_num_pages ); ?>
<?php next_posts_link( 'NEXT »', $loop->max_num_pages ); ?>
</div>
Related
Wanted to have a feature of a dropdown on my custom archive template like this https://facetwp.com/demo/cars/?_sort=title_asc
here is my code but doesnt sort any of the custom post either by title or for ratings.
<?php
$order = "&order=ASC";
if ($_POST['select'] == 'rmp_get_avg_rating') { $order =
"&order=ASC&orderby=ratings"; }
if ($_POST['select'] == 'title') { $order =
"&order=ASC&orderby=title"; }
?>
<form method="post" id="order">
Sort by:
<select name="select" onchange='this.form.submit()'>
<option value="ratings"<?php selected(
$_POST['select'],'rmp_get_avg_rating', 1 ); ?>>Highest Rated</option>
<option value="alphabetical"<?php selected(
$_POST['select'],'alphabetical' , 1 ); ?>>Alphabetical</option>
</select>
</form>
<?php $loop = new WP_Query(
array(
'post_type' => 'company',
'orderby' => 'title',
'order' => 'ASC',
'posts_per_page' => -1
)
);
?>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
Ok I managed to resolved this
here is the working code
<?php
$loop = isset($_GET['orderby']) ? sanitize_text_field($_GET['orderby']) :
"";
if(!empty($loop) && "title" == $loop):
$loop = new WP_Query(array(
'post_type'=>'company',
'posts_per_page'=>-1,
'orderby'=> "title",
'order'=>'ASC',
));
endif;
if(!empty($loop) && "rmp_get_avg_rating" == $loop):
$loop = new WP_Query(array(
'post_type'=>'company',
'posts_per_page'=>-1,
'orderby'=> "rmp_get_avg_rating",
'order'=>'ASC',
));
endif;
?>
<form method="GET">
<select name="orderby" id="orderby">
<option value="select">Select</option>
<option value="rmp_get_avg_rating">Highest Rated</option>
<option value="title">Alphabetical</option>
</select>
<button type="submit">Apply</button>
</form>
</div>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
i've been at this for a couple of evening now, i've tried many different solutions and would rather keep it PHP rather than a jQuery solution or AJAX, here's my code, for some reason the Select Dropdown just won't keep it's value, any advice would be amazing. Thanks in advance.
<?php
$taxonomy = 'accommodation_area';
$args = array(
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => true
);
$tax_terms = get_terms( $taxonomy, $args );
?>
<select name="<? echo $taxonomy ?>" id="<? echo $taxonomy ?>" class="postform">
<option>Choose Area</option>
<?php if($tax_terms): ?>
<?php foreach ($tax_terms as $tax_term): ?>
<option value="<?php echo $tax_term->slug; ?>" <?php if ( isset( $_POST[ $taxonomy ] ) && ( $_POST[ $taxonomy ] == $tax_term->slug ) ) echo "selected";?>><?php echo $tax_term->name; ?></option>
<?php endforeach; ?>
<?php endif; ?>
</select>
I am looking for a way to retain the selection from a a list of options which are created from within a WordPress post loop:
<?php
$args = array( 'post_type' => 'office_locations', 'posts_per_page' => -1, 'order_by' => 'title', 'order' => 'ASC' );
$loop = new WP_Query( $args ); ?>
<select style="width: 100%;" name="selectedValue" onchange="this.form.submit()">
<option disabled>Select an office location...</option> // This is disabled
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
<option><?php echo get_the_title();?></option>
<?php endwhile; ?>
</select>
So if a User makes a selection I have set it to post that upon selection, is there a way for the select to remain on that option after this happens?
Sure, check the value of POST matches the value of the select, then set as selected:
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
<option<?= (isset($_POST['selectedValue']) && $_POST['selectedValue'] == get_the_title() ? ' selected' : null) ?>><?php echo get_the_title();?></option>
<?php endwhile; ?>
I've got nested dropdown & I get format problems with more than 2 times nested items. Im pretty sure my "Mona Lisa" quality image made in Paint will demonstrate it perfectly.
Im looking for any suggestions what to change about my code to make it work properly.
IMAGE ABOUT MY PROBLEM:
CODE:
<div class="form-group">
<label for="p-location"><?php _e( 'Location', 'tt' ); ?></label>
<select name="p-location" id="p-location" class="form-control required" title="<?php _e( 'Please select the location.', 'tt' ); ?>" data-placeholder="<?php _e( 'Choose a location', 'tt' ); ?>">
<option value=""></option>
<?php
$locations = get_terms('p-location', array( 'orderby' => 'slug', 'parent' => 0, 'hide_empty' => false) );
if ( isset( $_GET['p_location'] ) ) {
$get_location = $_GET['p_location'];
}
else {
$get_location = '';
}
$p_locations = get_the_terms( $p_id , 'p-location' );
if ( !empty( $p_locations ) ) {
foreach ( $p_locations as $p_location ) {
$get_location = $p_location->term_id;
break;
}
}
?>
<?php foreach ( $locations as $key => $location ) : ?>
<option value="<?php echo $location->term_id; ?>" <?php selected( $location->term_id, $get_location ); ?>>
<?php
echo $location->name;
$location2 = get_terms( 'p-location', array( 'orderby' => 'slug', 'parent' => $location->term_id, 'hide_empty' => false ) );
if( $location2 ) :
?>
<optgroup>
<?php foreach( $location2 as $key => $location2 ) : ?>
<option value="<?php echo $location2->term_id; ?>" class="level2" <?php selected( $location2->term_id, $get_location ); ?>>
<?php
echo $location2->name;
$location3 = get_terms( 'p-location', array( 'orderby' => 'slug', 'parent' => $location2->term_id, 'hide_empty' => false ) );
if( $location3 ) : ?>
<optgroup>
<?php foreach( $location3 as $key => $location3 ) : ?>
<option value="<?php echo $location3->term_id; ?>" class="level3" <?php selected( $location3->term_id, $get_location ); ?>>
<?php
echo $location3->name;
$location4 = get_terms( 'p-location', array( 'orderby' => 'slug', 'parent' => $location3->term_id, 'hide_empty' => false ) );
if( $location4 ) :
?>
<optgroup>
<?php foreach( $location4 as $key => $location4 ) : ?>
<option value="<?php echo $location4->term_id; ?>" class="level4" <?php selected( $location4->term_id, $get_location ); ?>>
<?php echo $location4->name; ?>
</option>
<?php endforeach; ?>
</optgroup>
<?php endif; ?>
</option>
<?php endforeach; ?>
</optgroup>
<?php endif; ?>
</option>
<?php endforeach; ?>
</optgroup>
<?php endif; ?>
</option>
<?php endforeach; ?>
</select>
</div>
Can you show how it renders now in your browser? As mentioned here current HTML spec does not include multi-nested optgroups, so I'm not sure how you achieve 3rd level indentation there.
So there are two solutions of your problem:
easier is using x times = your current nested level. See here:
<body>
<select>
<option>Option 1</option>
<option>Option 2</option>
<!-- as many 's as the nest level you need -->
<option> Option 3</option>
<option> Option 4</option>
<!-- as many 's as the nest level you need -->
<option> Option 3</option>
<option> Option 4</option>
<!-- as many 's as the nest level you need -->
<option> Option 5</option>
<option> Option 6</option>
</select>
</body>
using kind of UI library such as this one + indenting your groups with CSS paddings
I have this custom loop and for some reason the "Sort" isn't working.
<?php
if(isset($_REQUEST['sort'])){
if($_REQUEST['sort'] == 'newest' )
$order = "&orderby=title&order=DESC";
else if($_REQUEST['sort'] == 'oldest' )
$order = "&orderby=title&order=ASC";
else if($_REQUEST['views'] == 'oldest' )
$order = "&meta_key=views&orderby=meta_value_num&order=DESC";
}
else
$order = "&orderby=ID&order=DESC";
?>
<form method="post" id="order">
<select name="sort" onchange='this.form.submit()'>
<option value="newest">Sort by Newest</option>
<option value="oldest">Sort by Oldest</option>
<option value="views">Sort by Most Viewed</option>
</select>
</form>
<ul class="acapellas row">
<?php
$loop = new WP_Query( array(
'post_type' => 'acapella',
'posts_per_page' => 10,
'paged' => $paged,
'orderby' => 'date',
'order' => $_POST['sort']
) );
?>
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ?>
<?php if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post(); ?>
<?php $posts = query_posts($query_string . $order); ?>
<li class="post-<?php the_ID(); ?> col-md-6">
<div class="wrap">
<h2><?php the_title() ?></h2>
<?php if(pmpro_hasMembershipLevel($level_id)) { ?>
<?php the_content(); ?>
<?php } else { ?>
<div class="pro-player">
<div class="upgrade">
<a href="<?php bloginfo('url'); ?>/pro" >Upgrade to unlock</a>
</div>
</div>
<?php } ?>
<a class="download left" href="<?php the_permalink(); ?>">Download</a>
<span class="list-date right">First added: <?php the_time('F jS, Y') ?></span><br>
<?php
global $post;
$post_type = get_post_type(get_the_ID());
$post_type_taxonomies = get_object_taxonomies($post_type);
if (!empty($post_type_taxonomies)) {
echo '<ul class="details">';
foreach ($post_type_taxonomies as $taxonomy) {
$terms = get_the_term_list(get_the_ID(), $taxonomy, '', '</li><li>', '');
if ($terms) {
echo '<li>' . $terms . '</li>';
}
}
echo '</ul>';
}
?>
</div>
</li>
<?php endwhile; endif; ?>
</ul>
You can use function get_posts().
$posts = get_posts([
'orderby' => 'date',
'order' => $_POST['sort']
]);
And send post variable 'ASC' or 'DESC' - that will be the newest or oldest