Swing allows to design and add custom filters to your searches.

Configure a custom filter

Filters are made of an HTML template and a related JS file.

Default templates are put in the base folder

{SWING-APP}/config/templates/search/filters

For custom templates, it is recommended ( read mandatory ) that you put them in a specific folder:

{SWING-APP}/config/templates/search/filters/{TEMPLATE-FOLDER}

Filters can be configured outside {SWING-APP}. See the paragraph How to configure search filters in external folder for some tips in how to take advantage of this new configuration option.

Design the template

The template is a simple HTML file.

There are no real boundaries inside the template, but it is strongly suggested to follow the guidelines below.

There are various attributes to be aware of:

Table 1. Supported attributes
Attribute Description

data-xvalue

This is the main parameter. It is the one that defines the type of filter. See Supported keywords for a list of available filters.

data-preload

In specific cases ( e.g. owner, status, type…​) if the value is true, Swing preloads the component with all the available values. See Supported keywords for a list of the keywords with support data-preload.

data-xprefix

This attribute is used to specify fixed prefix to the rules. For example, see metadata keyword.

data-default

This attribute is used to set a default value for the filter (e.g. a text for the input element, a date for the calendar, etc). The value is also used after a reset.

data-identifier

This attribute is used to identify a field. It is used in the setSearchValue method. See onLoad to see the method in use.

data-operator

Possible values are "AND", "OR", "NOT". If not specified, the condition is added with an AND operator. See the Warning below for further info.

data-block-operator

Possible values are "AND", "OR", "NOT". If not specified, the condition is added with an AND operator. See the Warning below for further info.

data-operator and data-block-operator are different. data-block-operator should be used ONLY with SELECT MULTIPLE or BOOTSTRAP TAGSINPUT or, in general, with any element which returns multiple values. data-block-operator defines the operator with which the whole selection is added to the query, while data-operator defines which operator is used to join each of the selected values. For example, the following HTML code:

<select multiple data-identifier="custom-select-multiple" data-xvalue="type" data-operator="OR" data-block-operator="AND">
    <option>EOM::Story</option>
    <option>EOM::CompoundStory</option>
    <option>EOM::Webpage</option>
    <option>Image</option>
</select>

The result will be AND ( EOM::Story OR Image ).

And the following:

<select class="form-control" multiple data-identifier="custom-select-multiple" data-xvalue="type" data-operator="NOT" data-block-operator="AND">
    <option>EOM::Story</option>
    <option>EOM::CompoundStory</option>
    <option>EOM::Webpage</option>
    <option>Image</option>
</select>

The result will be AND ( NOT EOM::Story NOT Image ).

Style guidelines

As will be clear from the predefined HTML suggestions, a "filter block" should be created as follows:

<div class="emui-row">
    <div class="emui-title">{BLOCK-TITLE}</div>
    <div class="emui-content">
        {BLOCK-CONTENT}
    </div>
</div>

Inside the block content, it is suggested to use standard HTML5 components, such as:

Input box

<input type="text" class="form-control" data-xvalue="{XVALUE}" placeholder="My placeholder" data-operator="AND"/>

Select, dropdown

<select class="form-control" data-xvalue="{XVALUE}" data-operator="AND">
    <option value="">Any workflow</option>
    <option value="NewsFlow/Editing">NewsFlow/Editing</option>
    <option value="NewsFlow/For Approval"></option>
</select>
It is important to insert an option without value ( or, better, value set to "" ), so the the user can, if necessary, exclude that particular filter.

Select multiple

Select multiple needs an additional data-block-operator attribute ( if omitted, default is AND ). See the specific paragraph for further information.

<select class="form-control" multiple data-identifier="custom-select-multiple" data-xvalue="type" data-operator="NOT" data-block-operator="AND">
    <option>EOM::Story</option>
    <option>EOM::CompoundStory</option>
    <option>EOM::Webpage</option>
    <option>Image</option>
</select>

The result will be AND ( NOT EOM::Story NOT Image ).

Radio buttons

It is possible to use radio buttons for some reasons, like enabling or disabling some fields. If you want to save the value, add a data-identifier attribute, without data-xvalue. Please stick to Bootstrap 3 syntax for radio buttons.

<!-- Sample radio button -->
<div class="emui-row">
    <div class="emui-title">Options radios</div>
    <div class="emui-content">
        <div class="radio">
          <label>
            <input type="radio" name="optionsRadios" data-identifier="optionsRadios1" value="option1" checked>
            Option one is this and that&mdash;be sure to include why it's great
          </label>
        </div>
        <div class="radio">
          <label>
            <input type="radio" name="optionsRadios" data-identifier="optionsRadios2" value="option2">
            Option two can be something else and selecting it will deselect option one
          </label>
        </div>
        <div class="radio disabled">
          <label>
            <input type="radio" name="optionsRadios" data-identifier="optionsRadios3" value="option3" disabled>
            Option three is disabled
          </label>
        </div>
    </div>
</div>

DatePicker and DateTimePicker components

It is possible to use the "datepicker" component using the following HTML. To use the dateTimePicker, write "datetimepicker" in the data-emui-type attribute.

It is extremely important to decide where to put the data-xvalue attribute in the case of datepicker or datetimepicker. If, as in the example, it is places in the input field, the value returned is the Date converted in the format specified by the data-format attribute. If, instead, it is placed directly in the div with the data-emui-type attribute, the value returned is a Javascript Date Object. See [range] for a better example of this second usage.

