Skip Navigation

[Resolved] Distance filter

This support ticket is created 3 years, 2 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 -
- 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 -

Supporter timezone: Asia/Karachi (GMT+05:00)

This topic contains 44 replies, has 2 voices.

Last updated by ilonaB-2 3 years, 1 month ago.

Assisted by: Waqar.

Author
Posts
#2187679
Searchbar - distance search.jpg

Hi Jamal, thanks so much for your help.

Just to be sure we (mainly me 🙂 ) are talking about the same things, I wrote everyting in a Word doc. see attached image.

I hope its clear what my whishes are.
Also i hope you have time to respond since you don't work on Wednesdays and Thursdays. If not perhaps some one else can help us out on the matter untill your back.

Regards,

#2187835

Right now, we can't really check for the filters(specialisatie, projekt, talen), because they are all empty. Some posts needs to have values for them in order to generate some options in the filter and to check.

Regarding the distance based on the user location or the entered location, you will need to use a condition on the entered center. If a center is entered use the shortcode that will calculate the distance from the center. If no center is provided, use the shortcode for the distance from the user's location.

Currently, we have dropped the conditional button(IF) from the Fields&Text block. So, you will have to use one of the approaches:
- Use a conditional block(to check if a center has been provided) to display one of two Fields&Text block. One would calculate the distance from the center, the other should calculate it from the user's location.
- Use the legacy editor, which has an IF button to generate the conditional shortcodes, and the shortcode for distance location on them.

I hope this makes sense to you. Let me know if you get stuck at any point.

#2187965

Hi Jamal,

Since the snippet of code you send us earlier had been added the filters have been empty.
For that reason i deleted that code -> so now the filters are filled again.

Again since i seriously have no knowhow about coding, I have no clew on how to achieve the approaches you mention.

So could you please help me out giving me a step bij step explanation on how to do eacht of the needed steps to make this work.

Thanks in advance.

#2188617
Distance search filter - image 3.jpg
Distance search filter - image 2.jpg
Distance search filter - image 1.jpg

Hi Jamal,

First of all thanks a lot for the time you're putting in supporting us!

I think i've been a bit messy about explaining what our whishes are, so we made some sheets trying to visualize what it exactly is we are trying to achieve. I hope this helps.

