A view filter can be created by a user to filter the rows of a view. Only the rows that apply to the filters are going to be displayed. There can be many types of filters like equals, contains, lower than, is empty, etc. These filter types can easily be added when creating a plugin.
We are going to create a really simple equals
filter. This filter already exists, but
because of its simplicity we are going to use it because of example purposes. In your
filter class you can define compatible field types. It will only be possible to create
a filter in combination with those field types. The get_filter
method should return
a Django models.Q
object which will automatically be added to the correct queryset.
Because the field name is provided we can easily do a Q(**{field_name: value})
comparison with the provided value.
plugins/my_baserow_plugin/backend/src/my_baserow_plugin/view_filters.py
from django.db.models import Q
from baserow.contrib.database.views.registries import ViewFilterType
class EqualToViewFilterType(ViewFilterType):
type = 'equal_to'
compatible_field_types = ['text']
def get_filter(self, field_name, value, model_field):
value = value.strip()
# If an empty value has been provided we do not want to filter at all.
if value == '':
return Q()
# Check if the model_field accepts the value.
try:
model_field.get_prep_value(value)
return Q(**{field_name: value})
except Exception:
pass
return Q()
Finally we need to register the view filter in the registry.
plugins/my_baserow_plugin/backend/src/my_baserow_plugin/config.py
from django.apps import AppConfig
from baserow.core.registries import plugin_registry
from baserow.contrib.database.views.registries import view_filter_type_registry
class PluginNameConfig(AppConfig):
name = 'my_baserow_plugin'
def ready(self):
from .plugins import PluginNamePlugin
from .view_filters import EqualToViewFilterType
plugin_registry.register(PluginNamePlugin())
view_filter_type_registry.register(EqualToViewFilterType())
After creating the filter type you can create a filter by making the following API request. Note that you must already have a grid view that contains some fields.
POST /api/database/views/{view_id}/filters/
Host: api.baserow.io
Content-Type: application/json
{
"field": {field_id},
"type": "equal_to",
"value": "Example"
}
or
curl -X POST -H 'Content-Type: application/json' -i https://api.baserow.io/api/database/views/{view_id}/filters/ --data '{
"field": {field_id},
"type": "equal_to",
"value": "Example"
}'
Now that the filter has been created you can refresh your grid view by calling the
list_database_table_grid_view_rows endpoint
. It will now only contain the rows that
apply to the filter.
GET /api/database/views/grid/{view_id}/
Host: api.baserow.io
Content-Type: application/json
or
curl -X GET -H 'Content-Type: application/json' -i https://api.baserow.io/api/database/views/grid/{view_id}/'
This filter also needs to be added to the web frontend, otherwise it does not know the
filter exists. You can add the filter by creating a new ViewFilterType
class and
register it with the viewFilter
registry. the getName
method should return a string
that is visible to the user when choosing the filter. The getInputComponent
method
handles the user input of the value. By default no input is shown. The
getCompatibleFieldTypes
should return a list of field type names that are compatible
with the filter. The last method is named matches
and we use this to check if a value
is compatible applies to the filter in real time.
It is really unfortunate that we need to have the same code in two places, but because the filtering needs to happen at the backend and the real time comparison needs to happen at the web frontend we do need this.
plugins/my_baserow_plugin/web-frontend/viewTypes.js
import { ViewFilterType } from '@baserow/modules/database/viewFilters'
import ViewFilterTypeText from '@baserow/modules/database/components/view/ViewFilterTypeText'
export class EqualViewFilterType extends ViewFilterType {
static getType() {
return 'equal_to'
}
getName() {
return 'is 2'
}
getInputComponent() {
// The component that handles the value input, in this case we use the existing
// text input, but it is also possible to create a custom component. It should
// follow v-model principle.
return ViewFilterTypeText
}
getCompatibleFieldTypes() {
return ['text']
}
matches(rowValue, filterValue) {
if (rowValue === null) {
rowValue = ''
}
rowValue = rowValue.toString().toLowerCase().trim()
filterValue = filterValue.toString().toLowerCase().trim()
return filterValue === '' || rowValue === filterValue
}
}
plugins/my_baserow_plugin/web-frontend/plugin.js
import { PluginNamePlugin } from '@my-baserow-plugin/plugins'
import { EqualViewFilterType } from '@my-baserow-plugin/viewFilters'
export default ({ store, app }) => {
app.$registry.register('plugin', new PluginNamePlugin())
app.$registry.register('viewFilter', new EqualViewFilterType())
}
Once you have added this code and you add a new filter to a view and you also selected
a text field you should be able to select the is 2
filter. It should also be possible
to provide a text value to compare the field value with.