Home › Toolset Professional Support › [Resolved] Searching a Map View that Uses Shortcode Attribute…
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 – 12:00 | 9:00 – 12:00 | 9:00 – 12:00 | 9:00 – 12:00 | 9:00 – 12:00 | - |
- | 13:00 – 18:00 | 13:00 – 18:00 | 13:00 – 18:00 | 14:00 – 18:00 | 13:00 – 18:00 | - |
Supporter timezone: America/Jamaica (GMT-05:00)
Tagged: Toolset Maps, Views plugin
Related documentation:
This topic contains 24 replies, has 3 voices.
Last updated by shawnW-3 3 years, 4 months ago.
Assisted by: Shane.
Tell us what you are trying to do?
I have a Map View that uses URL Parameters.
I want this map view to use a shortcode for the initial query, but I still want users to be able to search different addresses using filter controls after that first query. I thought it would be very straightforward, but it's not working as expected.
What's really strange is that if I click "Use My Location" and it puts in Geolocation, it will change the order - so something is happening. Next I tried setting DevTools Location Sensor to use the geolocation of a distant location, but all the results were within the original 'zone' set by the shortcode. This makes me think that URL parameter is working, but that it's restricted by the original mapcenter shortcode.
Setup...
On the Ordering I left it set to a distance from URL parameter.
On the Query Filter I changed...
"Distance center is set using URL parameter: toolset_maps_distance_center"
...to...
"Distance center is set using shortcode attribute: mapcenter"
(NOTE: the map shortcode "mapcenter" has a variable derived from PHP, which does work properly on load).
Custom Search Settings:
AJAX results update when visitors change any filter values (tried full page refresh and that didn't work).
In my filter controls I have:
[wpv-filter-controls] <div class="ddealerlocatorsearch uk-padding-remove-top uk-margin-remove-top uk-margin-medium-bottom"> [wpv-control-distance default_unit="mi" default_distance="60" compare_field="dealer-address" distance_center_url_param="toolset_maps_distance_center" distance_radius_url_param="toolset_maps_distance_radius" distance_unit_url_param="toolset_maps_distance_unit"] [wpv-filter-submit class="uk-button uk-button-primary uk-button-small uk-width-1-1 uk-width-1-6@m iploadsubclk"] [wpv-filter-spinner position="after" spinner="/wp-content/plugins/wp-views/embedded/res/img/ajax-loader.svg"] [/wpv-filter-spinner] </div> [/wpv-filter-controls]
When I try to change the location, ajax fires, and the URL parameter is updated, but the map doesn't change.
Is there any documentation that you are following?
Not able to find documentation or posts about this. Perhaps I'm not searching the right terms.
What is the link to your site?
Unless you're still whitelisted from a previous ticket, I'll need your IP to whitelist...
hidden link - click buy local
Another thing to note is that this is actually a plan B for us, since we had so many issues getting ajax to work with a do_shortcode in the same map view. Christian Cox helped with that, but ultimately the approach was abandoned.
Hello and thank you for contacting the Toolset support.
On the Query Filter I changed...
"Distance center is set using URL parameter: toolset_maps_distance_center"
...to...
"Distance center is set using shortcode attribute: mapcenter"
(NOTE: the map shortcode "mapcenter" has a variable derived from PHP, which does work properly on load).
I am afraid, the search using URL parameter won't work as long as the query filter is not set to it. It will always filter based on the shortcode argument. Maybe this can be worked around it with custom code, but I'll need to see the view's shortcode and how the argument is passed to it.
If you need to search the view based on the URL parameter, the query filter MUST be set on the URL parameters.
It would not be useful to whitelist my IP address as it will change, maybe before you whitelist it. So, I'll check with our systems team to see if they can provide a static IP using a VPN solution, and I'll communicate it to you. However, this will need to wait for Monday.
In the meantime, can you share the view's shortcode where you use the shortcode argument "mapcenter" or the PHP code where you use wpv_do_shortcode?
Sorry for the confusion, when I mentioned the do_shortcode, I was just referencing a past attempt to say it's not an option / doesn't work. You can see the recent ticket on that in my support profile.
Another thing I probably didn't communicate well is that when I do a manual search, ajax does fires and the map and results DO update, but they're confined to the region set by the mapcenter parameter. So if your address is in Los Angeles, the initial search loads in LA, then when you do a manual search for Chicago, the order of the results will change order (because they're ordered by distance and the top result becomes the one closest to Chicago) and the map will refresh, but they are ultimately the same results.
So the view is responding to the input, but within the confines of the original mapcenter location since that's the setting. Not sure if that's actually helpful info, but I didn't want any confusion about what's working and what isn't.
[wpv-view name="Buy Local Dealer Locator View for Blocked" mapcenter="[users_zip]"]
add_shortcode('users_zip', 'users_zip_func'); function users_zip_func() { $usrip = $_SERVER['REMOTE_ADDR']; $usripinfo = json_decode(file_get_contents("<em><u>hidden link</u></em>{$usrip}?key=apikeyvalue")); $usrcountrycode = $usripinfo->countryCode; $usrcity = $usripinfo->city; $usrregionname = $usripinfo->regionName; $usrzip = $usripinfo->zip; if (empty($usrzip) || $usrcountrycode != 'US') { $fullbuylocalmapshrtcd = $usrcity.', '.$usrregionname; } else { $fullbuylocalmapshrtcd = $usrzip; } return $fullbuylocalmapshrtcd; }
Well, because the view accepts a shortcode argument, it will always use it as the mapcenter, even if you enter a new address in the search field.
With the current solution, I would suggest to update the shortcode so, it will threat the case when the address is provided from the search input. Something like:
add_shortcode('users_zip', 'users_zip_func'); function users_zip_func() { // check if the map center is provided through search if ( isset($_GET['mapcenter']) && strlen($_GET['mapcenter']) > 0 ) { return $_GET['mapcenter']; } else { $usrip = $_SERVER['REMOTE_ADDR']; $usripinfo = json_decode(file_get_contents("<em><u>hidden link</u></em>{$usrip}?key=apikeyvalue")); $usrcountrycode = $usripinfo->countryCode; $usrcity = $usripinfo->city; $usrregionname = $usripinfo->regionName; $usrzip = $usripinfo->zip; if (empty($usrzip) || $usrcountrycode != 'US') { $fullbuylocalmapshrtcd = $usrcity.', '.$usrregionname; } else { $fullbuylocalmapshrtcd = $usrzip; } return $fullbuylocalmapshrtcd; } return ''; }
Does it make sense?
Please note that you may need to change:
$_GET['mapcenter']
To:
$_GET['toolset_maps_distance_center']
Depending on what you have named the URL parameter.
I tried this with both uses of GET values, and it made no difference. The results and function was the same as before. Cleared caches between each just to make sure - my URL Param is toolset_maps_distance_center
My thinking on this is because the function above is just a shortcode being entered into a view shortcode attribute, it would have already rendered fully on the initial load and thus wouldn't exist to update or be updated following user action (ie, ajax search).
Let me know if I'm wrong. I'm open to trying just about anything.
It's been a few days since I replied saying this suggestion didn't work.
Are there any other ideas about a workaround?
Another thing to note... I mentioned my URL Parameter was "toolset_maps_distance_center"
I was going off the Search and Pagination section ...
[wpv-control-distance default_unit="mi" default_distance="60" compare_field="dealer-address" distance_center_url_param="toolset_maps_distance_center" distance_radius_url_param="toolset_maps_distance_radius" distance_unit_url_param="toolset_maps_distance_unit"][wpv-filter-submit class="uk-button uk-button-primary uk-button-small uk-width-1-1 uk-width-1-6@m iploadsubclk"][wpv-filter-spinner position="after" spinner="/wp-content/plugins/wp-views/embedded/res/img/ajax-loader.svg"][/wpv-filter-spinner]
However, being that the query is defined as "Show posts within 60mi radius of address/coordinates provided using mapcenter shortcode attribute" means the URL after ajax search ends up looking like this...
?wpv_aux_current_post_id=154633&wpv_aux_parent_post_id=154633&wpv_view_count=77107-CATTR6b8dfeab7fef37ca7a29f438918486f3
So "toolset_maps_distance_center" isn't shown at all in the URL even though it is still the distance_center_url_param.
Again, the order of the results has changed. If I search Dallas Texas, the result that was originally in the "mapcenter" area and was furthest south, is now the top result. So again, the map isn't moving, the results are changing, but they are being reordered by distance from the search function.
And just for the heck of it I tried change toolset_maps_distance_center in to mapcenter in both Search and Pagination as well as Ordering. The results were the same. Changing mapcenter in the Query Filter to toolset_maps_distance_center isn't an option as it contains underscores.
I don't want to be a pain, but can this be reassigned to someone in my timezone?
My apologies for the late reply, but I do not work on Wednesdays and Thursdays. I'll also pass this ticket to Shane or Christian, who are probably close to your timezone. It seems that you did not add your timezone to your profile. Let me know which one, and I'll pass the ticket to the closest teammate to you.
However, I'll try to support you further with this last reply. You, maybe, are right. But, I still think that the map is rendered each time and that the shortcode to pass the mapcenter is executed each time. You can use error_log() calls inside of your custom code to confirm that.
Relying on the mapcenter shortcode argument does not seem to work, at least not yet. So, I'll suggest the following:
1. Dropping the mapcenter shortcode argument, and relying on the URL parameter to make sure that the view filters posts and sort them correctly when an address is entered.
2. Find a way to pass the user address, using your IP geolocation API, in another way.
I can think of using the either the wpv_view_settings hook, or the wpv_filter_query hook to modify the view's settings, or the view's query arguments:
- https://toolset.com/documentation/programmer-reference/views-filters/
You can check for the "toolset_maps_distance_center" URL parameter, if it does not exist, you can perform the IP geolocation code and set the returned address as value for "toolset_maps_distance_center"
While preparing step 1, use calls to error_log to determine where will you add the user's IP-geolocated address:
- On the view's settings using the wpv_view_settings filter.
- Or on the view's wp_query arguments using the wpv_filter_query filter.
If that does not help either, we can provide a test site, reproduce a minimal case to yours, and then we'll give it a try to find a workaround for you. If we could not find it, we'll escalate this request to our 2nd Tier for further assistance.
First off, no worries about the delay...
I don't really know where to add error_log in this and it doesn't seem necessary at this time, since everything is technically functioning properly - just not the way I need it to.
$query_args hasn't been helpful. I can't find anything pertaining to the location. Am I missing something??
$view_settings on the other hand has been somewhat helpful. With add_filter I'm able to change map_center_source between address (as in fixed address), shortcode_attr, and url_param. ... map_distance_center only works when the source is set to 'address', and as we established, the user entered location search doesn't work with anything but url_param.
So my first thought was to use ajax to call a function that would switch shortcode_attr to url_param. The logic there is that the view could use a shortcode attribute when it renders, and IF a user wanted to search further, ajax would trigger a switch - replacing shortcode_attr with url_param before the user could enter their search, thus ensuring their url parameters would work.
I tried doing this by wrapping the add_filter function in an add_action function. The ajax worked in that it correctly called the add action function, but I didn't get any result from it and don't know if the add_filter function did anything. Maybe that's where error_log would have been helpful. But it may be that you can't wrap an add_filter function in add_action function... I've certainly never tried doing that before. Just out of ideas on how to make one work with the other.
Do you have any ideas on how I could get that to work? It seems pretty ideal conceptually, but I'm not sure if it's possible. Code below...
Otherwise I'd have to switch to url_param permanently, then use php to get a users location and set it as a URL Parameter, which would only halfway meet my goals.
add_action('wp_ajax_nopriv_mapcentersourceswitch', 'mapcentersourceswitch'); add_action('wp_ajax_mapcentersourceswitch', 'mapcentersourceswitch'); function mapcentersourceswitch(){ function update_map_center_onload( $view_settings, $view_id ) { if ( $view_id == 77107 ) { $view_settings['map_distance_filter']['map_center_source'] = 'url_param'; } return $view_settings; } add_filter( 'wpv_view_settings', 'update_map_center_onload', 5, 2 ); echo 'success'; wp_die(); }
I played around with the placement of add_action and add_filter, but it didn't seem to have any effect.
jQuery(document).ready(function($) { $(document).one('scroll', function(e) { var ajaxurl = '/wp-admin/admin-ajax.php'; var data = { action: 'mapcentersourceswitch' }; jQuery.post(ajaxurl, data, function(response) { alert(response); }); }); });
I worked a couple of hours on this, trying to use both of the hooks wpv_view_settingsand wpv_filter_query to no avail.
You can check my test site here hidden link
Let me escalate this to our 2nd tier for further assistance. I'll get back to you as soon as we have something to share.
Before I could escalate this to our 2nd Tier, I thought about a workaround and I would like to discuss it with you. Hopefully, it will let you achieve what you need.
The workaround consists of using two views and conditionally display one of them. The existing view uses the shortcode attribute as the center, and the new one will use the URL parameter. Then you can conditionally display one of them depending on the existence of the URL parameter. You can use the wpv-search-term shortcode to check for the existence of the mapcenter parameter in the URL. But you will need to register it in Toolset->Settings->Front-end Content->Third-party shortcode arguments. Check this screenshot hidden link
https://toolset.com/documentation/programmer-reference/views/views-shortcodes/#vf-214940
You will have to include the 2nd view's search form separately than the view:
<!-- Include the 2nd view search form --> [wpv-form-view name="2nd-view" target_id="self"] <!-- Conditionally use one of the view --> [wpv-conditional if="( '[wpv-search-term]' eq '' )"] [wpv-view name="1st-view" mapcenter='[users_zip]'] [/wpv-conditional] [wpv-conditional if="( '[wpv-search-term]' eq '' )"] [wpv-view name="2nd-view" view_display="layout"] [/wpv-conditional]
The first view would not need to have the search form on it as it will use the shortcode attribute to get the mapcenter.
I hope this helps. Let me know if you have any questions.
From what you say I'm a bit confused. The second view won't render until a URL Parameter exists and there wouldn't be a URL parameter until a user searches, but you say the first view wouldn't need a search form so I don't see where the parameter comes from. Am I misunderstanding?
Putting that aside, I actually had considered something similar, but I ruled it out...
The user would arrive and the first view would be rendered with the mapcenter attribute.
They would click a Search button which would reveal the second view - only problem is that second view has already fully rendered and run a default query, so my idea was not too helpful.
I'm still open-minded to having two views. Your idea solves the issue of the view I was thinking of, by not running its query until a condition was met. However, let's say the search form were left in the first view, and it created the URL parameter when a user performed a manual search, and through PHP that URL parameter was converted into a shortcode... it wouldn't matter, because the shortcode conditionals would have already fully rendered on that page. Without using something like wpv_do_shortcode for the conditionals, there'd be no way for ajax to render them after the page had already loaded.
The idea could work, but it would require a hard refresh, thereby returning the condtionals to their shortcode state where a custom shortcode would be possible on a brand new page load. Unfortunately I think a hard refresh is too jarring for the UX and kind of defeats the purpose of having the search in that page.
Let me know if I'm misunderstanding your proposal, because I could very well be.
Also, I do realize I'm trying to thread a needle with all these goals...
- automation: query uses IP address to approximate user location which saves user time, and saves google maps API hits
- speed: only one query unless a user chooses to manually search
- clean UX: no URL parameters until user searches and use ajax on manual user search so user doesn't have to re-orientate
...but I sincerely appreciate the help.
There has got to be a way to make this work.
From what you say I'm a bit confused. The second view won't render until a URL Parameter exists and there wouldn't be a URL parameter until a user searches, but you say the first view wouldn't need a search form so I don't see where the parameter comes from. Am I misunderstanding?
Well, the trick that I thought about is to split the display of the 2nd view's search form and results. However, you are right, that solution is not AJAX wise.
So, it made me think further and I believe to find a better solution. I implemented an example to confirm it and I think it is working as you would expect.
This solution involves two views and a piece of custom code:
- One view that takes the map center as a shortcode attribute. Basically, your existing view, without the search form part.
- Another view that takes the map center as a URL parameter. That has the search form, and that will display the 1st view if no URL parameter is available.
- A piece of custom code that will empty the 2nd view if no URL parameter is available.
For my test, I implemented a shortcode that will act like your existing shortcode. It is not actually performing any IP geolocation. It just returns a hard-coded address near Paris. So, the post "Paris" is the only one that the first view should return.
The 1st view is used within the No results section of the 2nd view, but also inside a conditional shortcode against the URL parameter. To handle the case where the user has entered an address that won't return any results. Like this:
[wpv-no-items-found] [wpv-conditional if="( '[wpv-search-term param='mapcenter']' eq '' )"] [wpv-view name="map-center-in-a-shortcode-attribute" mapcenter="[user_location]"] [/wpv-conditional] [wpv-conditional if="( '[wpv-search-term param='mapcenter']' eq '' )" evaluate="false"] <strong>[wpml-string context="wpv-views"]No items found[/wpml-string]</strong> [/wpv-conditional] [/wpv-no-items-found]
Please check my test site here hidden link
- The first view, with the shortcode attribute, is here hidden link
- The second view, which performs the search, displays the map, and displays the 1st view when relevant, is here hidden link
- The page where we use the 2nd view is here hidden link
Please check it from your side, and let me know if I missed something.