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 as an example. 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, 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:
value = 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 unfortunate that we need to have the same code in two places, but because the filtering needs to happen at the backend and frontend for real time comparison we do need this. More specifically the frontend uses the filtering code to check if after a row is edited if it still matches the views current filters. If it doesn’t then a warning will be displayed to the user that if they save their edit, the row will be filtered out of view.
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 (context) => {
const { app } = context
app.$registry.register('plugin', new PluginNamePlugin(context))
app.$registry.register('viewFilter', new EqualViewFilterType(context))
}
Once you have added this code, a new filter to a view and have 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.