Web UI

HOWTO: Filter Data in Suggestions

Updated: September 26, 2024

In this tutorial, learn how to filter data from the directory suggestion element, by using different element attributes.

Concept

The web element nuxeo-directory-suggestion displays a dropdown list with the values of a defined vocabulary. In some cases, it could be relevant to restrict the list of values, depending on some criteria/filters.

As a starting point, it is a good practice to get information on the element we need to configure and inspect all its attributes. You can get it from the Web Components website.

It is possible to filter data, thanks to different attributes:

  • directoryName: Filter by the name of the vocabulary/directory.
  • operation: Filter by the values returned by an automation chain/scripting using the Directory.SuggestEntries operation.
  • queryResultsFilter: Add additional post-filters on the suggestion.

There are 2 ways to filter values:

Using the queryResultsFilter Parameter

The queryResultsFilter allows to filter specific list of values of a vocabulary. Nuxeo Platform provides some vocabularies by default, including continent (list of continents) and country (list of countries). By default, the same Nuxeo document property is used to display a hierarchical vocabulary (Coverage, or dc:coverage).

Let's see how to separate the continent and the country in two distinct properties, and automatically refreshed the country values according to the previously selected continent.

First of all, we will store the value of the selected continent in a variable. For this, we must define a function that will be called when the value-changed event is fired from the nuxeo-directory-suggestion showing the continent:

  • In the <template> part of your layout:
<nuxeo-directory-suggestion value=""
                                label="[[i18n('label.schema.geo.continent')]]"
                                directory-name="continent"
                                role="widget"
                                min-chars="0"                               
                                on-value-changed="_continentUpdated">
</nuxeo-directory-suggestion>
  • In the Polymer part:
Polymer({
  [...]
  _continentUpdated: function(event){
    if(event && event.detail && event.detail.value){
      gContinent = event.detail.value;         
    }
  },
  [...]

Next, we will write the function that will be responsible for filtering the countries depending on the continent. The function can be named as wanted, but it must have three parameters:

  • element: The entry of the vocabulary that is evaluated
  • index: The index of the element within the vocabulary
  • array: The list of vocabulary entries
_filterCountries: function(element, index, array){
  var isInContinent = false;

  if(element && element.parent && gContinent){
    isInContinent = (gContinent == element.parent);
  }

  return isInContinent;
},

Now we just have to assign the new function to the queryResultsFilter property of the web element:

<nuxeo-directory-suggestion value=""
                            label="[[i18n('label.schema.geo.country')]]"
                            directory-name="country"
                            role="widget"
                            min-chars="0"                               
                            query-results-filter="[[_filterCountries]]">
</nuxeo-directory-suggestion>

This is be the complete code of the element:

<nuxeo-directory-suggestion value=""
                                label="[[i18n('label.schema.geo.continent')]]"
                                directory-name="continent"
                                role="widget"
                                min-chars="0"                               
                                on-value-changed="_continentUpdated">
    </nuxeo-directory-suggestion>

    <nuxeo-directory-suggestion value=""
                                label="[[i18n('label.schema.geo.country')]]"
                                directory-name="country"
                                role="widget"
                                min-chars="0"                               
                                query-results-filter="[[_filterCountries]]">
    </nuxeo-directory-suggestion>  

And

<script>
  var gContinent = null;

  Polymer({
    is: 'nuxeo-myfile-create-layout',
    behaviors: [Nuxeo.LayoutBehavior],
    properties: {
      /**
         * @doctype MyFile       
         */
      document: {
        type: Object
      }
    },

    _continentUpdated: function(event){
      if(event && event.detail &&event.detail.value){
        gContinent = event.detail.value;         
      }
    },

    _filterCountries: function(element, index, array){
      var isInContinent = false;

      if(element && element.parent && gContinent){
        isInContinent = (gContinent == element.parent);
      }

      return isInContinent;
    },               
  });
</script>

See the result:

directory-suggestion1.png
directory-suggestion1.png

Using the Operation Parameter and the Directory.SuggestEntries Operation

Sometimes the number of entries returned by the server can be very high, so it's convenient to apply the filter server-side before returning the information.

By default, the nuxeo-directory-suggestion element relies on the Directory.SuggestEntries operation. This operation provides a parameter called filters that allows you to filter the entries to be returned.

If we want to filter the European countries included in the country vocabulary, we must apply the filter filters: parent=europe in the Directory.SuggestEntries operation.

Therefore, to apply the filter we must only assign the {“filters” : “parent=europe”} value to the params attribute of nuxeo-directory-suggestion, as follows:

<nuxeo-directory-suggestion role="widget"
                             value=""
                             label="Country"
                             directory-name="country"
                             params="{"filters" : "parent=europe"}"
                             min-chars="0">
 </nuxeo-directory-suggestion>

See the result:

directory-suggestion2.png
directory-suggestion2.png

Going Further

Create a Document From a Template

As an alternative to the Nuxeo Template Rendering addon, let's say we want to create a document (File) from a list of document templates, displayed on the creation form. Once again, we will use the same filtering mechanism.

First, we create a document property (file_schema:template in our example), to store the document template ID. We assume the document templates are identified by a specific document type, or any document property we can query on.

On the creation form of our document, we use the operation filter, pointing to a custom automation chain (AC_SearchTemplates here):

<nuxeo-document-suggestion id="docSuggWatermark"
                           label="Document Template"
                           name="TemplateId"
                           value=""
                           min-chars="0"
                           result-formatter="[[ResultFormatter]]"
                           operation="AC_SearchTemplates">
</nuxeo-document-suggestion>

You may have noticed that we are also using a Result Formatter (see the Nuxeo Studio Cookbook link at the end of the page to get more information).

Then, we create the AC_SearchTemplates automation chain:

- Repository.Query:
    language: NXQL
    query: "SELECT * FROM Document WHERE ecm:mixinType != 'HiddenInNavigation'AND ecm:isVersion = 0 AND ecm:isTrashed = 0 AND ecm:primaryType = 'TemplateSource'"
    sortOrder: ASC

In this example, we are using a NXQL query to fetch the document templates.

At this point, we have stored the template document ID within our document. All we need to do now is to generate the blob from it, using an automation scripting, and call it on the Document Created Event Handler:

[...]
var templateBlob = templateDoc["file:content"];
Blob.AttachOnDocument(
  templateBlob, {
  'document': input,
  'save' : true
  }
);
[...]

See the result:

directory-suggestion3.png
directory-suggestion3.png


Nuxeo Studio Community Cookbook