Chained selects in Wordpress via AJAX - ajax

I need to make two chained select inputs (country, city) in WP.
(all is in locations taxonomy, country is a main category and city is a subcategory)
in first select i listed all countries:
$locations = get_terms( ‘locations’, array(
‘hide_empty’ => false,
‘parent’ => 0 ) );
In second select i need only the cities depend on selected country
(without page refresh/submit, so with AJAX)
I need passing selected value from first select to php variable:
$whichCountry = AJAX RESPONSE HERE
Listing second select:
$locations = get_terms( ‘locations’, array(
‘hide_empty’ => false,
‘parent’ => $whichCounty) );
Please help me how to achieve this
i make same code but its not enough:
JS:
(function ($) {
$(document).ready(function () {
$(‘#first_select’).on(‘change’, function(){
$.post(
PT_Ajax.ajaxurl,
{
// wp ajax action
action: ‘ajax-inputtitleSubmit’,
// vars
data: $(‘#first-select’).val(),
// send the nonce along with the request
nextNonce: PT_Ajax.nextNonce
},
function (response) {
console.log(response.data);
}
);
return false;
});
});
})(jQuery);
PHP:
add_action( ‘wp_enqueue_scripts’, ‘inputtitle_submit_scripts’ );
add_action( ‘wp_ajax_ajax-inputtitleSubmit’, ‘myajax_inputtitleSubmit_func’ );
add_action( ‘wp_ajax_nopriv_ajax-inputtitleSubmit’, ‘myajax_inputtitleSubmit_func’ );
function inputtitle_submit_scripts() {
wp_enqueue_script( ‘inputtitle_submit’, get_template_directory_uri() . ‘/assets/js/inputtitle_submit.js’, array( ‘jquery’ ) );
wp_localize_script( ‘inputtitle_submit’, ‘PT_Ajax’, array(
‘ajaxurl’ => admin_url( ‘admin-ajax.php’ ),
‘nextNonce’ => wp_create_nonce( ‘myajax-next-nonce’ )
)
);
}
function myajax_inputtitleSubmit_func() {
// check nonce
$nonce = $_POST[‘nextNonce’];
if ( ! wp_verify_nonce( $nonce, ‘myajax-next-nonce’ ) ) {
die ( ‘Busted!’ );
}
// generate the response
$response = json_encode( $_POST );
// response output
header( “Content-Type: application/json” );
$whichCountry = $response;
// IMPORTANT: don’t forget to “exit”
exit;
}
Functions.php
include_once(‘inputtitle_submit_inc.php’)

Related

How to set an ajax url in wordpress? I want to call it with datatables.net in server side processing mode

I want to set up an ajax url to use it with Datatables in wordpress. But I don't know how I would set up the corresponding url in wordpress. I guess its a rather easy task but don't know how to do it.
I found example code how to set up datatables server side processing in wordpress but I am struggling to put the following code in real life (how to create the corresponding FrontendConfig.ajaxurl in Wordpress? Or would it be better to create a wordpress json endpoint?)
jQuery
jQuery('#student_table').DataTable({
"bProcessing": true,
"serverSide": true,
"ajax":{
"url": FrontendConfig.ajaxurl+'?action=getStudentsFromExamIdAjax&exam_nounce=exam_nounce_data&exam_id=1',
type: "post",
}
});
Wordpress php
add_action('wp_ajax_getStudentsFromExamIdAjax', 'getStudentsFromExamIdAjax' );
add_action('wp_ajax_nopriv_getStudentsFromExamIdAjax', 'getStudentsFromExamIdAjax' );
function getStudentsFromExamIdAjax(){
if(empty($_GET['action']) || empty($_GET['exam_id'])){
wp_send_json_error( new \WP_Error( 'Bad Request' ) );
}
if(isset($_GET['exam_id']) && $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( $_GET['exam_nounce'], 'exam_nounce_data' )):
$exam_id = (isset($_GET['exam_id'])) ? absint($_GET['exam_id']) : '';
/*# You can create a function to get the data here */
$students = getStudentsFromExamId($exam_id);
$tdata = [];
foreach ($students as $key => $value):
$tdata[$key][] = $value->roll_no;
$tdata[$key][] = $value->name;
$tdata[$key][] = $value->phone;
$tdata[$key][] = 'action here';
endforeach;
$total_records = count($tdata);
$json_data = array(
/* $_REQUEST['draw'] comes from the datatable, you can print to ensure that */
"draw" => intval( $_REQUEST['draw'] ),
"recordsTotal" => intval( $total_records ),
"recordsFiltered" => intval( $total_records ),
"data" => $tdata
);
echo json_encode($json_data);
endif;
wp_die();
}
You just need to set the following enqueue_style_and_scripts into your function.php file. You need to set wp_localize_script, check this link https://developer.wordpress.org/reference/functions/wp_localize_script/. Don't forget to change the code as per your coding requirement.
/*# Enqueue styles & scripts */
if( !function_exists('enqueue_style_and_scripts') ):
function enqueue_style_and_scripts(){
$version = wp_get_theme()->get('Version');
wp_enqueue_script(
'general_js',
get_stylesheet_directory_uri() . '/assets/js/general.js',
array('jquery'),
$version,
true
);
$frontendconfig = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'is_user_logged_in' => is_user_logged_in(),
);
wp_localize_script( 'general_js', 'FrontendConfig', $frontendconfig );
}
add_action('wp_enqueue_scripts', 'enqueue_style_and_scripts');
endif;

