.. _mapfish_core: Tutorial MapFish Client - Core ============================== This tutorial provides a tour of MapFish Client Core classes. It requires JavaScript programming knowledge. You may need some more documentation. In this case, please refer to the following API documentations: `MapFish API doc `_ `Ext API doc `_ Get Prepared ------------ To start with, let's create a new file called `mapfish2.html`. .. code-block:: html MapFish Lab
**Important note**: In order to get the following working you'll first need a web server. You'll also need a valid proxy. Please follow the explanation given in `How to set a ProxyHost `_. Don't forget to add `demo.mapfish.org` in the list of allowed domains in `proxy.cgi`. Protocols --------- There's in fact a single MapFish protocol, but it can be wrapped into several decorators, such as the TriggerEventDecorator or the MergeFilterDecorator. This is the reason why you can see several files in the protocol directory. The MapFish protocol itself is described in detail on this `wiki page `_. This is a RESTful protocol: it makes use of HTTP verbs to create, read, update, delete features. On the client side, it is implemented by the mapfish.Protocol.MapFish class, which extends OpenLayers.Protocol.HTTP. On the one hand, the TriggerEventDecorator decorates a protocol (it might be the MapFish protocol, but not exclusively), so that events are fired on successful "crudtriggered", "crudfinished", "committriggered", "commitfinished", "clear". This can be exploited in many manners, for instance to trigger a popup on successful getting features. On the other hand, the MergeFilterDecorator wraps a protocol by merging filters provided by searchers before invoking the decorated protocol's read method. We'll make usage of those protocols in the following steps. Searchers --------- There are two searcher Classes: Map, and Form: * A Map searcher sends search requests as the user clicks, pauses or draws boxes on the map. * A Form searcher gets search criteria from an HTML form and passes them to the protocol's read method. Both of them inherit (at least) from the base class mapfish.Searcher. Searcher Map ^^^^^^^^^^^^ Map searcher also inherits from OpenLayers.Control, so that it can be activated/deactivated. The great benefit is that it can be very easily added to an OpenLayers.Panel, or mapfish.widgets.toolbar.Toolbar. Here's the typical usage of a map searcher in HOVER mode .. code-block:: javascript var protocol = new mapfish.Protocol.MapFish({ url: "http://demo.mapfish.org/mapfishsample/1.1/summits", params: { limit: 10 } }); var triggerEventProtocol = new mapfish.Protocol.TriggerEventDecorator({ protocol: protocol }); var mapSearcher = new mapfish.Searcher.Map({ mode: mapfish.Searcher.Map.HOVER, protocol: triggerEvent, displayDefaultPopup: true, delay: 400 }); map.addControl(mapSearcher); mapSearcher.activate(); In this code, note that the MapFish protocol has to be wrapped into a TriggerEventDecorator, so that a popup can be displayed on successful getting features (it registers a listener on the crudfinished event). There are other types of searching mode : CLICK, BOX and EXTENT. You can play with them using the above code. Searcher Form ^^^^^^^^^^^^^ Now we probably want to filter the results by specifying some specific values for attributive data. To do so, we'll merge the filter parameters with some values set in a form. First of all, it's required to decorate the protocol with a *MergeFilterDecorator*. Replace the previous *triggerEventProtocol* instanciation by the following .. code-block:: javascript var mergeFilterProtocol = new mapfish.Protocol.MergeFilterDecorator({ protocol: protocol }); var triggerEventProtocol = new mapfish.Protocol.TriggerEventDecorator({ protocol: mergeFilterProtocol }); Note: Order is important here ! Updating your html page in your browser, you shouldn't see any difference, the popup should open the same way. If this is OK, lets move on. What we want now is add for example a input field in which user can set a minimum value for elevation. Add the following to your section .. code-block:: html
And the following within the onReady callback .. code-block:: javascript var formSearcher = new mapfish.Searcher.Form({ form: Ext.get('myForm').dom, protocol: mergeFilterProtocol }); mergeFilterProtocol.register(formSearcher); If your firebug console is open, and you're logging the XMLHttpRequests, you'll see that an additionnal *min* parameter is added to the request sent to the server. Unfortunately, your server code doesn't take this parameter into account. You can change the *summits* controller so that it does. Search Results in Grid ^^^^^^^^^^^^^^^^^^^^^^ OK, that's fine. Your search results are displayed in the map. How about listing them in an Ext grid as well ? This can be achieved by connecting the layer and a grid's store together using the *LayerStoreMediator*. This widget actually listens to the layer's events and manages the grid's store records consequently. What you first need is creating an Ext store using a dedicated reader .. code-block:: javascript var store = new Ext.data.Store({ reader: new mapfish.widgets.data.FeatureReader( {}, [{name: "name", type: "string"}] ) }); This specific **mapfish.widgets.data.FeatureReader** is able to create records by reading data from OpenLayers vector features. Then you can plug an Ext grid to this store .. code-block:: javascript var grid = new Ext.grid.GridPanel({ store: store, renderTo: Ext.getBody(), cm: new Ext.grid.ColumnModel([{header: "name"}]), height: 200 }); Need a way to select features on the map and get the corresponding row hilighted in the grid and vice-versa? The **GridRowFeatureMediator** widget is exactly what you are looking for .. code-block:: javascript var select = new OpenLayers.Control.SelectFeature(layer); var mediator = new mapfish.widgets.data.GridRowFeatureMediator({ grid: grid, selectControl: select });