WordPress post pagination not working with ajax - ajax

I am trying to load my WordPress posts using ajax. I implemented the following functions to do the pagination for me.
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$the_query = new WP_Query(
array(
'posts_per_page' => 6,
'post_type' => 'post',
'paged' => $paged
)
);
<?php next_posts_link( 'Next →', $the_query ->max_num_pages); ?>
<?php previous_posts_link( 'Previous ← ' ); wp_reset_query();?>
When I try to navigate through the paginated link (Next/Previous), the URL is looking like this:
http://localhost/vendor/wp-admin/admin-ajax.php?paged=2
The URL i am trying to get:
http://localhost/vendor/vendorpage/page/2/
Is there any way to help me out?

Try the below code -
ob_start(); // Turn output buffering on
global $paged;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'posts_per_page' => 6,
'paged' => $paged,
'post_type' => 'post',
'orderby' => 'date',
'order' => 'DESC',
);
$the_query = new WP_Query($args);
if ($the_query->have_posts()) {
while ($the_query->have_posts()) {
$the_query->the_post();
//your code
}
$big = 999999999;
echo paginate_links(
array(
'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
'format' => '?paged=%#%',
'current' => max(
1,
get_query_var('paged')
),
'total' => $the_query->max_num_pages //$q is your custom query
)
);
}
return ob_get_clean();
wp_reset_query();

Related

Ajax Post Filter | Split Taxonomy Into minPrice & maxPrice

Very much hoping that somebody can help me out.
Currently creating my own Ajax Post Filter, using https://rudrastyh.com/wordpress/ajax-post-filters.html as a template. Is it possible to split one Custom Post Type Taxonomy - in this case PRICE - so that users can filter by both minimum price and maximum price?
At the moment I can only work out how to filter by singular values.
Any help will be greatly appreciated.
Thanks,
S
FUNCTIONS.PHP
add_action('wp_ajax_myfilter', 'misha_filter_function'); // wp_ajax_{ACTION HERE}
add_action('wp_ajax_nopriv_myfilter', 'misha_filter_function');
function misha_filter_function(){
$args = array(
'orderby' => 'date', // we will sort posts by date
'order' => $_POST['date'], // ASC or DESC
'posts_per_page' => -1 // show all posts.
);
if( isset( $_POST['builderfilter'] ) && $_POST['builderfilter'] )
$args['tax_query'][] = array(
'taxonomy' => 'builders',
'field' => 'id',
'terms' => $_POST['builderfilter']
);
if( isset( $_POST['yachtfilter'] ) && $_POST['yachtfilter'] )
$args['tax_query'][] = array(
'taxonomy' => 'yachttype',
'field' => 'id',
'terms' => $_POST['yachtfilter']
);
// create $args['meta_query'] array if one of the following fields is filled
if( isset( $_POST['price_min'] ) && $_POST['price_min'] || isset( $_POST['price_max'] ) && $_POST['price_max'] == 'on' )
$args['tax_query'] = array( 'relation'=>'AND' ); // AND means that all conditions of meta_query should be true
// if both minimum price and maximum price are specified we will use BETWEEN comparison
if( isset( $_POST['price_min'] ) && $_POST['price_min'] && isset( $_POST['price_max'] ) && $_POST['price_max'] ) {
$args['tax_query'][] = array(
'taxonomy' => 'builder_length',
'field' => 'id',
'value' => array( $_POST['price_min'], $_POST['price_max'] ),
'type' => 'numeric',
'compare' => 'between'
);
} else {
// if only min price is set
if( isset( $_POST['price_min'] ) && $_POST['price_min'] )
$args['tax_query'][] = array(
'taxonomy' => 'builder_length',
'field' => 'id',
'value' => $_POST['price_min'],
'type' => 'numeric',
'compare' => '>'
);
// if only max price is set
if( isset( $_POST['price_max'] ) && $_POST['price_max'] )
$args['tax_query'][] = array(
'taxonomy' => 'builder_length',
'field' => 'id',
'value' => $_POST['price_max'],
'type' => 'numeric',
'compare' => '<'
);
}
$query = new WP_Query( $args );
if( $query->have_posts() ) :
while( $query->have_posts() ): $query->the_post();
get_template_part( 'includes/brokerage-archive', get_post_format() );
endwhile;
wp_reset_postdata();
else :
echo 'No posts found';
endif;
die();
}
HTML / CSS / PHP
Just the section that I need to edit.
<div class="hero-spec-box brokerage">
<label for="builder">LENGTH</label>
<?php
if( $terms = get_terms( array( 'taxonomy' => 'builder_length', 'orderby' => 'name' ) ) ) :
echo '<select name="lengthfilter"><option value="">ALL</option>';
foreach ( $terms as $term ) :
echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; // ID of the category as the value of an option
endforeach;
echo '</select>';
endif;
?>
</div>

