Skip to content

Commit

Permalink
Merge pull request #262 from theduckylittle/search-all-fields
Browse files Browse the repository at this point in the history
Improvements to search
  • Loading branch information
klassenjs committed Oct 25, 2017
2 parents 123546c + 9592e1c commit cd218ee
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 14 deletions.
77 changes: 77 additions & 0 deletions docs/howto/add-search-layer-picker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# How-to let the user choose a search layer

Sometimes data is stored across multiple layers and writing
multiple instances of the Search service is too laborious for
both the administrator and the user. This is an example
configuration that will allow searching two different layers,
with two different field names, from the same text box.

## Code

This example refers to the `firestations-wfs` layer. This is used in other
tutorials and the data is included in the gm3-demo-data repository.

```xml
<map-source name="firestations-wfs" type="mapserver-wfs">
<file>./demo/firestations/firestations.map</file>
<param name="typename" value="ms:fire_stations" />
<layer name="fire_stations" selectable="true" title="Firestations">
<template name="select"><![CDATA[
<div class="result-item">
<div class="result-title">
Firestation
</div>
<b>Station City:</b> {{ properties.Dak_GIS__4 }}<br>
<b>Station Number:</b> {{ properties.Dak_GIS__5 }}<br>
<div>
]]></template>
<template name="search" alias="select" />
</layer>
</map-source>
```

### In app.js

```javascript
app.registerService('super-search', SearchService, {
fields: [
{
type: 'select',
name: 'layer',
options: [
{value: 'vector-parcels/parcels', label: 'Parcel Owners'},
{value: 'firestations-wfs/fire_stations', label: 'Firestations'}
]
}, {
type: 'text',
name: 'search-value',
}
],
prepareFields: function(fields) {
var values = getFieldValues(fields);
var field_name = {
'vector-parcels/parcels' : 'OWNER_NAME',
'firestations-wfs/fire_stations' : 'Dak_GIS__4'
};
return [{
comparitor: 'ilike',
name: field_name[values['layer']],
value: values['search-value']
}];
},
getSearchLayers: function(searchLayers, fields) {
console.log(getFieldValues(fields));
return [getFieldValues(fields)['layer']];
}
});
```

### In the catalog

```xml
<toolbar>
...
<tool name="super-search" title="Super Search" type="service"/>
...
</toolbar>
```
5 changes: 5 additions & 0 deletions examples/desktop/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,8 @@ body {
.feature-class.pipelines {
background-color: #4894ff;
}

.search-address {
font-size: .85em;
padding-left: 1em;
}
10 changes: 9 additions & 1 deletion examples/desktop/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,15 @@ app.loadMapbook({url: 'mapbook.xml'}).then(function() {
});

app.registerService('identify', IdentifyService);
app.registerService('search', SearchService);
app.registerService('search', SearchService, {
fields: [
{type: 'text', label: 'Owner Name', name: 'OWNER_NAME'},
{type: 'text', label: 'Street/Address', name: 'OWN_ADD_L1'},
{type: 'text', label: 'City/State/ZIP', name: 'OWN_ADD_L3'}
],
searchLayers: ['vector-parcels/parcels']
});

app.registerService('search-firestations', SearchService, {
searchLayers: ['firestations/fire_stations'],
fields: [
Expand Down
6 changes: 5 additions & 1 deletion examples/desktop/mapbook.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@
</a>
</div>
</div>
<div class="search-address">
{{ properties.OWN_ADD_L1 }}<br/>
{{ properties.OWN_ADD_L3 }}<br/>
</div>
</div>
]]></template>

Expand Down Expand Up @@ -503,7 +507,7 @@
<tool name="select" title="Select Features" type="service"/>

<drawer name="searches" title="Search">
<tool name="search" title="Search by Owner" type="service"/>
<tool name="search" title="Search Parcels" type="service"/>
<tool name="geocode" title="Search by Address" type="service"/>
</drawer>

Expand Down
37 changes: 25 additions & 12 deletions src/services/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,33 @@ function SearchService(Application, options) {

/** User input fields */
this.fields = options.fields ? options.fields : [
{type: 'text', label: 'Owner Name', name: 'OWNER_NAME'}
];

/** Define the layer(s) to be searched. */
this.searchLayers = options.searchLayers ? options.searchLayers : [
'vector-parcels/parcels'
];
this.searchLayers = options.searchLayers ? options.searchLayers : [];

/** Allow the user to programmatically change which
* layers are searched.
*/
this.getSearchLayers = options.getSearchLayers ? options.getSearchLayers : function(searchLayers, fields) {
return searchLayers;
};

/** Field transfomation function. */
this.prepareFields = options.prepareFields ? options.prepareFields : function(fields) {
// reformat the fields for the query engine,
// "*stuff*" will do a case-ignored "contains" query.
return [
{
comparitor: 'ilike',
name: fields[0].name,
value: '*' + fields[0].value + '*'
var query = [];
for(var i = 0, ii = fields.length; i < ii; i++) {
if(fields[i].value !== '' && fields[i].value !== undefined) {
query.push({
comparitor: 'ilike',
name: fields[i].name,
value: '*' + fields[i].value + '*'
});
}
];
}
return query;
};

/** Define the results layer */
Expand All @@ -88,10 +96,15 @@ function SearchService(Application, options) {
// it would be necessary to put that code here and then manually tell
// the application when the query has finished, at which point resultsAsHtml()
// would be called by the service tab.
Application.dispatchQuery(this.name, selection, this.prepareFields(fields), this.searchLayers, this.template);
Application.dispatchQuery(
this.name,
selection,
this.prepareFields(fields),
this.getSearchLayers(this.searchLayers, fields),
this.template
);
}


/** resultsAsHtml is the function used to populate the Service Tab
* after the service has finished querying.
*/
Expand Down

0 comments on commit cd218ee

Please sign in to comment.