Example with data-xvalue in the input field
<div class="input-append date" data-emui-type="datepicker">
    <input data-format="dd-MM-yyyy" class="form-control" placeholder="Created" data-xvalue="created" type="text" data-operator="AND"></input>
    <span class="add-on"><i data-date-icon="icon-calendar"></i></span>
</div>

In this case, when doing ctx.getSearchValue(), a string with the selected format will be returned.

Example with data-xvalue in the date field
<div class="input-append date" data-emui-type="datepicker" data-xvalue="created" data-operator="AND">
    <input class="form-control" placeholder="Created" type="text"></input>
    <span class="add-on"><i data-date-icon="icon-calendar"></i></span>
</div>

In this case, when doing ctx.getSearchValue(), a Javascript Date Object will be returned. Plus, the calendar will have the localized format specified in the Configuration.

See [created] for an example of these components.

Bootstrap tagsinput

Swing filters natively support Bootstrap Tags input (Bootstrap Tags Input). Bootstrap Tags Input needs an additional data-block-operator attribute ( if omitted, default is AND ). See the specific paragraph for further information.

<div class="emui-row">
    <div class="emui-title">TYPES</div>
    <div class="emui-content">
        <input type="text" value="" data-role="tagsinput" data-identifier="type-tagsinput" data-xvalue="type" data-operator="OR" data-operator="AND" />
    </div>
</div>

It also requires a Javascript initialization.

{
    // ...
    onLoad: function( ctx, params ) {
        $('[data-identifier="type-tagsinput"]', params.panel).tagsinput({
            typeahead: {
              source: [ "EOM::Story", "Image", "EOM::MediaGallery", "EOM::WebPage" ]
            }
        });
    },
    // ...
}

Reset filter button

A "Reset filter" button is automatically added in the filter template.

Use the attribute data-default if you want the various filters to have a specific value after reset.

CSS guidelines

Use the form-control class to fix the width of the components to 100% of the filter panel.

Configure the JS file

To add a filter, the JS file should be structured as follows.

eidosmedia.webclient.search.addFilter( options );

In detail, the options are:

/**
 * CUSTOM FILTER
 * @name: Swing custom filter
 */
eidosmedia.webclient.search.addFilter({
    // @property "domain": {string} - it corresponds to the value configured in the <name> parameter of a specific search domain to apply the filter to
    // @property "domainType": {string} - it corresponds to the value configured in the <type> parameter of one or more searchs domain. So, if specified the filter is applied to all the domains with the same type
    // @required - only one parameter between domain or domainType
	"domain": "eomdblocal",
    // "domainType": "eomdb",

    // @property "template": {string} - the path to the search template. Path is relative to the 'config/search/filters/' folder.
    // @required
    template: 'swing-filter.html',

    /**
     * Function called after loading the template, but BEFORE loading the query
     * use it to add listeners.
     * @param {ContextObject}
     * @param {Object} params - the params of the search element
     * @param {Function} params.setSearchValue(identifier, value) - a method that allows to set a value for a specific field with the specified data-identifier.
     * @param {Node} params.panel - the current DOM node for the search filter panel
     */
    onLoad: function( ctx, params ) {
        // ...
    },

    /**
         * Function called whenever a condition in the search is changed.
         * @param {ContextObject}
         * @param {String} condition - the string with the changed condition
         */
        onConditionChange: function( ctx, condition ) {
            console.log('CONDITION CHANGED');
            console.log(condition)
        },

    /**
     * Function called after loading the query
     * use it to fix the custom elements.
     * @param {ContextObject}
     * @param {Object} params - the params of the search element
     * @param {Node} params.el - the current DOM node analized
     */
    onQueryLoaded: function( ctx, params ) {
        // ...
    },

    /**
     * This function must return the value in the form <key>:<value> for each of the
     * elements configured.
     * @method getSearchValue
     * @param {Object} params - the params of the search element
     * @param {Node} params.panel - the current DOM node for the search filter panel
     * @param {Node} params.el - the current DOM node analyzed
     * @param {String} params.dataId - the value of the data-xvalue attribute
     * @param {String} params.dataIdentifier - the value of the data-identifier attribute
     * @param {Function} getSearchValue() - the method that returns the search value calculated by default.
     * @param {Function} params.setSearchValue(identifier, value) - a method that allows to set a value for a specific field with the specified data-identifier.
     */
    getSearchValue: function( ctx, params ) {
        // ...
    }

});

Each parameter is detailed below.

domain and domainType

The filter can be coupled with either a domain or a domainType. In the latter case, all domain of the same type will share the same filter.

The domain parameter requires the same name configured in the Search configuration. See Domains configuration for further details. Please see the box below for information regarding the default-folder filter.

The domainType parameter can be one of the following: eomdb.

By specifying default-folder as a value for the domain property, it is possible to override the default filter for folders. This is an additional functionality available in Swing.

Under filter/default-folder-filter/ folder, it is possible to find the Swing default folder filter. Please use it as a reference.

template

This property defines the template for the filter.

{
    // ...
    template: "test.html",
    // ...
}

The path of the template starts from the search/filters/ folder. If you placed the template in a subfolder (e.g. search/filters/testfilter/), the template should be valued as "testfilter/test.html".

onLoad

onLoad is a function called when the filter is loaded for the first time. This function is called AFTER the DOM has been filled, so that all the DOM elements of the filter are available. This function is called BEFORE the query has been loaded. It can be used to add custom listeners for events.

Unless the filter is heavily customized, the onLoad function can be ignored.

It is called with 2 parameters:

  • ctx: the Context Object. See Context Object documentation for further details. In this case, though, the context object has neither activeObj nor selection, and only contains information on the Swing area.

  • params. It is a Javascript Object with 2 properties:

    • panel: the DOM reference to the filter panel.

    • setSearchValue: a method to set the value of a field in the Search filter. See the following example for further details.