Form input not cleared after ajax submission

I have a form with one field and a submit button with ajax submission option like following -
public function buildForm(array $form, FormStateInterface $form_state, $id = 0)
{
$form['fieldset']['message'] = array(
'#type' => 'textfield',
'#default_value' => "",
'#required' => true,
'#attributes' => array(
'placeholder' => t('write here'),
),
);
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => $this->t('Send'),
'#attributes' => array(
'class' => array(
),
),
'#ajax' => [
'callback' => [$this, 'Ajaxsubmit'],
'event' => 'click']
);
return $form;
}
The ajax function is following -
public function Ajaxsubmit(array $form, FormStateInterface $form_state)
{
$user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());
$db_values = [
"message" => $form_state->getValue("message"),
"date_create" => date("Y-m-d H:i:s"),
];
$save = DbStorage::Insert($db_values);
//$('#mychat_form input').val("");
//$form_state->setValue('content', NULL);
$response = new AjaxResponse();
if ($form_state->hasAnyErrors() || !$save) {
$response->addCommand(new AlertCommand('something wrong!'));
} else {
$message = DbStorage::Get(["id" => $save]);
$send_id = $message->send_id;
$build = [
'#theme' => "chat_view",
'#message' => $message,
'#sender' => $send_id,
'#current_user' => true
];
$ans_text = render($build);
$response->addCommand(new AppendCommand('#mychat', $ans_text));
}
return $response;
}
Here form data submission is working fine. But input data is not cleared after submission. I tried to clear it from my javascript using -
$('#my_form input').val("");
But the problem is my javascript file is called every 3 seconds and the form input is also cleared in every 3 seconds. this is problematic for users. Is there any other way to clear the form input after the ajax submission ? Can i do anything inside Ajaxsubmit function ?
You can use InvokeCommand for doing it.
For e.g: to clear an input value $('#my_form input').val(""); in ajax response
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Ajax\AppendCommand;
:
$form['fieldset']['message'] = array(
'#type' => 'textfield',
'#default_value' => "",
'#required' => true,
'#attributes' => array(
'placeholder' => t('write here'),
'class' => ['custom-class'],
),
);
In Ajax function
:
$build = [
'#theme' => "chat_view",
'#message' => $message,
'#sender' => $send_id,
'#current_user' => true
];
$response->addCommand(new AppendCommand('#mychat', $build));
$response->addCommand(new InvokeCommand('.custom-class', 'val', ['']));

WP_Query() 'orderby' => 'title' not working

So I have this query
$args = array(
'post_type' => 'course', // custom post type
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title'
);
$courses = new WP_Query($args);
This gives me what I want, but the orderby statement is being ignored. When I dump the $courses->request I get this
'SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_type
= 'course' AND ((wp_posts.post_status = 'publish')) ORDER BY wp_posts.menu_order ASC '
It is defaulting the orderby to menu_order instead of title. What's going on here?
I was facing the same issue and I solved it using 'post_title' instead of 'title'.
$args = array(
'post_type' => 'course', // custom post type
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'post_title' // change here
);
$courses = new WP_Query($args);
check whether you have used parse_query or pre_get_posts
hook somewhere in the website
add_action( 'pre_get_posts', 'function_name' );
add_filter( 'parse_query', 'function_name' );