Also to make it easier lets just skip the distance filter based on user location (we'll mention in our FAQ that for the distance filter to work users always need to fill in a location)

So we just want to filter the distance based on what location the user enters in the "Enter a Location" field.

I hope you can give us a step by step tutorial what code (if needed) we need to use and where to and how to build everything, since our experience is very limited.

Thanks again for your support.

#2190691

My apologies for the late reply and for not getting a teammate to continue with you during my weekend. Some teammates are on vacation.

Thank you for your feedback. Now, I am aware that the custom code that I shared with you is not optimized for this use case. This custom code skips the query to the database when no search is entered. And the dropdowns need this search. That's why they were empty, and I am sorry I did not realize that.

The use case still needs custom code that does not skip the database query. So, Instead of the previous code, we need to use a different filter. I come up with the following code, that uses the wpv_filter_query_post_process filter :

add_filter( 'wpv_filter_query_post_process', 'empty_results_if_no_filters', 10, 3 );
function empty_results_if_no_filters( $query, $view_settings, $view_id ) {
    $ids = array( 3323 );
    if ( in_array( $view_id, $ids ) ){
      // Check if there is a distance filter, both the center and the radius
      $radius = isset( $_GET['toolset_maps_distance_radius'] );
      $center = isset( $_GET['toolset_maps_distance_center'] ) && strlen( $_GET['toolset_maps_distance_center'] ) > 0;
      $distance = $radius && $center;
      
      // Check if Specialistie is provided
      $specialisatie = ( isset( $_GET['wpv-specialisatie'] ) && $_GET['wpv-specialisatie'] != '0' ) ? true : false;
      
      // check if Project is provided
      $project = ( isset( $_GET['wpv-project'] ) && $_GET['wpv-project'] != '0' ) ? true : false;
      
      // check if Spreektaal is provided
      $spreektaal = ( isset( $_GET['wpv-spreektaal'] ) && $_GET['wpv-spreektaal'] != '0' ) ? true : false;
      
      if ( ! ( $distance || $specialisatie || $project || $spreektaal ) ) {
        $query->posts = array();
        $query->found_posts = 0;
        $query->post_count = 0;
      }
    }
    return $query;
}

Read more about it here https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query_post_process

Now, let's get to display the distance. You want to display the distance from the provided center, or from the user's location, right? As I suggest we'll use the wpv-search-term shortcode to check if the center is provided. We need to use it inside a conditional, so, we'll have to register it in Toolset->Settings->Front-end Content->Third-party shortcode arguments. Check this screenshot hidden link

As I explained, we can either use the conditional block, or conditional shortcodes. The Fields&Text block has dropped the IF button to generate conditional shortcodes. So, I am going to build a content template(unassigned content template) with the legacy editor, for this matter(displaying the distance from the center).
I recorded a video for it. Unfortunately, the User Interface did not work as expected. And I'll need to debug it in order to tell why?
Check the video, I hope it will give you an idea on how to use the legacy editor, the conditional shortcode, and the Fields&Views button in general(which helps generating shortcodes)
hidden link

I built the shortcodes manually, then I included the content template inside the view as you may see here hidden link
But they did not work as I would expect. Would you allow me to take a copy of your website and debug this locally?

Please let me know you answer about the copy, and any questions you might have.

#2190809

Hi Jamal,

Thanks for getting back to us.
Yes of course you can make a copy and debug locally.

Also, would it be possible for you to build the entire thing for us? (since it costs us to much time to learn everything). If nessesary we're willing to pay for it.

If that's possible let us know asap.

Regards

#2190937
distance-from-provided-center-and-user-location.png

I am sorry, but I can't build the entire thing for you, nor get paid from you. I can only help you with our products until you get things done. Please check our support policy https://toolset.com/toolset-support-policy/

You may want to hire one of our partners here https://toolset.com/contractors/

Getting back to our distance calculation, I was able to make things work. Check the results of both cases on this screenshot hidden link

Because the conditional shortcodes are not offered anymore on the "Fields&Text" block, I worked on a content template with the legacy editor. My previous video demonstrates how I did it. This is the shortcodes that I come up with:

[wpv-conditional if="( '[wpv-search-term param="toolset_maps_distance_center"]' ne '' )"]
  Distance from the provided center ([wpv-search-term param="toolset_maps_distance_center"]): [toolset-maps-distance-value origin_source="url_param" url_param='toolset_maps_distance_center' target_source='postmeta' postmeta='wpcf-straat-en-huisnummer' decimals="1" unit="km"] km. 
[/wpv-conditional]
[wpv-conditional if="( '[wpv-search-term param="toolset_maps_distance_center"]' eq '' )"]
  Distance from the user's location: [wpv-geolocation][toolset-maps-distance-value origin_source='visitor_location' target_source='postmeta' postmeta='wpcf-straat-en-huisnummer' decimals="1" unit="km"] km. [/wpv-geolocation]
[/wpv-conditional]

Check the content template here hidden link

Then, I included the content template inside a Fields&Text block with the following shortcode, check it on the view/page hidden link

[wpv-post-body view_template="distance-from-center-or-user-location" suppress_filters="true"]

For more reading about Toolset shortcodes, check these two articles:
- https://toolset.com/documentation/programmer-reference/views/views-shortcodes/
- https://toolset.com/documentation/programmer-reference/maps/maps-shortcodes/

I'll remain at your disposal for any further questions.

#2191435
custom code - jamal.png

Hey Jamal,

Thank you so much for the code! I think we're almost at the point we want to be.

We tweaked the code a bit:
We noticed that due to privacy setting on laptops the users location won't always show. For that reason we deleted the 2nd part of the shortcode.
Also in the first part we deleted some text that was displayed in the results, so no we only show the actual distance like: "2,91 km".

We just have 2 questions remaining:
- The ordering (in the searchresults based on distance in km) isn't working yet: so the results are random at the moment. How can we have them ascending from shortest distance to longest? (can you provide that code?)

- When the user doens't use any filters (in the searchbar) and just presses the "search" button, no results are shown. If possible we'd like to show all resuts when this happens... (since we adjusted the shortcode the distance won't be shown on this occasion, but that's ok).

Im not exactly sure since my limited knowledge about code but i think this might have to do with the snippet of code in the "Custom code" section. I added an image -> something to do with empty fields??.

Hope to hear back soon.

#2191459

Well, for the second question(when the user hits search without any filters), we'll need to update the custom code to handle it. I can work on it later.

For the first question, I am afraid, this can't be done with the views that are built using the blocks editor. There is no custom code to overcome it. It is only possible through the legacy editor. And in there, you can choose to order by distance from the ordering section.

So, I guess, if you want distance ordering, you will have to build the view in the legacy editor. In that case, there will be no need for me to check the custom code, regarding the first question, until you build the view. Maybe this video can help you with creating the view in the legacy editor hidden link

I'll remain at your disposal.

#2191477

Hi Jamal,

Thanks for getting back to us so quick.

Does this mean that we need to build a new "zoekresultaten" page and create a new view instead of the current "zoekresultaten" page & the current view?

And if so; are you suggesting we do that with HTML & CSS code (in the Lagacy editor), right?

We just tried doing that using the video you provided.

The problems we are facing, are:
- The video is incompleet and doesn't show us exactly what to do to achieve our specific goal.
- We have no previous experience with HTML and/or CSS, so we have no clue where to start let alone how to work on it/get it done.

Is there any way you can provide us with the code for the legacy editor based on the current "zoekresultaten" page?

We're very happy with Toolset since we can build almost everything visually with the block editor, however building with the Legacy editor is way to complex for us.

#2191497

Well, no need to create a new page. But you will have to create a new view. With the blocks editor, we can only create views within the editor(in a page, a content template, or similar). But, with the legacy editor, we can only create views from Toolset->Views->Add New. Then, you can use the view inside the same page "zoekresultaten" after removing the old view.

Check the following Youtube videos, they have been produced before Toolset releases the Blocks editing experience:
- hidden link
- hidden link
- This one is a bit older, the user interface has been modified, by the workflow and the editors sections remain the same hidden link

And yes, as you have noticed, you will need to use HTML, CSS, and more importantly Toolset shortcodes to build with the legacy editor. Keep in mind, that you only need to create the view with the legacy editor. Inside a view's loop you can put a content template. That content template can be created with the blocks editor, so you don't need to use HTML/CSS inside of it. Does it make sense?

I can understand the frustration you may have with the legacy editor. But, I'd like to assure that it is not a big deal, you will quickly get used to it. And as I said, you can build the template inside the view(that will be put inside the view) using the blocks editor.
When you get to the View loop section, use the wizard to help you choose the grid, and to create the template of the view for you. Then, Toolset will offer a button to edit the template of the view in the blocks editor.

Keep in mind that:
- A view is meant to query the database for a list of posts and display them.
- A content template is meant to display one post.
- You can use content templates inside views' loops.
- You can also use views inside content templates.

This way, you can mix both editing experiences(Legacy and blocks).

I'll remain at your disposal.

#2192923

Hey Jamal, thanks for your reply.
So far I’ve managed to do the following:
Add a new view (zoekresultaten + afstand)
I’ve chosen the option: “Full custom display mode”
- at the “Content Selection” I choose: “Specialisten”
- at the “Ordering” I chose:
order by: “straat en huisnummer” | “Ascending” | “as a distance from” | “visitor location”
In the loop wizard:
- I chose </> Unformatted
Next in the “Choose fields” I added the following fields:
- Bedrijfsfoto
- Post tittle with a link
- Specialisaties
- Projecten
- Post excerpt
- Distance from center or user location (not sure if this is correct)
Also I checked the box for: “Use a Content Template to group the fields in this loop”
In the loop editor I added the following code:
[wpv-geolocation][toolset-maps-distance-value origin_source='visitor_location' postmeta='wpcf-straat-en-huisnummer' decimals='2'][/wpv-geolocation] km.

Next I added a new page (zoekresultaten + afstand), same name as the view, to check how everything works:
On the page “zoekresultaten + afstand” I did the following:
- Inserted a container
- Next I inserted a “Fields and Text” block.
- After that I used the “Add Field or View” option
o And inserted the View: “zoekresultaten + afstand” .
In the Search and Pagination section I added a simple searchbar (btw have no idea how to rebuilt this one based on the first one, but that’s something to worry about later on).
You can check everything on the following url:
mijnwingman.nl/zoekresultaten-afstand/

Please let me know if it’s possible for you to get the Distance ordering, based on short -> longest distance, working now.

Regards,

#2193005

Well, the view is correctly set up. And the ordering is also correctly set up(distance from the user location). And, you have already built the content template of the view's loop with the blocks editor. Congratulations!!!
However, It does not seem that the results are ordered based on distance. They seem to be ordered alphabetically based on the address.

I activated the views debug mode to check the underlying SQL query, and it is ordered based on the address instead of the distance.
https://toolset.com/documentation/programmer-reference/debugging-sites-built-with-toolset/#the-views-debug-tool

The underlying SQL query is:

SELECT   sxbh_posts.* FROM sxbh_posts  LEFT JOIN sxbh_term_relationships ON (sxbh_posts.ID = sxbh_term_relationships.object_id) INNER JOIN sxbh_postmeta ON ( sxbh_posts.ID = sxbh_postmeta.post_id )
INNER JOIN sxbh_postmeta AS tmapsmeta ON ( sxbh_posts.ID = tmapsmeta.post_id )
LEFT JOIN sxbh_toolset_maps_address_cache ON sxbh_toolset_maps_address_cache.address_passed = tmapsmeta.meta_value
 WHERE 1=1  AND ( 
  sxbh_term_relationships.term_taxonomy_id IN (200)
) AND ( 
  sxbh_postmeta.meta_key = 'wpcf-straat-en-huisnummer'
) AND sxbh_posts.post_type = 'specialist' AND ((sxbh_posts.post_status = 'publish' OR sxbh_posts.post_status = 'private')) GROUP BY sxbh_posts.ID ORDER BY sxbh_postmeta.meta_value ASC 

At first, I thought that the MySQL server is less than 5.6(which includes geolocation features), but the current version is higher(5.7).

Please note that:
- The ordering by distance is done by MySQL.
- The distance calculated by the shortcode is done by Toolset/PHP.
That's why the distance is calculated during our tests.

This being said, I would like to take a copy of your website and debug it locally. This will help us exclude the server configuration and focus on the real cause of the issue.
Would you allow me to take the copy?

#2193069

Hi Jamal,

Sounds good so far! 🙂
Of course you can make a copy to debug locally.

Thanks a lot!

#2193701

Thank you! I took a copy and worked on it on our online platform and I was able to find the issue.

Actually, the view did not have any information about the user's location. So, I added the following shortcodes inside of the view's loop editor, which triggers a popup to ask the user for permissions on his location. If the user allows the site to get the location from the browser, the view will be reloaded and it will be sorted based on the distance from the user's location.
This is the shortcode that I added to enforce asking for location permissions:

[wpv-geolocation][/wpv-geolocation]

And then the view is sorted correctly, from the database level. Notice the ORDER clause in this underlying SQL query:

SELECT   sxbh_posts.* FROM sxbh_posts  INNER JOIN sxbh_postmeta ON ( sxbh_posts.ID = sxbh_postmeta.post_id )
INNER JOIN sxbh_postmeta AS tmapsmeta ON ( sxbh_posts.ID = tmapsmeta.post_id )
LEFT JOIN sxbh_toolset_maps_address_cache ON sxbh_toolset_maps_address_cache.address_passed = tmapsmeta.meta_value
 WHERE 1=1  AND ( 
  sxbh_postmeta.meta_key = 'wpcf-straat-en-huisnummer'
) AND sxbh_posts.post_type = 'specialist' AND ((sxbh_posts.post_status = 'publish' OR sxbh_posts.post_status = 'private')) GROUP BY sxbh_posts.ID ORDER BY ST_Distance_Sphere(ST_PointFromText('POINT(-8.0283754 31.6373823)'), sxbh_toolset_maps_address_cache.point) ASC 

Now, I am confident to say that the view is correctly sorted by distance from the user's location.

I'll remain at your disposal for any additional questions.