{
    onLoad: function( ctx, params ) {
        var $panel = $( params.panel );
        // Do some things...

        // setSearchValue( identifier, value ) - sets the value of a field which has a 'data-identifier' attribute;
        params.setSearchValue('createdField', '09-08-2015')

    }
}

Return value of the function is not important.

onUpdateFilterElements

onUpdateFilterElements is a function called whenever the filter elements should be updated.

It is called with the following parameters:

  • ctx: the Context Object. See Context Object documentation for further details. In this case, though, the context object has neither activeObj nor selection, and only contains information on the Swing area.

  • panel: the DOM reference to the filter panel.

  • filters. It is an array of Javascript Object with 2 main properties:

    • identifier: the filter indetifier.

    • value: the related filter value.

{
    onUpdateFilterElements: function( ctx, panel, filters ) {
         for (let j = 0; j < filters.length; j++) {
            const filterElement = filters[j];
            if (filterElement.identifier == 'author') {
                const value = filterElement.value;
            }
        }
    }
}

Return value of the function is not important.

onConditionChange

onConditionChange is a function called whenever a condition inside the search is changed (the ones on the top left dropdown). It can be used to change the filter HTML according to a specific condition.

It is called with 2 parameters:

  • ctx: the Context Object. See Context Object documentation for further details. In this case, though, the context object has neither activeObj nor selection, and only contains information on the Swing area.

  • params. It is a Javascript Object with 2 properties:

    • panel: the DOM reference to the filter panel.

    • condition. The condition that has changed. (As a string).

{
    onConditionChange: function( ctx, params ) {
        if (params.condition === 'type:image') {
            // I'm selecting, for example the condition image.
            // Show only the part related to the image.
            $(params.panel).find('[data-filter="image"]').show();
        }

    }
}

Return value of the function is not important.

onQueryLoaded

onQueryLoaded is a function called AFTER the query has been loaded. It can be used to customize behaviour after the query values have been loaded.

Unless the filter is heavily customized, the onQueryLoaded function can be ignored.

It is called with 2 parameters:

  • ctx: the Context Object. See Context Object documentation for further details. In this case, though, the context object has neither activeObj nor selection, and only contains information on the Swing area.

  • params. It is a Javascript Object with 2 properties:

    • panel: the DOM reference to the filter panel.

    • setSearchValue: a method to set the value of a field in the Search filter. See the following example for further details.

{
    onQueryLoaded: function( ctx, params ) {
        // ...
    }
}

Return value of the function is not important.