Fetch products if image is found in woocommerce and filter the products

I have a big problem, I used this code in my website - fetch products if image is found in woocommerce?
<?php
$args = array(
'post_type' => 'product',
'stock' => 1,
'posts_per_page' => 9,
'orderby' =>'date',
'orderby' => 'rand',
'meta_query'=>array(
array(
'key'=>'_thumbnail_id',
'compare' => 'EXISTS'
)
)
);
$loop = new WP_Query( $args );
while ($loop->have_posts()) : $loop->the_post();
echo get_the_post_thumbnail($loop->post->ID, 'shop_catalog');
endwhile;
?>
But I can't filter the products, do I have to put some variable in orderby?
I can't put this in order

A related Model isn't being validated

I currently have the following models:
class Category extends AppModel {
var $name = 'Category';
/*var $validate = array(
'name' => 'multiple'
);
no idea how to use this
*/
var $hasAndBelongsToMany = array(
'Post' => array(
'className' => 'Post'
)
);
class Post extends AppModel {
var $name = 'Post';
var $hasAndBelongsToMany = array(
'Category' => array(
'className' => 'Category'
)
);
var $belongsTo = array(
'Page' => array(
'className' => 'Page'
)
);
class Page extends AppModel {
var $name = 'Page';
var $order = array('Page.modified' => 'desc');
var $hasOne = array(
'Post' => array(
'className' => 'Post'
));
I also have this Form in the view:
<div id="content-wrap">
<div id="main">
<h2>Add Post</h2>
<?php echo $this->Session->flash();?>
<div>
<?php
echo $this->Form->create('Post');
echo $this->Form->input('Post.title');
echo $this->Form->input('Category.Category', array('multiple' => 'checkbox'));
echo $this->Form->input('Post.body', array('rows' => '3'));
echo $this->Form->input('Page.meta_keywords');
echo $this->Form->input('Page.meta_description');
echo $this->Form->end('Save Post');
?>
</div>
<!-- main ends -->
</div>
My Controller:
function admin_add() {
// pr(Debugger::trace());
$this->set('categories', $this->Post->Category->find('list'));
if ( ! empty($this->data)) {
$this->data['Page']['title'] = $this->data['Post']['title'];
$this->data['Page']['layout'] = 'index';
if ($this->Post->saveAll($this->data)) {
$this->Session->setFlash('Your post has been saved', 'flash_good');
$this->redirect($this->here);
}
}
}
The problem I am having is that I could save a Post without choosing a category for it.
I've tried adding the following as a rule to the Category Model:
var $validate = array(
'rule' => array('multiple', array('in' => array(1, 2, 3, 4))),
'required' => TRUE,
'message' => 'Please select one, two or three options'
);
The Post and Page Model validates.
How do I activate validation for the Category?
First off, you haven't set up the $validate variable properly. The keys in the $validate array must be field names. Secondly, the multiple rule is used to check if the value(s) of a field lies within a set of values.
var $validate = array(
'color' => array(
'multiple' => array(
'rule' => array('multiple', array('in' => array('Red', 'Blue', 'Green'))),
'required' => false,
'message' => 'Please select one, two or three options'
),
),
);
I checked the example in the book for multiple and it's a typo there. The above code is correct.
Next, if you want to validate related models, I suggest you do that in your beforeSave() function:
function beforeSave(){
if (isset($this->data['Category']['Category']) && empty($this->data['Category']['Category'])) {
return false;
}
return true;
}
Here, returning false from the beforeSave() would prevent the save from going through. So, you will have successfully validated your requirement.

Resources