Expression Editor


Source: oroform/js/expression-editor-util.

Implements core autocomplete and validate functionality for expressions.

You can configure allowed expression syntax by options.

Contains the following public functions:

  • validate - Validates expression syntax
  • getAutocompleteData - Builds autocomplete data by expression and cursor position
  • updateAutocompleteItem - Inserts a new item into autocomplete data
  • updateDataSourceValue - Sets a new data source value into autocomplete data


Source: oroform/js/app/views/expression-editor-view.

Used ExpressionEditorUtil and typeahead widget to provide autocomplete and validate the UI for text fields.

How to Use

Use ExpressionEditorView for text fields:

{{ form_widget(form.expression, {'attr': {
    'data-page-component-module': 'oroui/js/app/components/view-component',
    'data-page-component-options': initializeOptions|merge({
        view: 'oroform/js/app/views/expression-editor-view',
}}) }}

Use ExpressionEditorUtil for form validation:

var ExpressionEditorUtil = require('oroform/js/expression-editor-util');
var expressionEditorUtil = new ExpressionEditorUtil(initializeOptions);


For validation, we transform expression into safe native JS code and execute it.

For transformation, we use ExpressionEditorUtil.itemToNativeJS property and a list of allowed and not allowed words/symbols, see ExpressionEditorUtil.regex.nativeReplaceAllowedBeforeTest and ExpressionEditorUtil.regex.nativeFindNotAllowed.


Both util and view expect same initialize options. The most important of them are:

  • Operations groups, a list of all supported operations. Default value:

    operations: {
        math: ['+', '-', '%', '*', '/'],
        bool: ['and', 'or'],
        equality: ['==', '!='],
        compare: ['>', '<', '<=', '>='],
        inclusion: ['in', 'not in'],
        like: ['matches']
  • Allowed operations groups. Default value:

    allowedOperations: ['math', 'bool', 'equality', 'compare', 'inclusion', 'like']
  • Entities and fields that you can use. Does not have a default value, you should specify it for each view or util. Format:

    entities: {
        root_entities: {
            "Oro\\Bundle\\ProductBundle\\Entity\\Product": "product",
            "Oro\\Bundle\\PricingBundle\\Entity\\PriceList": "pricelist"
        fields_data: {
            "Oro\\Bundle\\ProductBundle\\Entity\\Product": {
                id: {
                    label: "Id",
                    type: "integer"
                category: {
                    label: "Category",
                    type: "relation",
                    relation_alias: "Oro\\Bundle\\CatalogBundle\\Entity\\Category"
            "Oro\\Bundle\\CatalogBundle\\Entity\\Category": {
                id: {
                    label: "Id",
                    type: "integer"
            "Oro\\Bundle\\PricingBundle\\Entity\\PriceList": {...}
  • Limit of nested entities level. For example, if you set this option to 1, category will be excluded from the allowed items list. Default value:

    itemLevelLimit: 3
  • Widgets to choose specific entities. This widget will be rendered when you type pricelist. Format:

    dataSource: {
        pricelist: "<select><option value='1'>Option 1</option><option value='2'>Option 2</option><option value='3'>Option 3</option></select>"