getSearchValue

    /**
     * This function must return the value in the form <key>:<value> for each of the
     * elements configured.
     * @method getSearchValue
     * @param {Object} params - the params of the search element
     * @param {Node} params.panel - the current DOM node for the search filter panel
     * @param {Node} params.el - the current DOM node analyzed
     * @param {String} params.dataId - the value of the data-xvalue attribute
     * @param {String} params.dataIdentifier - the value of the data-identifier attribute
     * @param {Function} params.getSearchValue() - the method that returns the search value calculated by default.
     * @param {Function} params.setSearchValue(identifier, value) - a method that allows to set a value for a specific field with the specified data-identifier.
     */
    getSearchValue: function( ctx, params ) {
        /*
         * ctx object, in this case, contains only info about the current view and tab.
         */

        /*
         *  Use this method ONLY if you need to perform further elaborations ( e.g. in case
         *  you don't want to pass some values, or in case this element is hidden but
         *  you still want to pass it, or in case of multiple connected inputs to produce
         *  a single value ).
         */

        /*
         * IMPORTANT
         * If this value must not be used for the query, return null.
         */

        // EXAMPLE: force Globe/Images folder.
        if ( params.dataId === 'restrictto' ) {
            return 'restrictto:/Globe/Images';
        } else if ( params.dataId === 'created' ) { {
            // EXAMPLE: let's ignore this value
            return null;
        } else {
            // Returns the value as calculated by Swing.
            return params.getSearchValue();
        }
    }

As it will be clear from the Supported keywords paragraph, the filters are built as a set of <key>:<value>. This is done by finding all the DOM elements with data-xvalue attribute, and elaborating their contents.

This is done automatically for simple elements such as the one shown in the documentation. For more complex elements, it is possible to override the default behaviour with this getSearchValue function.

It is called with 2 parameters:

  • ctx: the Context Object. See Context Object documentation for further details. In this case, though, the context object has neither activeObj nor selection, and only contains information on the Swing area.

  • params. It is a Javascript Object with 4 properties:

    • {Node} el: the DOM reference to the current filter ( the element which has the data-xvalue attribute ).

    • {Node} panel: the DOM reference to the filter panel

    • {String} dataId: the value of the data-xvalue attribute. It is the current key which is processed.

    • {String} dataIdentifier - the value of the data-identifier attribute.

    • {Function} getSearchValue: a function which builds the string in the correct format ( <key>:<value> ).

    • {Function} setSearchValue( identifier, value ): a method to set the value of a filter with a specific data-identifier attribute.

Unless the filter is heavily customized, the getSearchValue function can be ignored.

If you want a specific filter to be ignored, the return value of the function should be null.

Supported keywords

The supported keywords are meaningful for EOMDB searches only. If you want to use filters for custom domains, feel free to use any keyword you prefer. The filters will be passed in the conditions array of the Search Controller (options parameter). See Search controller documentation for further details.

Table 2. Supported keywords
Keyword Description

channel, userchannel

Returns only the objects of a given channel. If userchannel is used, only the channels available to the current user are visible.

content

Search a specific text in the content of an object.

contentmetadata

Search for a text in both content and metadata.

created

Given a date, returns the objects created in that period.

created_lastdays

Allow to obtain the documents created in the last N days

creator

See user.

freexml

Allow to insert a specific xml in the query. Please use it with moderation.

issuedate

Given a date, returns the objects whose issue date is in that period.

lastmodifier

Returns the objects last modified by a specific user.

limit

Limits the results to a specific number.

locker, lockedby

Search for objects locked by a given user

metadata

Search a specific value in a given xpath.

metadatarange

Search a specific value in a given xpath, with the "range" operator ( inside the se:attributes tag )

modified

Given a date, returns the objects modified in that period.

modified_lastdays

Allow to obtain the documents modified in the last N days

owner

See user.

range

See metadatarange.

restrictto

Returns the objects inside a path.

sort

Complete sorting mechanism.

sortby

Simple descending sort according to a parameter in the ObjectInfo.

status, workflow

Search objects with a given status ( workflow ).

type

Returns only the objects of a given type.

usageticket

Allow to search within the usage tickets.

user, creator, owner

Search for objects created by a given user

userchannel

channel.

workflow

See status.

workfolder

Returns the objects inside a workfolder.

channel

Returns only the objects of a given channel.

Syntax

channel:(CHANNEL)
userchannel:(CHANNEL)

Values

Table 3. Supported values
Keyword Example Description

CHANNEL

channel:"Globe-Print"

Any string value (with quotes if there is a space).

userchannel differs from channel in the fact that only the channels relative to the current user are available..

Suggested HTML implementations

Free channel input
<div class="emui-row">
    <div class="emui-title">Channel</div>
    <div class="emui-content">
        <input type="text" class="form-control" data-xvalue="channel" placeholder="Channel" data-operator="AND"/>
    </div>
</div>
Free channel input filter
Figure 1. Free channel input filter
Choice from a list of channels
<div class="emui-row">
    <div class="emui-title">Channel</div>
    <div class="emui-content">
        <select data-xvalue="channel" class="form-control" data-operator="OR">
            <option value="">All channels</options>
            <option value="Globe-Print">Globe-Print</options>
            <option value="Globe-Web">Globe-Web</options>
        </select>
    </div>
</div>
Choice from a list of channels
Figure 2. Choice from a list of channels
Preload user channels (ONLY for userchannel keyword)
<div class="emui-row">
    <div class="emui-title">Channel</div>
    <div class="emui-content">
        <select data-xvalue="userchannel" class="form-control" data-preload="true" data-operator="OR">
        </select>
    </div>
</div>
In case of userchannel keyword, it is possible to use data-preload="true". In that case, only the current user’s channels are available.

content

Search a specific text in the content of an object.

Syntax

content:"CONTENT"

Values

Table 4. Supported values
Keyword Example Description

CONTENT

content:Obama

Any string value (with quotes if there is a space).

Suggested HTML implementations

<div class="emui-row">
    <div class="emui-title">Content</div>
    <div class="emui-content">
        <input type="text" class="form-control" data-xvalue="content" placeholder="Content"data-identifier="contentField1"/>
    </div>
</div>
Result
Content filter
Figure 3. Content filter

contentmetadata

Search for a text in both content and metadata.

Syntax

contentmetadata:"CONTENT"

Values

Table 5. Supported values
Keyword Example Description

CONTENT

contentmetadata:Obama

Any string value (with quotes if there is a space).

Suggested HTML implementations

See content for a suggested implementation: please remember to replace data-xvalue="content" with data-xvalue="contentmetadata".

created_lastdays

Allow to obtain the documents created in the last N days

Syntax

created_lastdays:(VALUE)

Values

Table 6. Supported values
Keyword Example Description

VALUE

created_lastdays:10

Any numeric value.

creator

freexml

Allow to insert a specific xml in the query. Please use it with moderation.

Syntax

freexml:"CONTENT"

Values

Table 7. Supported values
Keyword Example Description

CONTENT

freexml:"<SysAttributes><props><productInfo><issueDate q:op='EXIST'/></productInfo></props></SysAttributes>"

Any string value (with quotes if there is a space). Note: please use single quotes when a double quote is used inside the value.

In case of freexml, double quotes need to be replaced by @@. Alternatively, CDATA can be used to wrap "content".

<filter>
<name>EDT_Sport</name>
<condition>freexml:<![CDATA[<ObjectInfo><oteam>EDT_Sport</oteam></ObjectInfo>]]></condition>
</filter>

Suggested HTML implementations

If checked, only items with an issue date are searched.

<div class="emui-row">
    <div class="emui-content">
        <div class="checkbox">
          <label>
            <input type="checkbox" data-xvalue="freexml" value="<SysAttributes><props><productInfo><issueDate q:op='EXIST'/></productInfo></props></SysAttributes>"/>
            Only items with issue date
          </label>
        </div>
    </div>
</div>

Advanced HTML Sample

Here follows a complex example that makes use of freexml to search into Virtual Attributes according to the user input.

<div class="emui-row">
    <div class="emui-title">Owner Team</div>
    <div class="emui-content">
        <input type="text" class="form-control" data-xvalue="oteamVA" />
    </div>
</div>

<div class="emui-row">
    <div class="emui-title">C Team</div>
    <div class="emui-content">
        <input type="text" class="form-control" data-xvalue="cteamVA" />
    </div>
</div>

<!-- hidden field for virtual-attributes existence -->
<input type="hidden" data-identifier="vaexist" data-xvalue="freexml" />

The javascript part must be included within the Filter definition.

    getSearchValue: function( ctx, params ) {
        // Example to manage the virtual attributes
        if (params.dataId === 'oteamVA') {
            // Saves for later reuse
            this.oTeam = params.getSearchValue();
            return null;
        } else if (params.dataId === 'cteamVA') {
            // Saves for later reuse
            this.cTeam = params.getSearchValue();
            return null;
        } else if (params.dataIdentifier === 'vaexist') {
            var xml = "<va xmlns:eom='http://www.eidosmedia.com/eom'>" +
            '<parent_uuid>fbed282e-35e2-11e2-9e81-0545e1a77e80</parent_uuid>' +
            (this.oTeam ? '<oteam>' + this.oTeam + '</oteam>' : '') +
            (this.cTeam ? '<cteam>' + this.cTeam + '</cteam>' : '') +
            '<vid>3</vid>' +
            '<vt>1511298626</vt>' +
            '<vm>eidosmedia_support</vm>'
            '</va>';
            return xml;
        }

        return params.getSearchValue();
     }

lastmodifier

Returns the objects last modified by a specific user.

Syntax

lastmodifier:(USER|myself)

Values

Table 8. Supported values
Keyword Example Description

USER

lastmodifier:johndoe

Any string value (with quotes if there is a space). Return the objects modified by the specified user.

myself

lastmodifier:myself

Return the objects modified by the current user

Suggested HTML implementations

See user, creator, owner. The supported value and the HTML implementations are the same. Please remember to replace "owner", "user" or "creator" with "lastmodifier".

limit

Limits the results to a specific number.

Syntax

limit:(VALUE)

Values

Table 9. Supported values
Keyword Example Description

VALUE

Any numeric value

limit:100

Suggested HTML implementations

<div class="emui-row">
    <div class="emui-title">Limit results</div>
    <div class="emui-content">
        <input type="number" class="form-control" data-xvalue="limit" min="0" max="5000"/>
    </div>
</div>
Result
Limit filter
Figure 4. Limit filter

locker, lockedby

Search for objects locked by a given user

Syntax

locker:(USER|myself)

Values

Table 10. Supported values
Keyword Example Description

USER

locker:joe.bolton

Any string value (with quotes if there is a space). Return the objects locked by the specified user.

myself

locker:myself

Return the objects locked by the current user

locker, lockedby keywords are totally equivalent.

Suggested HTML implementations

See user, creator, owner. The supported value and the HTML implementations are the same. Please remember to replace "owner", "user" or "creator" with "locker".

metadata

Search a specific value in a given xpath.

Syntax

metadata:"CONTENT"

Values

Table 11. Supported values
Keyword Example Description

CONTENT

metadata:"{{SETTINGS}}/Metadata/Editorial/ContentType=my value here"

Any string value (with quotes if there is a space).

Suggested HTML implementations

<div class="emui-row">
    <div class="emui-title">Metadata</div>
    <div class="emui-content">
        <input type="text" class="form-control" data-xvalue="metadata" placeholder="Metadata" data-identifier="metadataField1"/>
    </div>
</div>

If you want the user to put only the value, because the x-path is already defined ( and should not be changed ), use the data-xprefix attribute, as in the following example:

<div class="emui-row">
    <div class="emui-title">Editorial/ContentType</div>
    <div class="emui-content">
        <input type="text" class="form-control" data-xvalue="metadata" data-xprefix="/Editorial/ContentType=" placeholder="ContentType"/>
    </div>
</div>

In this second case, the user will only need to write the value of the /Editorial/ContentType/ xpath.

Result
Metadata filter
Figure 5. Metadata filter

It is possible to specify additional properties within the metadata keyword. At the moment, the only supported setting is the search operator. To configure it, add {{op=MATCH}} in the data-prefix or to the value of the metadata. The content inside the {{ …​ }} will be processed and all the settings inside applied to the search. Currently supported settings are:

  • Search operator : op=OPERATOR (e.g. op=MATCH )

A sample with settings:

<div class="emui-row">
    <div class="emui-title">Editorial/ContentType</div>
    <div class="emui-content">
        <input type="text" class="form-control" data-xvalue="metadata" data-xprefix="{{op=MATCH}}/Editorial/ContentType=" placeholder="ContentType"/>
    </div>
</div>

metadatarange

Search a specific value in a given xpath, with the "range" operator ( inside the se:attributes tag )

Syntax

metadatarange:"{X-PATH}={VALUE}"

Values

Table 12. Supported values
Keyword Example Description

"{X-PATH}={VALUE}"

metadatarange:"/Metadata/Editorial/ContentType=RANGE"

See previous example. Note: Quotes are mandatory. If the value contains double quotes, use single quotes instead.

The RANGE value must be in the following format: YYYYMMDDhhmmss;YYYYMMDDhhmmss.

Suggested HTML implementations

See Modified: Interval of dates for a sample implementation.

In this example, we are creating a "Created range" filter, allowing the user to specify both date and time. Please notice that:

  • data-xvalue attributes are respectively "field-from", "field-to", and "range" and are placed in the DIV element with data-emui-type="datetimepicker". This allows the user to obtain the Javascript Date Object as an elaboration.

  • The element with data-xvalue="range" also has a data-xprefix="/ObjectInfo/Created=" attribute.

  • the only difference between metadatarange and range is that the generated xml is wrapped in a <se:attributes></se:attributes> tag in case of metadatarange.

Result
Range filter
Figure 6. Range filter
Javascript

See Modified: Interval of dates for a sample implementation. Please refer only to the first part of the getSearchValue function.

Modified: Interval of dates

With this filter implementation, it is possible to play a little bit with the fields to allow the use of an interval of dates.

Let’s see a complete example:

HTML
<!-- MODIFIED -->
<div class="emui-row">
    <div class="emui-title">Modified</div>
    <div>
        <div class="emui-content" style="width: 40%;float: left;">
            <div class="emui-title">From:</div>
            <div class="input-append date" data-emui-type="datepicker" data-xvalue="modified-date-from">
                <input id="modified-date-from" class="form-control" placeholder="From" type="text" data-identifier="fromField1"></input>
                <span class="add-on"><i data-date-icon="icon-calendar"></i></span>
            </div>
        </div>
        <div class="emui-content" style="width: 40%;float: left; margin-left:30px">
            <div class="emui-title">To:</div>
            <div class="input-append date" data-emui-type="datepicker" data-xvalue="modified-date-to">
                <input id="modified-date-to" class="form-control" placeholder="To" type="text" data-identifier="toField1"></input>
                <span class="add-on"><i data-date-icon="icon-calendar"></i></span>
            </div>
        </div>
        <div class="emui-content" style="display: none; visibility: hidden;">
                <div class="input-append date" data-emui-type="datepicker" data-xvalue="modified">
                <input id="date-to" class="form-control" type="text" data-identifier="modifiedField1"></input>
            </div>
        </div>
    </div>
</div>

It is extremely important to decide where to put the data-xvalue attribute in the case of datepicker or datetimepicker. If, as in the example, it is places in the input field, the value returned is the Date converted in the format specified by the data-format attribute. If, instead, it is placed directly in the div with the data-emui-type attribute, the value returned is a Javascript Date Object.

In this case, the data-xvalue is placed in the DIV element of the datepicker.
Javascript
// NOTE: We are including ONLY the "getSearchValue" method of the Javascript file. The rest looks the same as documented below.

getSearchValue: function(ctx, params) {
    /*
     *  ctx object, in this case, contains only info about the current view and tab.
     *  Use this method ONLY if you need to perform further elaborations ( e.g. in case
     *  you don't want to pass some values, or in case this element is hidden but
     *  you still want to pass it, or in case of multiple connected inputs to produce
     *  a single value ).
     */

    /* EXAMPLE WITH DATA-XVALUE IN THE DATEPICKER DIV. A DATE OBJECT IS RETURNED. */

    // Does nothing.
    if (params.dataId === 'modified-date-from') {
        // First, save the date-from value for later
        this.dateFrom = null;
        if(params.getSearchValue() !== null){
             this.dateFrom = params.getSearchValue()[0];
        }
        // We return null because we don't want it to be processed by the filter engine.
        return null;
    }
    else if (params.dataId === 'modified-date-to') {
        // Then, save the date-to value for later
        this.dateTo = null;
        if(params.getSearchValue() !== null){
            this.dateTo = params.getSearchValue()[0];
        }
        // We return null because we don't want it to be processed by the filter engine.
        return null;
    } else if (params.dataId === 'modified') {
        // At last, I have the hidden "modified" field, which I can build as desired.

        if (this.dateFrom === null && this.dateTo === null) {
            // User did not specify anything. We don't specify the "modified" field
            return null;
        } else if (this.dateFrom !== null && this.dateTo !== null) {
            // User specified both the "from" date and the "to" one.
            // We build the modified value as "DATEFROM;DATETO";

            /* NOTE: IN CASE OF RANGE / METADATARANGE FILTER, the format MUST BE YYYYMMDDHHmmss instead of YYYYMMDD */
            return moment(this.dateFrom).format('YYYYMMDD') + ';' + moment(this.dateTo).format('YYYYMMDD');
        } else if (this.dateFrom === null) {
            // User specified ONLY the "to" date.
            // We can decide that, in this case, the from date is a year before.
            var today = new Date();
            var yyyy = today.getFullYear() - 1;
            this.dateFrom = moment(today).year(yyyy).toDate();

            /* NOTE: IN CASE OF RANGE / METADATARANGE FILTER, the format MUST BE YYYYMMDDHHmmss instead of YYYYMMDD */
            return moment(this.dateFrom).format('YYYYMMDD') + ';' + moment(this.dateTo).format('YYYYMMDD');
        } else {
            // User specified ONLY the "from" date.
            // We can decide that, in this case, the to date is today.
            var today = new Date();
            this.dateTo = moment(today).toDate();

            /* NOTE: IN CASE OF RANGE / METADATARANGE FILTER, the format MUST BE YYYYMMDDHHmmss instead of YYYYMMDD */
            return moment(this.dateFrom).format('YYYYMMDD') + ';' + moment(this.dateTo).format('YYYYMMDD');
        }
    }
    else {
        // In any other case, for any other field, we return the value inserted by the user.
        return params.getSearchValue();
    }


    /* ALTERNATIVE EXAMPLE WITH DATA-XVALUE IN THE INPUT DATEPICKER. A STRING IS RETURNED. */

    if (params.dataId === 'modified-date-from') {
        // First, save the date-from value for later
        this.dateFrom = params.getSearchValue();
        // We return null because we don't want it to be processed by the filter engine.
        return null;
    }
    else if (params.dataId === 'modified-date-to') {
        // Then, save the date-to value for later
        this.dateTo = params.getSearchValue();
        // We return null because we don't want it to be processed by the filter engine.
        return null;
    }
    else if (params.dataId === 'modified') {
        // At last, I have the hidden "modified" field, which I can build as desired.

        if (this.dateFrom === null && this.dateTo === null) {
            // User did not specify anything. We don't specify the "modified" field
            return null;
        } else if (this.dateFrom !== null && this.dateTo !== null) {
            // User specified both the "from" date and the "to" one.
            // We build the modified value as "DATEFROM;DATETO";
            return this.dateFrom + ';' + this.dateTo;
        } else if (this.dateFrom === null) {
            // User specified ONLY the "to" date.
            // We can decide that, in this case, the from date is a year before.

            var today = new Date();
            var yyyy = today.getFullYear() - 1;
            var newDateFrom = yyyy + '' + '0101';

            // We build the new interval.
            return newDateFrom + ';' + this.dateTo;
        } else {
            // User specified ONLY the "from" date.
            // We can decide that, in this case, the from date is 15 days after today.

            var today = new Date();
            today.setDate(today.getDate() + 15);

            var dd = today.getDate();
            var mm = today.getMonth() + 1;

            if (dd < 10) dd = '0'+ dd;
            if (mm < 10) mm = '0'+ mm;

            var newDateTo = today.getFullYear() + '' + mm + dd;

            return dateFrom + ';' + newDateTo;
        }
    } else {
        // In any other case, for any other field, we return the value inserted by the user.
        return params.getSearchValue();
    }
}
Explanation

We are exploiting the fact that the filter engine processes fields in the order they appear. So, at first we include two fields, whose data-xvalue attribute is modified-date-from and modified-date-to. Then, we include a hidden field named modified, which is the supported keyword. By hiding it, we prevent the user from filling it. By including it, the modified field will be processed exactly like any other, so we can process it in the Javascript file, as presented.

modified_lastdays

Allow to obtain the documents modified in the last N days

Syntax

modified_lastdays:(VALUE)

Values

Table 13. Supported values
Keyword Example Description

VALUE

modified_lastdays:10

Any numeric value.

range

restrictto

Returns the objects inside a path.

Syntax

restrictto:(VALUE)

Values

Table 14. Supported values
Keyword Example Description

VALUE

Any string value (with quotes if there is a space).

restrictto:"/Globe/Images"

Suggested HTML implementations

Free input
<div class="emui-row">
    <div class="emui-title">Restrict to path (and subfolders)</div>
    <div class="emui-content">
        <input type="text" class="form-control" data-xvalue="restrictto" placeholder="Path" />
    </div>
</div>
Free path input filter
Figure 7. Free path input filter
Choice from a list
<div class="emui-row">
    <div class="emui-title">Restrict to path (and subfolders)</div>
    <div class="emui-content">
        <select data-xvalue="restrictto" class="form-control">
            <option value="">All paths</options>
            <option value="/Globe/Stories/Politics">/Globe/Stories/Politics</options>
            <option value="/Globe/Stories/Sport">/Globe/Stories/Sport</options>
        </select>
    </div>
</div>
Choice from a list of paths
Figure 8. Choice from a list of paths

sort

Complete sorting mechanism.

Syntax

sort:"{X-PATH};{VALUE}"

Values

Table 15. Supported values
Keyword Example Description

"{X-PATH};{VALUE}"

sort:"ObjectInfo/modified;ND"

See previous example. Note: Quotes are mandatory. If the value contains double quotes, use single quotes instead.

In {x-path};{Value}, value can be:

Table 16. Values
Value Description

A

Ascending

D

Descending

NA

Numeric Ascending

ND

Ascending

Suggested HTML implementations

Free input
<div class="emui-row">
    <div class="emui-title">Sort</div>
    <div class="emui-content">
        <input type="text" class="form-control" data-xvalue="sort" placeholder="Sort" />
    </div>
</div>
Free sort input filter
Figure 9. Free sort filter
Choice from a list of sorting mechanisms
<div class="emui-row">
    <div class="emui-title">Sort</div>
    <div class="emui-content">
        <select data-xvalue="sort" class="form-control">
            <option value="">Default sort</options>
            <option value="ObjectInfo/modified;ND">Modified, DESC</options>
            <option value="ObjectInfo/modified;NA">Modified, ASC</options>
            <option value="ObjectInfo/created;ND">Created, DESC</options>
            <option value="ObjectInfo/created;NA">Created, ASC</options>
        </select>
    </div>
</div>
Sort filter with specific options
Figure 10. Sort filter with specific options

sortby

Simple descending sort according to a parameter in the ObjectInfo.

Syntax

sortby:(VALUE)

Values

Table 17. Supported values
Keyword Example Description

created

sortby:created

Return the objects sorted by creation date, descending.

modified

sortby:modified

Return the objects sorted by modified date, descending.

Suggested HTML implementations

<div class="emui-row">
    <div class="emui-title">Sort by:</div>
    <div class="emui-content">
        <select class="form-control" data-xvalue="sortby">
            <option value="">Default sort</option>
            <option value="Created">Created</option>
            <option value="Modified">Modified</option>
        </select>
    </div>
</div>
Result
Sort by
Figure 11. Sort by

status, workflow

Search objects with a given status ( workflow ).

Syntax

status:(VALUE)

Values

Table 18. Supported values
Keyword Example Description

VALUE

status:NewsFlow/Editing

Any string value (with quotes if there is a space).

Suggested HTML implementations

By adding the data-preload="true" attribute, the select element will be preloaded with all the workflow steps available.

<div class="emui-row">
    <div class="emui-title">Workflow</div>
    <div class="emui-content">
        <select class="form-control" data-xvalue="workflow" data-preload="true"></select>
    </div>
</div>
Result
Workflow filter
Figure 12. Workflow filter

It is also possible to specify the values manually. Be careful in putting a value="" in case no filter should be applied.

<div class="emui-row">
    <div class="emui-title">Workflow</div>
    <div class="emui-content">
        <select class="form-control" data-xvalue="workflow">
            <option value="">Any workflow</option>
            <option value="NewsFlow/Editing">NewsFlow/Editing</option>
            <option value="NewsFlow/For Approval"></option>
        </select>
    </div>
</div>
Result
Workflow filter with specific statuses
Figure 13. Workflow filter with specific statuses

type

Returns only the objects of a given type.

Syntax

type:(TYPE)

Values

Table 19. Supported values
Keyword Example Description

TYPE

type:EOM::Story

Any string value (with quotes if there is a space). Return the objects of specified type.

Suggested HTML implementations

By adding the data-preload="true" attribute, the select element will be preloaded with all the types available.

<div class="emui-row">
    <div class="emui-title">Type</div>
    <div class="emui-content">
        <select class="form-control" data-xvalue="type" data-preload="true"></select>
    </div>
</div>
Result
Filter on type
Figure 14. Filter on type

It is also possible to specify the values manually. Be careful in putting a value="" in case no filter should be applied.

<div class="emui-row">
    <div class="emui-title">Type</div>
    <div class="emui-content">
        <select class="form-control" data-xvalue="type">
            <option value="">Any type</option>
            <option value="EOM::Story">EOM::Story</option>
            <option value="EOM::MediaGallery">EOM::MediaGallery</option>
        </select>
    </div>
</div>
Result
Filter on specified types
Figure 15. Filter on specified types

It is also possible to have a multiple selection of types. REMEMBER to change the data-operator attribute to OR to make it work. data-block-operator should be omitted or "AND".

<div class="emui-row">
    <div class="emui-title">Type</div>
    <div class="emui-content">
        <select class="form-control" data-xvalue="type" data-operator="OR" data-preload="true" multiple data-block-operator="AND"></select>
    </div>
</div>
Result
Filter on type
Figure 16. Filter on type

usageticket

Allow to search within the usage tickets.

Syntax

usageticket:"tp:{type};;c:{creator};;rng:{range}"

Values

Table 20. Supported values
Keyword Example Description

CONTENT

tp:{type};;c:{creator};;rng:{range}

usageticket:"tp:WebPub;c:alessandropiana;rng:20160420220000__20160421215900"

  • Type (tp) is the only mandatory field for the usageticket filter. creator (c) and range (rng) are optional.

  • Range (rng) is in the format YYYYMMDDhhmmss__YYYYMMDDhhmmss

  • Separate the fields with a double ; ( ;; ).

  • If the field values have spaces in it, use a double underscore instead of spaces ( __ )

Suggested HTML implementations

There is no a real suggested HTML implementation. It could be useful to create three different choices for the different fields ( types, creator and range ), and combine them in the filter JS.

user, creator, owner

Search for objects created by a given user

Syntax

user:(USER|myself)

Values

Table 21. Supported values
Keyword Example Description

USER

user:johndoe

Any string value (with quotes if there is a space). Return the objects created by the specified user.

myself

user:myself

Return the objects created by the current user

user, creator, owner keywords are totally equivalent.

Suggested HTML implementations

By adding the data-preload="true" attribute, the select element will be preloaded with all the users available.

<div class="emui-row">
    <div class="emui-title">Owner</div>
    <div class="emui-content">
        <select class="form-control" data-xvalue="owner" data-preload="true"></select>
    </div>
</div>
Result
Owner filter
Figure 17. Owner filter

It is also possible to specify the values manually. Be careful in putting a value="" in case no filter should be applied.

<div class="emui-row">
    <div class="emui-title">Owner</div>
    <div class="emui-content">
        <select class="form-control" data-xvalue="owner">
            <option value="">Any user</option>
            <option value="johndoe">johndoe</option>
            <option value="Kurt">Kurt Cobain</option>
        </select>
    </div>
</div>
Result
Owner filter with specific statuses
Figure 18. Owner filter with specific statuses

userchannel

See channel.

workflow

workfolder

Returns the objects inside a workfolder.

Syntax

workfolder:(VALUE)

Values

Table 22. Supported values
Keyword Example Description

VALUE

Any string value (with quotes if there is a space).

workfolder:"/Globe/Images"

Suggested HTML implementations

Free path input
<div class="emui-row">
    <div class="emui-title">Search in workfolder</div>
    <div class="emui-content">
        <input type="text" class="form-control" data-xvalue="workfolder" placeholder="Path" />
    </div>
</div>
Free path input filter
Figure 19. Free path input filter
Choice from a list of paths
<div class="emui-row">
    <div class="emui-title">Search in workfolder</div>
    <div class="emui-content">
        <select data-xvalue="workfolder" class="form-control">
            <option value="">All paths</options>
            <option value="/Globe/Stories/Politics">/Globe/Stories/Politics</options>
            <option value="/Globe/Stories/Sport">/Globe/Stories/Sport</options>
        </select>
    </div>
</div>
Choice from a list of paths
Figure 20. Choice from a list of paths

How to configure search filters in external folder

Additional search filters may be made available to Swing application by defining one or more nested components in Swing web context in server.xml. (for further details on Tomcat 9.x Resources configuration, please refer to Resources configuration).

This is an example of the external filters configuration.

<Context docBase="com.eidosmedia.webclient.web-app"
    path="/swing" reloadable="false">
    <Resources
        className="org.apache.catalina.webresources.StandardRoot">
        <PreResources
            className="org.apache.catalina.webresources.DirResourceSet"
            base="/methode/meth01/extension/searchfilters" readOnly="true"
            webAppMount="/config/templates/search/filters" />
    </Resources>
</Context>