Advice on Gmap showing other table results

lcollong

FabriKant d'applications web
Hi,

I'd like to show on a map a filtered number of markers. These markers are the result of some complex filtering made by the user on a list view. The map uses a different list on the same underlying SQL Table. The idea is to have a link on the list view "see you selection on the map" which will display another page with the corresponding markers.

I'm aware of (and use) the possibility to combine both map and list on the same page and share the same filtering result using content plugin inside an article or displaying map on top or bottom of a list view.

But the underlying list are not the same and I need that map and list are on separate pages.

Is there a way to "catch" the filter thing ($this->filter) from the list view and apply it to the underlying list used by the Gmap as the columns are the same ?

Using sessions vars ? using templates to to set and assign things ? using the php_events plugin to set filters (onFiltersGot ?)

Any trick to make me on the road is welcome...

Thanks,

Laurent
 
Hello

I think about a PHP form plugin, or a list plugin, which would take user filters to construct a customized URL to your map.

But indeed, easier said than done...
 
As you are probably aware, we go to great lengths to prevent exactly what you want to do, of applying filters from one "context" of a list to another. This is what allows you to have different copies of a list, and not have the filters from one affect the other.

The short answer is "probably", as you surmised, by using the php_events plugin and the onFiltersGot. Any filters posted on the original list should be in the session data for that list. So you should be able to retrieve them and apply them to the copy displaying the map. However, as that plugin is only called after the filters have been built, you'd have to basically replicate what getSessionFilters() does (in models/listfilter.php). Which is a pain.

I think a better approach might be if I add another hook, in storeRequestData(), in the main list model:

https://github.com/Fabrik/fabrik/blob/master/components/com_fabrik/models/list.php#L5145

... which would allow you to duplicate what the foreach loop does at line 5168, and do a setUserState() for each of the filters, but using the 'key' for your target list.

I'm happy to add the call in storeRequestData, and add the hook in php_events, but that's about as far as I can go. If you run into issues getting that to work, and need further assistance, I'd have to look at this as custom work, and charge an hourly rate.

-- hugh
 
OK, I added that hook:

https://github.com/Fabrik/fabrik/commit/8bd05d4cfc8272f50ff780db315048cf91308e88

In your PHP events code, the request filters will be in $args[0]['request']. The "listref" is in $args[0]['context'], and will look like com_fabrik.list2_com_fabrik_2.filter. You'll need to provide one that matches the context of your target list, which I think (even in a map viz) will be the same, just with a different list ID (so like 5 instead of 2, or whatever).

The request data will be an array of 19 arrays, things like 'value', 'key', 'condition', etc. On the whole, you'll just do what the main storeRequestData does, and write each one out with it's array name appended to the main context as the key (so you'll be writing things like com_fabrik.list5_com_fabrik_5.filter.value, etc).

One issue you will have is with the 'elementid' array. You'll need to map those to the corresponding numeric element ID in the target list. Technically you could probably load up the form model for your target, and get them programmatically get the ids by loading the element models by name (derived from the 'key' filter array), but I'd suggest just mapping them by hand for now, during "proof of concept" stage (mostly because I'm too lazy to figure that code out right now).

So, something like ...

PHP:
$elementIdMap = array(
   '123' => '456',
   '124' => '457'
);

$request = $args[0]['request'];
$context = 'com_fabrik.list5_com_fabrik_5.filter';

foreach ($request as $key => $val)
{
    if (is_array($val))
   {
      if ($key === 'elementid')
      {
         foreach ($val as &$v)
         {
            $v = FArrayHelper::getValue($elementIdMap, $v, '');     
         }
      }
      $key = $context . '.' . $key;
      $this->app->setUserState($key, array_values($val));
   }
}

Obviously modify the element map ('source element id' => 'target element id') and the context name.

You could probably improve that mapping of the element id's, so you remove any not mapped from the elementid array, rather than just leaving them blank.

-- hugh
 
Hi,

I was "on the road" these days. Reason for my silence.
@georgie : thanks for your answer.

Hugh, I greatly appreciate you added the hook to make this possible and take time to explain. I'll do some tests these next days and see if I need more help to achieve it. I'll keep you informed.

Laurent
 
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top