Wordpress Lazy Loading using Pagination

im doing a lazy loading with WP_Query Pagination
it's working fine but the content duplicate itself when it reaches it's end
and when i search for a specific result it shows the result correctly
but after that it still want to do lazy load so it load random data
here is my code
lazy-load.php
<?php
add_action('wp_ajax_nopriv_load_posts_by_ajax', 'load_posts_by_ajax_callback');
add_action('wp_ajax_load_posts_by_ajax', 'load_posts_by_ajax_callback');
function load_posts_by_ajax_callback(){
// check_ajax_referer( 'load_more_posts', 'security' );
$paged = $_POST['page'];
$args = array(
'post_type' => 'unit',
'post_status' => 'publish',
'posts_per_page' => 4,
'paged' => $paged
);
if ( !empty($_POST['taxonomy']) && !empty($_POST['term_id']) ){
$args['tax_query'] = array (
array(
'taxonomy' => $_POST['taxonomy'],
'terms' => $_POST['term_id'],
),
);
}
if ( ! is_null($_POST['offer']) ) {
$args['meta_query'][] = array(
'key' => 'WAKEB_hot',
'value' => '1',
'compare' => '=',
);
}
if ( ! is_null($_POST['purpose']) ) {
$args['meta_query'][] = array(
'key' => 'WAKEB_vacation',
'value' => '1',
'compare' => '=',
);
}
if (!empty($_POST['project'])){
$args['meta_query'] = array (
array(
'key' => 'WAKEB_project',
'value' => $_POST['project'],
'compare' => '='
),
);
}
// start buffer
ob_start();
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
while($query->have_posts()){ $query->the_post();
get_template_part("template-parts/units");
}
endif; wp_reset_postdata();
// start buffered data in data variable
$data = ob_get_clean();
wp_send_json_success( $data );
wp_die();
}
add_action('wp_ajax_nopriv_load_projects_by_ajax', 'load_projects_by_ajax_callback');
add_action('wp_ajax_load_projects_by_ajax', 'load_projects_by_ajax_callback');
function load_projects_by_ajax_callback(){
// check_ajax_referer( 'load_more_posts', 'security' );
$paged = $_POST['page'];
$args = array(
'post_type' => 'project',
'post_status' => 'publish',
'posts_per_page' => 4,
'paged' => $paged
);
if ( ! is_null($_POST['ptype']) ) {
$args['tax_query'] = array (
array(
'taxonomy' => 'pptypes',
'field' => 'slug',
'terms' => $_POST['ptype'],
),
);
}
if ( !empty($_POST['taxonomy']) && !empty($_POST['term_id']) ){
$args['tax_query'] = array (
array(
'taxonomy' => $_POST['taxonomy'],
'terms' => $_POST['term_id'],
),
);
}
// start buffer
ob_start();
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
while($query->have_posts()){ $query->the_post();
get_template_part("template-parts/projects");
}
endif; wp_reset_postdata();
// start buffered data in data variable
$data = ob_get_clean();
wp_send_json_success( $data );
wp_die();
}
lazy-load.js
$('.unit-terms li a').each( function() {
if ( this.href == window.location.href ) {
$(this).parent().addClass('current');
}
});
main.js
(function($){
$('.isotope a').on('click', function(){
$('.isotope .active').removeClass('active');
$(this).addClass('active');
var filter = $(this).data('filter');
if(filter=='*'){
$('.property').show();
}else{
$('.property').not(filter).hide();
$('.property'+filter).show();
}
return false;
});
})(jQuery);
so how can i make it work? i don't know what im doing wrong here
Here is the repo link for the full project
https://github.com/Ov3rControl/hoomerz
ok, now I understand what you meant ;) During lazy load you send to backend only page number without current state of filters and / or search string. So it sends all posttype items based on page number only. You should send also current state of filters
main.js: add this to your after-page-load function:
var currentUrl = new URL(window.location.href);
var searchQuery = urlObj.searchParams.get("k");
lazy-load.js: add search param to data posted to backend
var data = {
'action': 'load_posts_by_ajax',
'page': page,
'search: searchQuery // new field
};
lazy-load.php: add search param to WP_Query
if ( isset($_POST['search']) && !empty($_POST['search']) ){ // new section
$args['s'] = sanitize_text_field($_POST['search']);
}
That's example for text search filter. For all filters you must
1. match every filter from front (URL get param) (main.js)
2. than put it in data object sent to backend (lazy-load.js)
3. address this variable in lazy-load.php in if(isset($_POST['param-name'])) section ( new or existing one as there are some )
I suggest to try without ob_start() / ob_get_clean(). Also if you generate html instead of raw data structure, I would simply print it to output without wp_send_json_success().
Other solution would be sending raw data (1. array in php, 2. json_encode(), 3. wp_send_json() ) and than processing in javascript (dynamic dom element creation after request to backend made).

