This topic has 11 replies, 3 voices, and was last updated 5 months, 3 weeks ago ago by Luca Rossi
Hello,
Is there a way to implement a size/dimension filter, based on this data:
https://prnt.sc/GBaDxURHM4dR
I know we can create product attributes, but it’s double the work, and double the data. We have boxes and cake boards and a lot of other products that come in different sizes (not like L, M or S, but in CM’s). Maybe there is a snippet or something I can use to make it work, or a setting inside a filter widget?
Thanks in advance,
Nancy
Hello, Nancy,
Thank you for reaching out to us with your query.
Please be advised that the feature you are inquiring about is not available by default within our theme. The fields you have mentioned are part of the WooCommerce functionality. Therefore, we kindly suggest that you reach out to the WooCommerce plugin support team for further assistance – https://wordpress.org/support/plugin/woocommerce/
Best regards,
The 8Theme Team
Hello Rose Tyler!
So there is not an xstore widget that can filter by dimension or another custom field (I believe _width can also be approached as a custom meta field)? As I said, a snippet for functions.php is also not a problem.
Kind regards,
Nancy
Dear Nancy,
We hope this message finds you well.
It requires the customization to achieve. Please be advised that the customization you are inquiring about falls beyond the scope of the support we are able to provide. However, we would like to direct your attention to a plugin that may offer a solution to your needs. You can find more information about it at the following links:
– https://wordpress.org/support/topic/filtering-woos-dimension-field/
– https://woobewoo.com/documentation/filter-by-length-width-height-and-weight/
– https://toolset.com/course-lesson/creating-a-custom-search/
We trust that this resource will be of assistance to you.
Warm regards,
The 8Theme Team
I was having the trouble with the plugins suggested that it redirected to the front page somehow everytime I tried to filter it. Annasta Woocommerce Product Filters works though! Maybe you can keep this in mind if someone wants the same thing 😉
Also, if you have any idea why only your plugin and annasta works correctly on my site, let me know.
Dear Nancy,
We hope this message finds you well.
We would like to inform you that the size/dimension you have inquired about is not included as a standard option within our XStore theme. The specific fields you referenced are associated with the WooCommerce plugin’s capabilities. As such, we respectfully recommend that you contact the WooCommerce plugin support team for more detailed assistance. They can be reached at the following link: https://wordpress.org/support/plugin/woocommerce/ or annasta Woocommerce Product Filters plugin: https://annasta.net/plugins/annasta-woocommerce-product-filters/support/.
Should you have any other questions or require additional information regarding our theme, please do not hesitate to reach out.
Warm regards,
The 8Theme Team
Well for now this is my third version. It works with the other filters, but only if the other filters are chosen first, and the dimension is chosen last. If you guys have any ideas on how to fix it so the order doesn’t matter, let me know
class Custom_Dimensions_Filter_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'custom_dimensions_filter',
esc_html__('Custom Dimensions Filter', 'text_domain'),
array('description' => esc_html__('A widget to filter products by custom dimensions', 'text_domain'))
);
}
public function widget($args, $instance) {
$title = apply_filters('widget_title', $instance['title']);
if (is_shop() || is_product_category()) {
$current_category = get_queried_object();
// Check if there are products with dimensions in the current category
if ($this->category_has_dimensions($current_category->term_id)) {
echo $args['before_widget'];
if (!empty($title)) {
echo $args['before_title'] . $title . $args['after_title'];
}
// Capture existing filter parameters
$existing_filters = $_GET;
// Generate filter links with existing parameters
$current_url = $this->get_current_page_url();
$width_options = $this->get_dimension_options('width', $current_category->term_id);
$length_options = $this->get_dimension_options('length', $current_category->term_id);
?>
<form id="custom-filters" method="get">
<?php
foreach ($existing_filters as $key => $value) {
if (strpos($key, 'filter_') === 0) {
echo "<input type='hidden' name='$key' value='" . esc_attr($value) . "' />";
}
}
?>
<select name="filter_width" id="filter_width">
<option value=""><?php _e('Select width in cm', 'text_domain'); ?></option>
<?php echo $width_options; ?>
</select>
<select name="filter_length" id="filter_length">
<option value=""><?php _e('Select length in cm', 'text_domain'); ?></option>
<?php echo $length_options; ?>
</select>
</form>
<script>
jQuery(function($) {
$('#filter_width, #filter_length').change(function() {
$('#custom-filters').submit();
});
});
</script>
<?php
echo $args['after_widget'];
}
}
}
public function form($instance) {
$title = !empty($instance['title']) ? $instance['title'] : esc_html__('Filter by Dimensions', 'text_domain');
?>
<p>
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php esc_attr_e('Title:', 'text_domain'); ?></label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>"
name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text"
value="<?php echo esc_attr($title); ?>">
</p>
<?php
}
private function get_current_page_url() {
global $wp;
return home_url(add_query_arg(array(), $wp->request));
}
private function get_dimension_options($dimension, $category_id) {
$ranges = array('1-10', '11-20', '21-30', '31-40', '41-50'); // Adjusted ranges as per your requirement
$options = '';
foreach ($ranges as $range) {
$selected_count = $this->count_products_with_filters($dimension, $range, $category_id);
if ($selected_count > 0) {
$selected = isset($_GET["filter_$dimension"]) && $_GET["filter_$dimension"] == $range ? 'selected' : '';
$options .= '<option value="' . esc_attr($range) . '" ' . $selected . '>' . esc_html($range) . ' (' . $selected_count . ')</option>';
}
}
return $options;
}
private function count_products_with_filters($dimension, $range, $category_id) {
global $wpdb;
$meta_key = '_' . $dimension;
$meta_value = explode('-', $range);
// Prepare meta query
$meta_query = array(
'relation' => 'AND',
array(
'key' => $meta_key,
'value' => floatval($meta_value[0]),
'compare' => '>=',
'type' => 'DECIMAL(10,2)',
),
array(
'key' => $meta_key,
'value' => floatval($meta_value[1]),
'compare' => '<=',
'type' => 'DECIMAL(10,2)',
)
);
// Add taxonomy query
$tax_query = array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $category_id
)
);
// Add color filter if selected
if (isset($_GET['filter_kleur']) && !empty($_GET['filter_kleur'])) {
$tax_query[] = array(
'taxonomy' => 'pa_kleur', // Replace with your taxonomy name
'field' => 'slug',
'terms' => sanitize_text_field($_GET['filter_kleur']),
'operator' => 'IN'
);
}
// Count matching products
$query = new WP_Query(array(
'post_type' => 'product',
'posts_per_page' => -1, // Count all posts
'meta_query' => $meta_query,
'tax_query' => $tax_query,
));
return $query->found_posts;
}
private function category_has_dimensions($category_id) {
global $wpdb;
$meta_query = array('relation' => 'OR');
$meta_keys = array('_width', '_length');
foreach ($meta_keys as $meta_key) {
$meta_query[] = array(
'key' => $meta_key,
'value' => 0,
'compare' => '>',
'type' => 'NUMERIC'
);
}
$query = new WP_Query(array(
'post_type' => 'product',
'posts_per_page' => 1,
'meta_query' => $meta_query,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $category_id
)
)
));
return $query->have_posts();
}
}
// Register the widget
function register_custom_dimensions_filter_widget() {
register_widget('Custom_Dimensions_Filter_Widget');
}
add_action('widgets_init', 'register_custom_dimensions_filter_widget');
// Add custom filter query logic
function custom_filter_query($query) {
if (!is_admin() && $query->is_main_query() && (is_shop() || is_product_category())) {
$meta_query = array('relation' => 'AND');
$filtering = false;
// Handle width filter
if (isset($_GET['filter_width']) && !empty($_GET['filter_width'])) {
$width_range = explode('-', sanitize_text_field($_GET['filter_width']));
if (count($width_range) == 2) {
$meta_query[] = array(
'key' => '_width',
'value' => array(floatval($width_range[0]), floatval($width_range[1])),
'compare' => 'BETWEEN',
'type' => 'DECIMAL(10,2)',
);
$filtering = true;
}
}
// Handle length filter
if (isset($_GET['filter_length']) && !empty($_GET['filter_length'])) {
$length_range = explode('-', sanitize_text_field($_GET['filter_length']));
if (count($length_range) == 2) {
$meta_query[] = array(
'key' => '_length',
'value' => array(floatval($length_range[0]), floatval($length_range[1])),
'compare' => 'BETWEEN',
'type' => 'DECIMAL(10,2)',
);
$filtering = true;
}
}
// Add more custom filters here as needed
// Only set the meta query if a filter is being applied
if ($filtering) {
$query->set('meta_query', $meta_query);
}
}
}
add_action('pre_get_posts', 'custom_filter_query');
Dear Nancy,
We regret to inform you that the issues arising from the custom codes fall outside the standard scope of our support services.
Should you require personalized customization services, we kindly invite you to submit a request via our customization panel at: [https://www.8theme.com/account/#etheme_customization_panel](https://www.8theme.com/account/#etheme_customization_panel). This will enable you to engage directly with our team of technicians.
Please note that customization services will incur additional charges. The exact amount will be determined after a detailed review of your request.
Thank you for your understanding.
Best Regards,
The 8Theme Team
Ofcourse I understand. Maybe you just knew the trick to make it work 😉
Hi @Nancy,
The provided codes you sent are too complicated and it could take a lot times to research/debug.
Thank you for your understanding.
Best Regards,
The 8Theme Team
The issue related to '‘Filter by dimension? (Width, length, height filter)’' has been successfully resolved, and the topic is now closed for further responses