4

I'm using Smart Map to find locations ordered by distance. But I can only set 3 parameters: target, range and units. However, when my range goes beyond the country borders I obviously get results in other countries. I want to list all locations within a country by distance, but limited to that country.

Is it possible to do this? I tried related items, but can't seem to get it to work. And I don't see any option in Smart Map either.

2 Answers 2

4

At the moment, there's no in-plugin way to handle this. However, you can probably do it out-of-plugin, once you've retrieved a larger set of results.

So first, you'd get the largest possible results set:

{% set params = {
    target: targetLocation,
    range:  10000,
    units:  'kilometers'
} %}

{% set entries = craft.entries.myFieldHandle(params).order('distance').find() %}

Then, you'd cycle through those results to filter only the entries from your desired country:

{% set desiredCountry = 'France' %}
{% set filteredByCountry = [] %}

{% for entry in entries %}
    {% if entry.myFieldHandle.country == desiredCountry %}
        {% set filteredByCountry = filteredByCountry|merge([entry]) %}
    {% endif %}
{% endfor %}

Once you've done that, you'll have a filteredByCountry array of entries, which should be exactly the results set you were looking for.

1
  • I did it the exact same way before I read your post :) Thanks anyway for the quick response! Love the power of Twig! Commented Aug 12, 2015 at 11:35
5

What I've done to do something very similar is to add a template variable to my BusinessLogic plugin, that takes the ElementCriteriaModel, prepared with all other parameters e.g. section, limit and SmartMap set. The plugin then translates the model into a Yii CDbCommand using buildElementsQuery, adds the additional conditions to the query and returns the further filtered entry models to the template.

Here's my service function with modifications for your country filtering needs. It#s untested but should probably work as is:

public function addCountryCriteria(ElementCriteriaModel $criteria, $country)
{
    $query = craft()->elements->buildElementsQuery($criteria);

    // Add where condition for country filter
    $params = array(':country' => $country);
    $conditions = array('smartmap_addresses.country = :country');

    $query->andWhere($conditions, $params);

    // Join addresses table to bring in the state
    $query->leftJoin('smartmap_addresses smartmap_addresses', 'smartmap_addresses.elementId = entries.id');

    // Get query results and populate entry models
    $results = $query->queryAll();

    return EntryModel::populateModels($results);
}

Also have a look at my other answers on how to add conditions to CDbCommand from the template:

8
  • Great answer! For folks comfortable with plugin dev, this would be a slick way to pull it off in the initial query. My answer caters more towards folks who'd rather just filter it in Twig. :)
    – Lindsey D
    Commented Aug 6, 2015 at 16:53
  • Yes exactly my thoughts, now there's two good answers! :)
    – carlcs
    Commented Aug 6, 2015 at 16:56
  • I can only select one correct answer to this. I haven't tried your way, but it looks very good! Thanks! Commented Aug 12, 2015 at 11:36
  • @TomDeSmet try it, it shouldn't take longer than 5mins. to set this up. Do you need pagination – works with this approach. ;)
    – carlcs
    Commented Aug 12, 2015 at 11:43
  • Colleague of mine is allready putting the site live and I'm allready working on another project :) Deadlines, deadlines! ;) Commented Aug 12, 2015 at 11:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.