Different ajax search on multiple pages - Wordpress

i need to perform 2 different searches for 2 different pages
This is first one, and second one would be 10 posts per page and different post type, i've tried using is_page() but it doesn't work since it trows 0 results and i've checked if there are any
function ja_ajax_search() {
$results = new WP_Query( array(
'post_type' => array( 'post', 'page' ),
'posts_per_page' => 5,
's' => stripslashes( $_POST['search'] ),
) );
$items = array();
if ( ! empty( $results->posts ) ) {
foreach ( $results->posts as $result ) {
$items[] = $result->post_title;
}
}
wp_send_json_success( $items );
}
add_action( 'wp_ajax_search_site', 'ja_ajax_search' );
add_action( 'wp_ajax_nopriv_search_site', 'ja_ajax_search' );
/*eslint-disable */
jQuery(function ($) {
var searchRequest;
$('#ses').autoComplete({
minChars: 3,
source: function (term, suggest) {
searchRequest = $.post(global.ajax, {search: term, action: 'search_site',tip_pretrage: 'cards'}, function (res) {
suggest(res.data);
});
},
})
});

YII CListView Ajax multiple TextField filter

I have a CListView which I want to filter using Ajax. I have 2 textfields. Now they both filter the same column: titel. I'm searching quite some time now, but I can't seem to figger out why they both filter the titel and not the locatie too..
It's my first time to use Ajax so, i'm afraid I don't know exactly how to pass the right parameters at the moment and am kind of lost. Someone who can help me?
So here's my view:
<?php echo CHtml::beginForm(CHtml::normalizeUrl(array('kunstwerk/index')), 'get', array('id'=>'filter-form'))?>
<?php echo CHtml::textField('string', (isset($_GET['string'])) ? $_GET['string'] : '', array('id'=>'locatie'));?>
<?php echo CHtml::textField('string', (isset($_GET['string'])) ? $_GET['string'] : '', array('id'=>'titel'));?>
and..
Yii::app()->clientScript->registerScript('search',
"var ajaxUpdateTimeout;
var ajaxRequest;
$('input#titel').keyup(function(){
titel = $(this).serialize();
clearTimeout(ajaxUpdateTimeout);
ajaxUpdateTimeout = setTimeout(function () {
$.fn.yiiListView.update(
// this is the id of the CListView
'ajaxListView',
{data: titel}
)
},
// this is the delay
300);
});
$('input#locatie').keyup(function(){
locatie = $(this).serialize();
clearTimeout(ajaxUpdateTimeout);
ajaxUpdateTimeout = setTimeout(function () {
$.fn.yiiListView.update(
// this is the id of the CListView
'ajaxListView',
{data: locatie}
)
},
// this is the delay
300);
});"
);
and..
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
'sortableAttributes'=>array(
'titel'
),
'id'=>'ajaxListView',
));
?>
Here's my controller:
public function actionIndex($string = '')
{
$criteria = new CDbCriteria();
if( strlen( $string ) > 0 )
$criteria->addSearchCondition( 'titel', $string, true, 'OR' );
$criteria->addSearchCondition( 'locatie', $string, true, 'OR' );
$dataProvider = new CActiveDataProvider( 'Kunstwerk', array( 'criteria' => $criteria, ) );
//$dataProvider=new CActiveDataProvider('Kunstwerk');
$this->render('index',array(
'dataProvider'=>$dataProvider,
'bedrijven' => Bedrijf::model()->findAll(),
));
}

