Good afternoon devs, I developed a favorite system using Wordpress and php, it works as follows, clicking on the add favorites icon I send an ajax request to php with the favorite id and the user id logged in. php processes this by saving in user_meta the information with number of favorite users and in the logged user an array with the ids of the favorites. Anyway, the question is, the system is working, but whenever I develop something I keep wondering if there is a way to improve the code, if there is a way to do it in a better way, I will leave my code here.
All this for learning ok?
HTML
<div class="stats -favorites">
<a class="icon -click <?php echo is_favorite(get_current_user_id(), $user_ID) ? 'fa' : 'far' ?> fa-heart" data-js="favorite" data-favorite="<?php echo $user_ID; ?>" data-user="<?php echo get_current_user_id(); ?>"></a>
<span class="label" data-js="favorite_label">
<?php echo get_favorites_num( $user_ID ); ?>
</span>
<span class="value">favoritos</span>
</div>
JS
function setFavorite(userid, favoriteid) {
var favorite_field = $('[data-js="favorite"]');
var favorite_label = $('[data-js="favorite_label"]');
$.ajax({
url : appmeninas_ajax_params.ajaxurl,
data : {
'action' : 'setfavorite',
'userid' : userid,
'favoriteid' : favoriteid,
},
dataType : 'json',
type : 'POST',
cache : false,
beforeSend : function( xhr ) {
favorite_field.removeClass('far fa fa-heart').addClass('fas fa-circle-notch fa-spin');
},
success : function( data ) {
var icon = (data.is_favorite) ? 'fa fa-heart' : 'far fa-heart';
favorite_field.removeClass('fas fa-circle-notch fa-spin');
favorite_field.addClass(icon);
favorite_label.html('');
favorite_label.append(data.favorites_num);
}
});
};
$('[data-js=favorite]').click(function() {
var favoriteid = $(this).data('favorite');
var userid = $(this).data('user');
setFavorite(userid, favoriteid);
});
PHP
function setfavorite() {
$userid = $_POST['userid'];
$favoriteid = $_POST['favoriteid'];
// user require favorite
$favorites_list = get_field( 'favorites_list', 'user_' .$userid );
$favorites_num = get_field( 'favorites', 'user_' .$favoriteid );
if ( !$favorites_list ) {
$favorites_list = [];
}
// profile favorite
if ( in_array( $favoriteid, $favorites_list ) ) {
$favorites_num--;
$tmp = array_search( $userid, $favorites_list );
array_splice( $favorites_list, $tmp, 1 );
$is_favorite = false;
} else {
$favorites_num++;
$favorites_list[] = $favoriteid;
$is_favorite = true;
}
// set favorite counter
update_user_meta( $favoriteid, 'favorites', $favorites_num );
// set favorite list
update_user_meta( $userid, 'favorites_list', $favorites_list );
echo json_encode( array(
'favorites_num' => $favorites_num,
'favorites_list' => $favorites_list,
'is_favorite' => $is_favorite,
) );
die();
}
function is_favorite($userid, $favoriteid) {
$favorites_list = get_field( 'favorites_list', 'user_' .$userid );
return in_array( $favoriteid, $favorites_list );
}
function get_favorites_num( $userid ) {
if ( get_field( 'favorites', 'user_' .$userid ) ) {
return get_field( 'favorites', 'user_' .$userid );
} else {
return '0';
}
}
add_action('wp_ajax_setfavorite', 'setfavorite');
add_action('wp_ajax_nopriv_setfavorite', 'setfavorite');
i maybe will implement a same function in the next 2 months. i allready started researching plugins but as your question states, it does not seems to be very hard.
I try to come back then but first i need a frontend profile page where i can list the favorites.
The first impression looks good so far but first i would give attention to the $_POST array and sanitize and maybe validate the values because sometimes not only your ajax will call.
if ( isset($_POST['userid']) && isset($_POST['favoriteid']) ) { // Both $_POST values exist
$userid = filter_var($_POST['userid'], FILTER_SANITIZE_NUMBER_INT);
$favoriteid = filter_var($_POST['favoriteid'], FILTER_SANITIZE_NUMBER_INT);
if ( filter_var($userid, FILTER_VALIDATE_INT) && filter_var($favoriteid, FILTER_VALIDATE_INT) ) {
// $_POST was save, both values are Integers
}
}
The second one is related to get_field which is a function provided by the ACF Plugin. therefor when deactivating it or it gets replaced with JCF, it may cause errors.
You can avoid this by using if ( function_exists('get_field') ) {. Then your code only stops working when ACF gets deactivated.
Otherwise it seems not neccessary to use the ACF function and you can use the WP native function get_user_meta instead:
function is_favorite($userid, $favoriteid){
$favorites_list = get_user_meta($userid, 'favorites_list', true);
// check the new output instead of get_field
return in_array( $favoriteid, $favorites_list );
}
and also all calls to get_field('favorites', 'user_' .$favoriteid) seem to be wrong then. The ACF Docs say the the second parameter of get_field ist a post ID so i don't know what 'user_' means then. I would call:
function get_favorites_num($favoriteid){
return get_user_meta($favoriteid, 'favorites', true) || 0;
}
i now have my own favorite system ready where users can favorite posts from a specific post_type
HTML
<?php while ( have_posts() ) : the_post() ?>
<?php
$customPostsMeta = get_post_custom();
$favorite_class = 'favorite-me disabled';
$fav_count = isset($customPostsMeta['_favorites']) ? intval($customPostsMeta['_favorites'][0]) : 0;
$fav_count_text = $fav_count > 0 ? '(' . $fav_count . ')' : '';
$fav_count = ' <span class="fav-count clearfix">' . $fav_count_text . '</span>';
$favorite_title = '';
if ( is_user_logged_in() ) {
$user = wp_get_current_user();
$favorites = get_user_meta($user->ID, '_favorite_posts', true);
$fav_key = array_search($post_id, $favorites);
$is_favorite = ( $fav_key !== false );
if ( $is_favorite ) {
$favorite_class .= ' is-favorite';
$favorite_title = ' title="' . get_the_title() . ' ' . __('favorisieren', 'myTheme') . '"';
} else {
$favorite_title = ' title="' . get_the_title() . ' ' . __('nicht mehr favorisieren', 'myTheme') . '"';
}
}
?>
<a class="<?php echo $favorite_class; ?>" href="#post-<?php the_ID() ?>"<?php echo $favorite_title; ?>><?php echo __('Favorit', 'myTheme')?><?php echo $fav_count; ?></a>
<?php endwhile; ?>
JS
// i use a small self written JS module frame where this is included as module
// favorite.setup() is fired imediatly, favorite.ready() fires on document ready
// you can see a full version here: https://dev.alphabetisierung.at/wp-content/themes/sandbox_2017/js/actions.js
// line 732
/**
* Favorites ajax system
* =====================
* https://stackoverflow.com/questions/60468237
*/
favorite: {
options: {
selectors: {
link: '.favorite-me',
fav_count: '.fav-count'
},
classNames: {
disabled: 'disabled',
is_favorite: 'is-favorite',
}
},
events: function(){
var options = this.options,
selectors = options.selectors,
classNames = options.classNames,
info = this.info;
this.$favorites.on('click', function(event){
var post_id = this.hash.replace('#post-', ''),
$favorite_link = $(this).addClass(classNames.disabled),
$fav_count = $favorite_link.children(selectors.fav_count),
$favorite = $.ajax({
url: myTheme.page.urls.ajax,
type: 'post',
data: {
action: info.name, // derived from the module name "favorite"
verify: myTheme.page.verify, // https://developer.wordpress.org/reference/functions/check_ajax_referer/
post_id: post_id
// user_id of user who takes the action is not necessary
}
});
$favorite.done(function(data){
var fav_count = data.hasOwnProperty('fav_count') ? parseInt(data.fav_count) : 0,
fav_count_text = '',
is_favorite = data.hasOwnProperty('is_favorite') ? data.is_favorite : false;
if ( fav_count > 0 ) {
fav_count_text = '(' + fav_count + ')';
}
$fav_count.html(fav_count_text);
if ( is_favorite && !$favorite_link.is('.' + classNames.is_favorite) ) {
$favorite_link.addClass(classNames.is_favorite);
} else {
$favorite_link.removeClass(classNames.is_favorite);
}
$favorite_link.removeClass(classNames.disabled);
});
event.preventDefault();
});
},
ready: function ready(){
var selectors = this.options.selectors,
classNames = this.options.classNames;
this.$favorites = $(selectors.link).removeClass(classNames.disabled);
this.events();
},
setup: function setup(){
var setup = myTheme.info.is_user_logged_in && myTheme.info.post_type === 'my_custom_post_type';
return setup; // only for my post_type
}
PHP
add_action('wp_enqueue_scripts', 'myTheme_enqueue_scripts');
add_action('wp_ajax_favorite', 'myTheme_set_favorite');
// wp_ajax_nopriv_{action} is not necessary when feature is only for logged in users
function myTheme_enqueue_scripts(){
$data = array(
'id' => get_the_ID(),
'urls' => array(
'ajax' => admin_url('admin-ajax.php'),
'template' => get_stylesheet_directory_uri(),
),
'verify' => wp_create_nonce('myThemeOrAction_ajax_call'), // used for check_ajax_referer()
// ...
'info' => array(
// ...
'is_user_logged_in' => is_user_logged_in(),
'post_type' => get_post_type(),
),
);
// ...
wp_localize_script('actions', 'myTheme_data', $data );
}
function myTheme_set_favorite(){
check_ajax_referer('myThemeOrAction_ajax_call', 'verify');
if ( isset($_POST['post_id']) ) {
$user = wp_get_current_user(); // here we get the user ID of the current user
$post_id = filter_var($_POST['post_id'], FILTER_SANITIZE_NUMBER_INT);
$post = get_post($post_id);
// $fav_id = filter_var($_POST['fav_id'], FILTER_SANITIZE_NUMBER_INT);
// $fav_user = get_userdata($fav_id); // WP_User
$is_favorite = false;
if ( $post instanceof WP_Post ) { // post ID is valid
// for user favorites it would be
// if ( $fav_user instanceof WP_User ) {
$fav_count = intval(get_post_meta($post->ID, '_favorites', true));
$favorites = get_user_meta($user->ID, '_favorite_posts', true);
if ( !filter_var($fav_count, FILTER_VALIDATE_INT) ) {
$fav_count = 0;
}
if ( !is_array($favorites) || empty($favorites) ) {
$favorites = array();
}
$fav_key = array_search($post->ID, $favorites);
if ( $fav_key !== false ) { // is favorite, remove it
$fav_count--;
unset($favorites[$fav_key]);
} else { // is no favorite, add it
$fav_count++;
$favorites[] = $post->ID;
$is_favorite = true;
}
// set favorite counter
update_post_meta($post->ID, '_favorites', $fav_count);
// set favorite list
update_user_meta($user->ID, '_favorite_posts', $favorites);
// Output
$json = array(
'fav_count' => $fav_count,
'favorites' => $favorites,
'error' => false,
'is_favorite' => $is_favorite,
);
} else {
$json = array('is_favorite' => $is_favorite, 'error' => true, 'message' => 'Invalid Post ID');
}
} else {
$json = array('is_favorite' => $is_favorite, 'error' => true, 'message' => 'No post_id Post ID sent');
}
// wp_send_json sets the http header and ends the request
wp_send_json($json);
}
this are the things i noticed on the way:
verify referer with wp_create_nonce() and check_ajax_referer()
check JSON result data keys for existance with data.hasOwnProperty('key') to avoid possible JS errors
check valid WP_User or WP_Post object
current users ID with is not necessary to send with POST
wp_ajax_nopriv_{action} is not necessary when feature is only for logged in users
use wp_send_json() for ending the response
kind regards
tom
Related
Have been trying to solve this for a couple days and decided to just break down and ask for some insight. I'm basing what I have off of these two solutions:
Change items tax rate in WooCommerce checkout based on radio buttons
Add a dynamic fee based on a select field in WooCommerce Checkout
I'm trying to use a drop down/select to change the tax class on the checkout page of WooCommerce.
I've left a lot alone from the two above examples but am still not getting the results expected. I also need to store & place the delivery location in the admin area & emails but need to get this tax class change issue sorted first.
Below is what I have right now. It seems like it should be working but alas, no joy.
// Add a custom select fields for packing option fee
add_action( 'woocommerce_after_order_notes', 'checkout_shipping_form_packing_addition', 20 );
function checkout_shipping_form_packing_addition( ) {
$domain = 'woocommerce';
echo '<tr class="packing-select"><th>' . __('Pickup Location', $domain) . '</th><td>';
$chosen = WC()->session->get('chosen_packing');
// Add a custom checkbox field
woocommerce_form_field( 'chosen_packing', array(
'type' => 'select',
'class' => array( 'form-row-wide packing' ),
'options' => array(
'' => __("Please select a location...", $domain),
'BELGIUM - LOC' => sprintf( __("BELGIUM - LOC", $domain) ),
'BROOTEN - LOC' => sprintf( __("BROOTEN - LOC", $domain) ),
'OWATONNA - LOC' => sprintf( __("OWATONNA - LOC", $domain) ),
),
'required' => true,
), $chosen );
echo '</td></tr>';
}
// jQuery - Ajax script
add_action( 'wp_footer', 'checkout_shipping_packing_script' );
function checkout_shipping_packing_script() {
// Only checkout page
if ( is_checkout() && ! is_wc_endpoint_url() ) :
WC()->session->__unset('chosen_packing');
?>
<script type="text/javascript">
jQuery( function($){
$('form.checkout').on('change', 'select#chosen_packing', function(){
var p = $(this).val();
console.log(p);
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'woo_get_ajax_data',
'packing': p,
},
success: function (result) {
$('body').trigger('update_checkout');
console.log('response: '+result); // just for testing | TO BE REMOVED
},
error: function(error){
console.log(error); // just for testing | TO BE REMOVED
}
});
});
});
</script>
<?php
endif;
}
// Php Ajax (Receiving request and saving to WC session)
add_action( 'wp_ajax_woo_get_ajax_data', 'woo_get_ajax_data' );
add_action( 'wp_ajax_nopriv_woo_get_ajax_data', 'woo_get_ajax_data' );
function woo_get_ajax_data() {
if ( isset($_POST['packing']) ){
$packing = sanitize_key( $_POST['packing'] );
WC()->session->set('chosen_packing', $packing );
echo json_encode( $packing );
}
die(); // Alway at the end (to avoid server error 500)
}
// Add a custom dynamic packaging fee
add_action( 'woocommerce_before_calculate_totals', 'change_tax_class_conditionally', 1000 );
function change_tax_class_conditionally( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
$domain = "woocommerce";
$packing_fee = WC()->session->get( 'chosen_packing' ); // Dynamic packing fee
if ( $packing_fee === 'BELGIUM - LOC' ) {
//$label = __("Bag packing fee", $domain);
$tax_class = '5 Percent';
}
if ( $packing_fee === 'BROOTEN - LOC' ) {
//$label = __("Bag packing fee", $domain);
$tax_class = '0 Percent';
}
if ( $packing_fee === 'CHER-MAKE - LOC' ) {
//$label = __("Bag packing fee", $domain);
$tax_class = 'Reduced Rates';
}
// Loop through cart items
foreach( $cart->get_cart() as $cart_item ){
if( $choice === $field_value ) {
$cart_item['data']->set_tax_class($tax_class);
}
}
}
// Field validation, as this packing field is required
add_action('woocommerce_checkout_process', 'packing_field_checkout_process');
function packing_field_checkout_process() {
// Check if set, if its not set add an error.
if ( isset($_POST['chosen_packing']) && empty($_POST['chosen_packing']) )
wc_add_notice( __( "Please choose a packing option...", "woocommerce" ), 'error' );
}
I have a custom taxonomy in WordPress called Case studies.
Home.php is a page. Within home.php I have ran a loop to get all the case studies:
<?php
// only display 5 posts at first, then load 5 more on button click
$args = array('post_type' => 'case-studies', 'posts_per_page' => 5 );
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) {
echo "<div id='customers' class='case-studies-container'>"; // If there are results, create a single div in which all case studies will sit.
// run a loop to get data from all the posts that exist
while ($the_query->have_posts() ) {
$the_query->the_post();
tp_get_part( 'templates/snippets/case-study-card',
array(
'heading' => get_the_title(),
'subheading' => get_field( 'case_study_subheading'),
)
);
}
echo "<div><input type='button' id='loadmore' value='Load more'/></div>
</div>" // case-studies-container closed;
wp_reset_postdata();
} else {
// no posts found
}
?>
On #loadmore button click, I want it to load 5 more posts from the DB and display them. To accomodate this, I have the following JS within *home.php*
<script type="text/javascript">
$(document).ready(function(){
$('#loadmore').click(function(){
// alert('Hello world');
// load more case studies here
jQuery(function($){
var column_width = $(this).data('column-width');
var max_num_pages = $(this).data('max-num-pages');
var ignore = $(this).data('featured');
var post_type = $(this).data('type');
var button = $(this),
data = {
action:'loadmore',
query: loadmore_params.posts, // that's how we get params from wp_localize_script() function
page : loadmore_params.current_page,
security : loadmore_params.security,
columns : column_width,
exclude : ignore,
max_num_pages : max_num_pages,
post_type : post_type
};
$.ajax({
url : loadmore_params.ajaxurl, // AJAX handler
data : data,
type : 'POST',
beforeSend : function ( xhr ) {
button.text('Loading...'); // change the button text, you can also add a preloader image
},
success : function( data ){
if( data ) {
button.text( 'Load More' ).prev().before(data); // insert new posts
loadmore_params.current_page++;
$('.case-studies-container').find('.case-card').last().after( data ); // where to insert posts
if ( loadmore_params.current_page == max_num_pages )
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
}
},
error : function(error){ console.log(error) }
});
});
});
});
</script>
And the following AJAX written in ajax-loaders.php:
<?php
function ajax_handler(){
check_ajax_referer('load_more', 'security');
// prepare our arguments for the query
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1; // we need next page to be loaded
$args['post_status'] = 'publish';
$args['post__not_in'] = explode(',',$_POST['exclude']);
$args['max_num_pages'] = $_POST['max_num_pages'];
$cols = $_POST['columns'];
$type = $_POST['post_type'];
query_posts($args );
if( have_posts() ) :
// run the loop
while( have_posts() ): the_post(); ?>
<div class="<?php echo ($cols ? 'col-'.$cols : 'col-3') .' '. ($type === 'case-study' ? 'case-studies' : 'article__item'); ?> grid__item" id="<?php echo get_the_id(); ?>">
<?php
tp_get_part( 'templates/snippets/case-study-card',
array(
'filterable' => true,
'post' => $post,
'type' => get_cpt_term(get_the_id(), 'case-studies')
)
);
?>
</div>
<?php
endwhile;
endif;
die;
}
add_action('wp_ajax_loadmore', 'ajax_handler'); // wp_ajax_{action}
add_action('wp_ajax_nopriv_loadmore', 'ajax_handler'); // wp_ajax_nopriv_{action}
?>
With all these files set up, on button click, nothing happens? If I uncomment out the alert, the alert occurs which means the trigger is occurring, but unsure on where my load more functionality is going wrong?
Not really expecting to get answer but struggling with this 2 days now and have no idea whats going on.
So here what I have done:
Uploading file via AJAX and immediately starting processing it in backend.
$.ajax({
type : "post",
cache: false,
contentType: false,
processData: false,
url : formAction,
data : formData
});
In backend I writing session where storing current progress like 500 of 10000...
Then I calling another AJAX to check status from session, I calling this funcion every 1 second till responsve returns 'done'.
Looks legit to me, but problem is that after backend proccessing done, and first XHR changing status from 'pending' to 200 browsers freeze, looks like something is blocking it, like another request or somehing. chekc screens bellow.
So it's done, check is stopped, status is changed to 200, nothing happening but browsers freeze, tried Chrome, Firefox...Browser suggesting me to kill process, but if I wait some time it will refresh.
UPDATE
So i lie a little bit, I tried again do same but without ajax and saw similar issue, after backend processing complete, browser waiting response (spinning backwards)...So that is what cousin hanging.
Here is my backend it's Laravel
foreach ($chunks as $rows)
{
$current_chunk++;
if ( $current_chunk < $all_chunks ) {
Session::put(['import_progress'=>'Importing ' . $current_chunk * 150 . ' of ' . $all_results]);
Session::save();
} elseif ( $current_chunk >= $all_chunks ) {
Session::put(['import_progress'=>'done']);
}
foreach ($rows as $row)
{
// transakcija start
DB::transaction(function() use ($row) {
$code = $row[0];
$gender = $row[1];
$brand_name = filter_var($row[2],FILTER_SANITIZE_STRING);
$category = $row[3];
$subcategory = $row[4];
$condition = $row[5];
$details = $row[6];
$composition = $row[7];
$materials = $row[8];
$colors = $row[9];
$patterns = $row[10];
$country = $row[11];
$size = $row[12];
$m_a = $row[13];
$m_b = $row[14];
$m_c = $row[15];
$m_d = $row[16];
$m_e = $row[17];
$m_f = $row[18];
$m_g = $row[19];
$product = new Product();
$product->code = $code;
$product->gender = $gender;
$product->size = $country . ' | ' . $size;
$product->condition = $condition;
$product->measurement_a = $m_a;
$product->measurement_b = $m_b;
$product->measurement_c = $m_c;
$product->measurement_d = $m_d;
$product->measurement_e = $m_e;
$product->measurement_f = $m_f;
$product->measurement_g = $m_g;
$product->save();
if ( empty($code) ) {
$bad_prods[] = $product->id;
}
if ( !empty( $brand_name ) ) {
$brand = Brand::firstOrCreate(['brand_name'=>$brand_name]);
$product_b = new ProductBrand();
$product_b->brand_id = $brand->id;
$product_b->product_id = $product->id;
$product_b->save();
}
if ( !empty( $materials ) ) {
$materials_exp = explode(',',$materials);
foreach ($materials_exp as $material) {
$material = Material::firstOrCreate(['material_name'=>trim($material)]);
$product_m = new ProductMaterial();
$product_m->material_id = $material->id;
$product_m->product_id = $product->id;
$product_m->save();
}
}
if ( !empty( $patterns ) ) {
$patterns_exp = explode('/',$patterns);
foreach ($patterns_exp as $pattern) {
$pattern = Pattern::firstOrCreate(['pattern_name'=>trim($pattern)]);
$product_p = new ProductPattern();
$product_p->pattern_id = $pattern->id;
$product_p->product_id = $product->id;
$product_p->save();
}
}
if ( !empty( $colors ) ) {
$colors_exp = explode('/',$colors);
foreach ($colors_exp as $color) {
$color = Color::firstOrCreate(['color_name'=>trim($color)]);
$product_c = new ProductColor();
$product_c->color_id = $color->id;
$product_c->product_id = $product->id;
$product_c->save();
}
}
$product_t = new ProductTranslation();
$product_t->product_id = $product->id;
$product_t->product_title = $brand_name;
$product_t->product_description = '<p>'.$details.'</p><p>'.$composition.'</p>';
$product_t->save();
}); // end transakcija
}
}
Session::put(['import_progress'=>'done']);
Session::put(['bad_prods'=>$bad_prods]);
return redirect()->route('admin.import');
And here I'm checking status
public function status()
{
return response()->json([
'status' => Session::get('import_progress'),
'bad_prods' => Session::get('bad_prods')
]);
}
When processing is done I put simple exit(); at the end of processing Controller...Not sure why this works and any other return statement doesn't.
I have an error "Cannot set property 'onchange' of null" when I try to run this code. Why it shows null if it is not blank?
This code is not mine, I found it in google, but It seems to be working for others.
function woo_product_categories_dropdown( $atts ) {
extract(shortcode_atts(array(
'count' => '0',
'hierarchical' => '0',
'orderby' => ''
), $atts));
ob_start();
$c = $count;
$h = $hierarchical;
$o = ( isset( $orderby ) && $orderby != '' ) ? $orderby : 'order';
?>
<script type='text/javascript'>
/* <![CDATA[ */
var product_cat_dropdown = document.getElementById("dropdown_product_cat");
function onProductCatChange() {
var urlmenu = document.getElementById( 'menu1' );
if (urlmenu) {
urlmenu.onchange = function()
{
window.open(this.options[ this.selectedIndex ].value,'_self');
};
}
if ( product_cat_dropdown.options[product_cat_dropdown.selectedIndex].value !=='' ) {
location.href = "<?php echo home_url(); ?>/?product_cat="+product_cat_dropdown.options[product_cat_dropdown.selectedIndex].value;
}
}
product_cat_dropdown.onchange = onProductCatChange;
/* ]]> */
</script>
<?php
return ob_get_clean();
}
Do you have an element in your html with an id of "menu1"?
If not, you have a few choices:
You would have to create the element with the correct id.
Rename the id of an existing element.
Change the id the script is looking for in the following line:
var urlmenu = document.getElementById( 'newid' );
If you are dealing with a situation where the aforementioned ID may or may not show up in the page, handle the undefined case like such:
on the line which has:
if (urlmenu)
change to:
if (typeof(urlmenu) != "undefined" && urlmenu)
P.S. This question is long as there's lot of code. Thank you for your patience and time. I appreciate it.
I am using ultimate wp query search filter plugin on my wordpress site. I would like to use chosen plugin instead of default select boxes. The select boxes already on the page are working perfectly with this code.
(function($){
$(".first-ddwn, .second-ddwn, .third-ddwn, .main-ddwn, .posts_ajax select").chosen({
no_results_text: "Oops, nothing found!",
width: "50%"
});
})(jQuery);
I have changed the result html for AJAX search as mentioned by the plugin author so that I get a dropdown of result posts.
add_filter('uwpqsf_result_tempt', 'customize_output', '', 4);
function customize_output($results , $arg, $id, $getdata ){
// The Query
global $post;
$apiclass = new uwpqsfprocess();
$query = new WP_Query( $arg );
ob_start(); $result = '';?>
<form action="<? bloginfo('url'); ?>" method="get"><?php
echo '<select name="page_id" id="page_id">';
echo '<option value="">Select</option>';
// The Loop
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post(); ?>
<option value="<? echo $post->ID; ?>"><?php echo the_title(); ?></option>
<?php }
echo '</select>';
echo '<input type="submit" name="submit" value="view" />';
echo '</form>';
} else {
echo 'no post found';
}
/* Restore original Post Data */
wp_reset_postdata();
$results = ob_get_clean();
return $results;
}
However, chosen doesn't get applied to this result dropdown. I have tried the option of using settimeout after the AJAX call as mentioned http://davidwalsh.name/jquery-chosen#comment-29299 but it didn't work. maybe I did it wrong. Also when I run it after ajax call like below, chosen does get applied to the select but is all broken.
jQuery.ajax({
type: 'POST',
url: ajax.url,
timeout:3000,
data: ({action : 'uwpqsf_ajax',getdata:getdata, pagenum:pagenum }),
beforeSend:function() {$(''+ajxdiv+'').empty();res.container.append(res.loader);},
success: function(html) {
res.container.find(res.loader).remove();
$(''+ajxdiv+'').html(html);
$(".content select").chosen();
}
});
This is what I get
This is plugin's uwpqsfscript.js file
jQuery(document).ready(function($) {
$('body').on('click','.usearchbtn', function(e) {
process_data($(this));
return false;
});
$('body').on('click','.upagievent', function(e) {
var pagenumber = $(this).attr('id');
var formid = $('#curuform').val();
upagi_ajax(pagenumber, formid);
return false;
});
$('body').on('keypress','.uwpqsftext',function(e) {
if(e.keyCode == 13){
e.preventDefault();
process_data($(this));
}
});
window.process_data = function ($obj) {
var ajxdiv = $obj.closest("form").find("#uajaxdiv").val();
var res = {loader:$('<div />',{'class':'umloading'}),container : $(''+ajxdiv+'')};
var getdata = $obj.closest("form").serialize();
var pagenum = '1';
jQuery.ajax({
type: 'POST',
url: ajax.url,
timeout:3000,
data: ({action : 'uwpqsf_ajax',getdata:getdata, pagenum:pagenum }),
beforeSend:function() {$(''+ajxdiv+'').empty();res.container.append(res.loader);},
success: function(html) {
res.container.find(res.loader).remove();
$(''+ajxdiv+'').html(html);
}
});
}
window.upagi_ajax = function (pagenum, formid) {
var ajxdiv = $(''+formid+'').find("#uajaxdiv").val();
var res = {loader:$('<div />',{'class':'umloading'}),container : $(''+ajxdiv+'')};
var getdata = $(''+formid+'').serialize();
jQuery.ajax({
type: 'POST',
url: ajax.url,
data: ({action : 'uwpqsf_ajax',getdata:getdata, pagenum:pagenum }),
beforeSend:function() {$(''+ajxdiv+'').empty(); res.container.append(res.loader);},
success: function(html) {
res.container.find(res.loader).remove();
$(''+ajxdiv+'').html(html);
//res.container.find(res.loader).remove();
}
});
}
$('body').on('click', '.chktaxoall,.chkcmfall',function () {
$(this).closest('.togglecheck').find('input:checkbox').prop('checked', this.checked);
});
});//end of script
And some relevant code (maybe?) from uwpqsf-process-class.php
//front ajax
add_action( 'wp_ajax_nopriv_uwpqsf_ajax', array($this, 'uwpqsf_ajax') );
add_action( 'wp_ajax_uwpqsf_ajax', array($this, 'uwpqsf_ajax') );
add_action( 'pre_get_posts', array($this ,'uwpqsf_search_query'),1000);
}
function uwpqsf_ajax(){
$postdata =parse_str($_POST['getdata'], $getdata);
$taxo = (isset($getdata['taxo']) && !empty($getdata['taxo'])) ? $getdata['taxo'] : null;
$cmf = (isset($getdata['cmf']) && !empty($getdata['cmf'])) ? $getdata['cmf'] : null;
$formid = $getdata['uformid'];
$nonce = $getdata['unonce'];
$pagenumber = isset($_POST['pagenum']) ? $_POST['pagenum'] : null;
if(isset($formid) && wp_verify_nonce($nonce, 'uwpsfsearch')){
$id = absint($formid);
$options = get_post_meta($id, 'uwpqsf-option', true);
$cpts = get_post_meta($id, 'uwpqsf-cpt', true);
$pagenumber = isset($_POST['pagenum']) ? $_POST['pagenum'] : null;
$default_number = get_option('posts_per_page');
$cpt = !empty($cpts) ? $cpts : 'any';
$ordermeta = !empty($options[0]['smetekey']) ? $options[0]['smetekey'] : null;
$ordertype = (!empty($options[0]['otype']) ) ? $options[0]['otype'] : null;
$order = !empty($options[0]['sorder']) ? $options[0]['sorder'] : null;
$number = !empty($options[0]['resultc']) ? $options[0]['resultc'] : $default_number;
$keyword = !empty($getdata['skeyword']) ? sanitize_text_field($getdata['skeyword']) : null;
$get_tax = $this->get_uwqsf_taxo($id, $taxo);
$get_meta = $this->get_uwqsf_cmf($id, $cmf);
if($options[0]['snf'] != '1' && !empty($keyword)){
$get_tax = $get_meta = null;
}
$ordermeta = apply_filters('uwpqsf_ometa_query',$ordermeta,$getdata,$id);
$ordervalue = apply_filters('uwpqsf_ometa_type',$ordertype,$getdata,$id);
$order = apply_filters('uwpqsf_order_query',$order,$getdata,$id);
$number = apply_filters('uwpqsf_pnum_query',$number,$getdata,$id);
$args = array(
'post_type' => $cpt,
'post_status' => 'publish',
'meta_key'=> $ordermeta,
'orderby' => $ordertype,
'order' => $order,
'paged'=> $pagenumber,
'posts_per_page' => $number,
'meta_query' => $get_meta,
'tax_query' => $get_tax,
's' => esc_html($keyword),
);
$arg = apply_filters( 'uwpqsf_query_args', $args, $id,$getdata);
$results = $this->uajax_result($arg, $id,$pagenumber,$getdata);
$result = apply_filters( 'uwpqsf_result_tempt',$results , $arg, $id, $getdata );
echo $result;
}else{ echo 'There is error here';}
die;
}//end ajax
function uajax_result($arg, $id,$pagenumber,$getdata){
$query = new WP_Query( $arg );
$html = '';
//print_r($query); // The Loop
if ( $query->have_posts() ) {
$html .= '<h1>'.__('Search Results :', 'UWPQSF' ).'</h1>';
while ( $query->have_posts() ) {
$query->the_post();global $post;
$html .= '<article><header class="entry-header">'.get_the_post_thumbnail().'';
$html .= '<h1 class="entry-title">'.get_the_title().'</h1>';
$html .= '</header>';
$html .= '<div class="entry-summary">'.get_the_excerpt().'</div></article>';
}
$html .= $this->ajax_pagination($pagenumber,$query->max_num_pages, 4, $id,$getdata);
} else {
$html .= __( 'Nothing Found', 'UWPQSF' );
}
/* Restore original Post Data */
wp_reset_postdata();
return $html;
}//end result
I have been searching for days and have tried many things to make this work. I have no knowledge of jquery,so maybe someone will help me out.
Many Thanks