Adding wp_editor inside a thickbox

I would like to add a wp_editor inside a modal dialog (thickbox) at frontend but only gets an empty editor with no buttons on in. (WordPress 3.5 and plugin development)
The wp_editor is attached via an ajax call...
It seems like some important javascripts is missing to the page.
Is it possible to preload editor scripts i WP in some way?
Here is a sample plugin to expose the problem (adds a edit link to every content):
<?php
/*
Plugin Name: ThickboxEditor
*/
$thickboxeditor = new ThickboxEditor();
class ThickboxEditor{
function __construct()
{
add_action( 'wp_print_styles', array( &$this, 'wp_print_styles' ) );
add_action( 'init', array( &$this, 'init' ) );
add_filter( 'the_content', array( &$this, 'the_content' ) );
add_action( 'wp_ajax_thickboxeditor', array( &$this, 'editor' ) );
add_action( 'wp_ajax_nopriv_thickboxeditor', array( &$this, 'editor' ) );
}
function the_content( $content ){
$content .= 'EDIT THICKBOXEDITOR';
return $content;
}
function editor(){
wp_editor( $this->postcontent, 'postcontent', array(
'media_buttons' => false,
'teeny' => false,
'textarea_rows' => '7',
'tinymce' => array( 'plugins' => 'inlinepopups, fullscreen, wordpress, wplink, wpdialogs' )
) );
die(0);
}
}
?>
UPDATE
Thanks to #danielauener one solution is to initialize mceAddControl. So here is a working sample of the same plugin:
<?php
/*
Plugin Name: ThickboxEditor
*/
$thickboxeditor = new ThickboxEditor();
class ThickboxEditor{
function __construct()
{
add_action( 'wp_print_styles', array( &$this, 'wp_print_styles' ) );
add_action( 'init', array( &$this, 'init' ) );
add_filter( 'the_content', array( &$this, 'the_content' ) );
add_action( 'wp_ajax_thickboxeditor', array( &$this, 'editor' ) );
add_action( 'wp_ajax_nopriv_thickboxeditor', array( &$this, 'editor' ) );
add_action( 'wp_footer', array( &$this, 'wp_footer' ) );
}
function wp_footer(){
echo '<!--';
wp_editor( '', 'invisible_editor_for_initialization' );
echo '-->';
}
function the_content( $content ){
$content .= 'EDIT THICKBOXEDITOR';
return $content;
}
function editor(){
wp_editor( '', 'postcontent', array(
'media_buttons' => false,
'teeny' => false,
'textarea_rows' => '7',
'tinymce' => array( 'plugins' => 'inlinepopups, fullscreen, wordpress, wplink, wpdialogs' )
) );
?>
<script language="javascript">
jQuery(document).ready(function(){
tinymce.execCommand('mceAddControl',true,'postcontent');
});
</script>
<?php
die(0);
}
}
?>
It would be really nice to skip the ugly wp_editor initialization :-)
Funny, that thickbox doesn't provides any callbacks. But as I mentioned on twitter, I would try a $.ajaxSuccess call to solve the ugly js-inject. Just add the following to one of your javascript files:
(function($) {
// gets called for every successful ajax call
$(document).ajaxSuccess( function(evt, request, settings) {
// make sure this call was from your thickbox
if ($('#your-thickbox-selector').length > 0) {
tinymce.execCommand('mceAddControl',true,'postcontent');
}
});
})( jQuery );
UPDATE: The ajaxSuccess method has to be assigned to an element, changed the code

Resources