How can we apply custom filters on Lookups in Freedom UI? I can see that there is some existence of a filtersConfig potential property for the object passed as the first parameter to executeRequest, but cannot find any examples or information on how this should be configured in Academy or on other Community questions. We are trying to use this to associate records to a parent record using the + button on a Freedom UI "detail" list, but we don't want any records already associated with any parent by foreign key to be eligible for association using the lookup, and also have some other conditions to apply based on the child entity. Our environment is currently on 8.1 Quantum.

 

Here is the relevant excerpt from the handler on our form page, without any filters applied and with the non-relevant logic applied in the afterClosed area removed for brevity:

request.$context.executeRequest({
	type: "crt.OpenLookupPageRequest",
	$context: request.$context,
	entitySchemaName: "Order",
	caption: "Select Quotes to associate with the Lead",
	features: {
		select: {
			multiple: true,
			selectAll: false,
			resultType: 'lookupValues'
		},
		create: {
			enabled: false
		}
	},
	afterClosed: async function(selectedItems) {
		// logic here
		return next?.handle(request)
	}
});

 

Like 0

Like

5 comments
Best reply

Hello,

Here is an example of OpenLookupPageRequest with a filtersConfig.

handlers: /**SCHEMA_HANDLERS*/[
			{
				request: "usr.OpenLookupRequest",
				handler: async (request, next) => {
					devkit.HandlerChainService.instance.process({
						type: "crt.OpenLookupPageRequest",
						scopes: [...request.scopes],
						$context: request.$context,
						entitySchemaName: "Contact",
						// caption: 'Responsible',
						schemaName: 'CustomLookupPage',
						itemAttributeName: 'LookupAttribute_2mnilrq',
						// itemsAttributeName: 'Contact_List',
						afterClosed: (result) => {
							alert(result?.displayValue ?? '');
						},
						filtersConfig: {
							filterAttributes: [
								{
									name: 'MyFilter',
									loadOnChange: false
								}
							],
							attributesConfig: {
								MyFilter: {
									value: {
										"items": {
											"29e16d42-36f1-4e04-9029-4321cbb2494d": {
												"filterType": 1,
												"comparisonType": 11,
												"isEnabled": true,
												"trimDateTimeParameterToDate": false,
												"leftExpression": {
													"expressionType": 0,
													"columnPath": "Name"
												},
												"isAggregative": false,
												"dataValueType": 1,
												"rightExpression": {
													"expressionType": 2,
													"parameter": {
														"dataValueType": 1,
														"value": "Super"
													}
												}
											}
										},
										"logicalOperation": 0,
										"isEnabled": true,
										"filterType": 6,
										"rootSchemaName": "Contact"
									}
								}
							}
						}
					});
					return next?.handle(request);
				}
			}
		]/**SCHEMA_HANDLERS*/,

If you don't know how to build a proper filter here is a small tip. On a Freedom UI page add a list with the object you want to filter. In this list add a static filter with a condition you want to apply to a OpenLookupPageRequest and save it. As a result, in the code of this page, you can find the full filter code, all you need to do is to replace "MyFilter" with it.

Hello,

Here is an example of OpenLookupPageRequest with a filtersConfig.

handlers: /**SCHEMA_HANDLERS*/[
			{
				request: "usr.OpenLookupRequest",
				handler: async (request, next) => {
					devkit.HandlerChainService.instance.process({
						type: "crt.OpenLookupPageRequest",
						scopes: [...request.scopes],
						$context: request.$context,
						entitySchemaName: "Contact",
						// caption: 'Responsible',
						schemaName: 'CustomLookupPage',
						itemAttributeName: 'LookupAttribute_2mnilrq',
						// itemsAttributeName: 'Contact_List',
						afterClosed: (result) => {
							alert(result?.displayValue ?? '');
						},
						filtersConfig: {
							filterAttributes: [
								{
									name: 'MyFilter',
									loadOnChange: false
								}
							],
							attributesConfig: {
								MyFilter: {
									value: {
										"items": {
											"29e16d42-36f1-4e04-9029-4321cbb2494d": {
												"filterType": 1,
												"comparisonType": 11,
												"isEnabled": true,
												"trimDateTimeParameterToDate": false,
												"leftExpression": {
													"expressionType": 0,
													"columnPath": "Name"
												},
												"isAggregative": false,
												"dataValueType": 1,
												"rightExpression": {
													"expressionType": 2,
													"parameter": {
														"dataValueType": 1,
														"value": "Super"
													}
												}
											}
										},
										"logicalOperation": 0,
										"isEnabled": true,
										"filterType": 6,
										"rootSchemaName": "Contact"
									}
								}
							}
						}
					});
					return next?.handle(request);
				}
			}
		]/**SCHEMA_HANDLERS*/,

If you don't know how to build a proper filter here is a small tip. On a Freedom UI page add a list with the object you want to filter. In this list add a static filter with a condition you want to apply to a OpenLookupPageRequest and save it. As a result, in the code of this page, you can find the full filter code, all you need to do is to replace "MyFilter" with it.

Question on OpenLookupPageRequest. In an edit scenario, could you pass the already selected options so that they appear already selected in the lookup list?

You can use the option selectionState to predefine selected rows, which will be pre-selected

type: "crt.OpenLookupPageRequest",
	...
	selectionState: {
		type: 'specific',
		selected: [
			'9d06bf9f-eb7a-4849-b83d-cbba994f185d',
			'49ba9a9e-2e28-48cb-b1bc-81b7871acb9d',
		],
	},

 

Dmytro Vovchenko,

 

Those are really useful, are there any other parameters that can be passed to the newly opened lookup page? I'm currently looking for a way to automatically set the initial search value of the lookup window, but I'm sure there are many other undocumented useful parameters like the selectionState that can be passed to a lookup page when opening it. A generic way to pass data into the page would be great!

 

I looked into passing a defaultSearchValue parameter into the request, but it didn't seem to affect the modal lookup.

Harvey Adcock,

 

Hello,

 

Here is all the available documentation we have:

 

Lookup window example:

In order to open the lookup window, you have to use crt.OpenSelectionWindowRequest

/**
 * @publicApi
 */
@CrtRequest({
    type: 'crt.OpenSelectionWindowRequest',
})
export class OpenSelectionWindowRequest extends BaseRequest {
    public itemAttributeName?: string;
    public itemsAttributeName?: string;
    /**
     * @publicApi
     */
    public entitySchemaName?: string;
    /**
     * @publicApi
     */
    public schemaName?: string;
    /**
     * @publicApi
     */
    public filtersConfig?: FiltersConfig;
    /**
     * @publicApi
     */
    public features?: PageLookupFeatures;
    /**
     * @publicApi
     */
    public selectionState?: SelectionState;
    /**
     * @publicApi
     */
    public afterClosed?: (result: SelectionWindowResult) => void;
    /**
     * @publicApi
     */
    public caption?: LocalizableString;
}

Add the following code to your custom handler:

handlers: /**SCHEMA_HANDLERS*/[
			{
				request: "usr.OpenLookupRequest",
				handler: async (request, next) => {
					devkit.HandlerChainService.instance.process({
						type: "crt.OpenSelectionWindowRequest",
						scopes: [...request.scopes],
						$context: request.$context,
						entitySchemaName: "Contact",
						// caption: 'Responsible',
						schemaName: 'CustomLookupPage',
						itemAttributeName: 'LookupAttribute_2mnilrq',
						// itemsAttributeName: 'Contact_List',
						afterClosed: async (result) => {
							if (!result.canceled) {
								const lookupValues = await result.getLookupValues();
								const value = lookupValues[0];
								if (value) {
									alert(value?.displayValue ?? '');
								}
							}
						},
						filtersConfig: {
							filterAttributes: [
								{
									name: 'MyFilter',
									loadOnChange: false
								}
							],
							attributesConfig: {
								MyFilter: {
									value: {
										"items": {
											"29e16d42-36f1-4e04-9029-4321cbb2494d": {
												"filterType": 1,
												"comparisonType": 11,
												"isEnabled": true,
												"trimDateTimeParameterToDate": false,
												"leftExpression": {
													"expressionType": 0,
													"columnPath": "Name"
												},
												"isAggregative": false,
												"dataValueType": 1,
												"rightExpression": {
													"expressionType": 2,
													"parameter": {
														"dataValueType": 1,
														"value": "Super"
													}
												}
											}
										},
										"logicalOperation": 0,
										"isEnabled": true,
										"filterType": 6,
										"rootSchemaName": "Contact"
									}
								}
							}
						}
					});
					return next?.handle(request);
				}
			}
		]/**SCHEMA_HANDLERS*/,

where

 

entitySchemaName - the name of the entity schema whose data is displayed in the lookup window. Optional parameter. If not specified, the data source is taken from the attribute specified in itemAttributeName

 

caption - optional parameter, displayed in the window title. If caption is not specified, the caption is taken from the attribute specified in the itemAttributeName parameter. If itemAttributeName is not specified, then from the entity schema.

 

schemaName - the name of the schema that is displayed in the lookup window. Optional parameter. Default is BaseLookupPageTemplate

 

itemAttributeName - the name of the attribute from which the title is taken, the name of the entity schema and in which the result of the selection in the window will be written. Optional parameter. As a rule, this is the attribute with which the Combobox control is associated.

 

itemsAttributeName - the name of the attribute from which the data source name is taken. Optional parameter.

 

afterClosed - callback function returning the result of the selection in the window. Optional parameter.

 

filtersConfig-  describes the filter to be applied to the data. Optional parameter

 

PageLookupFeatures

 

Additionally, the user can specify additional features for the selection window.

export interface PageLookupFeatures {
    create?: {
        enabled: boolean;                         // false by default
    };
    select: {
        multiple: boolean;                        // false by default
        selectAll: boolean;                       // false by default
    };
    showDeactivatedRecords?: boolean;
}

 

The user should provide the Create option as enabled to display the New button in the selection window (only for the FreedomUI host).

devkit.HandlerChainService.instance.process({
	type: "crt.OpenSelectionWindowRequest",
	scopes: [...request.scopes],
	$context: request.$context,
	....
	"features": {
		"create": {
            "enabled": true;
        }
	}
});

 

The New button in this window works best only in the Freedom UI shell. In the Classic UI, new record will be created, but the selection window will close after saving it without passing the created record selected value. If you want to use this window in the Classic UI, please consider it, or don’t show this button there.

 

SelectionWindowResult  type

export class SelectionWindowResult {
    canceled: boolean; // indicates whether selection window was canceled by user
    filter: FilterMetadata; // Filter 
    async getLookupValues(options?: { pagingConfig: DataSourcePagingConfig }): Promise<LookupValue[]>; // method to get lookup values
}

where DataSourcePagingConfig is 

interface DataSourcePagingConfig {
    rowsOffset: number;
    rowCount: number;
}

example

devkit.HandlerChainService.instance.process({
	type: "crt.OpenSelectionWindowRequest",
	scopes: [...request.scopes],
	$context: request.$context,
	....
	"features": {
		"select": {
            "multiple": true;
        }
	},
	afterClosed: async (selectionWindowResult) => {
		const filter = selectionWindowResult.filter // getting filter
		// or 
		const lookupValues = await selectionWindowResult.getLookupValues(); // getting lookupValues
	}
});

 

Multiselection mode

 

To enable multiselection mode user should add next feature to OpenPageLookupRequest

devkit.HandlerChainService.instance.process({
	type: "crt.OpenSelectionWindowRequest",
	scopes: [...request.scopes],
	$context: request.$context,
	....
	features: {
		select: {
            "multiple": true
        }
	}
});

So afterClosed will look like this 

devkit.HandlerChainService.instance.process({
	type: "crt.OpenSelectionWindowRequest",
	scopes: [...request.scopes],
	$context: request.$context,
	....
	features: {
		select: {
			multiple: true
		}
	},
	afterClosed: async (selectionWindowResult) => {
		const lookupValues = await selectionWindowResult.getLookupValues();
		// do something with lookup values
	}
});

 

Select all


To enable the ability to select all records, you should add the next features to OpenPageLookupRequest.

devkit.HandlerChainService.instance.process({
	type: "crt.OpenSelectionWindowRequest",
	scopes: [...request.scopes],
	$context: request.$context,
	....
	features: {
		select: {
            multiple: true,
            selectAll: true
        }
	}
});

 

Canceled
 

Handling cases when the user presses the cancels Selection window

devkit.HandlerChainService.instance.process({
	type: "crt.OpenSelectionWindowRequest",
	scopes: [...request.scopes],
	$context: request.$context,
	....
	features: {
		select: {
			multiple: true
		}
	},
	afterClosed: (selectionWindowResult) => {
		const canceled = selectionWindowResult.canceled;
		if (canceled) {
			// do some logic when user canceled selection window
		}
	}
});

 

Selecting a special set of values


getLookupValues could be called with paging config where user can specify rowsOffset and rowCount to get a specific list of values

devkit.HandlerChainService.instance.process({
	type: "crt.OpenSelectionWindowRequest",
	scopes: [...request.scopes],
	$context: request.$context,
	....
	features: {
		select: {
			multiple: true
		}
	},
	afterClosed: async (selectionWindowResult) => {
		const pagingConfig = {
			rowsOffset: 2,
			rowCount: 2
		}
		const lookupValues = await selectionWindowResult.getLookupValues({ pagingConfig });
		// do something with received lookup values
	}
});

Example of iterating through lookupValues. Getting pair of 2 lookupValues with step of 2

devkit.HandlerChainService.instance.process({
	type: "crt.OpenSelectionWindowRequest",
	scopes: [...request.scopes],
	$context: request.$context,
	....
	features: {
		select: {
			multiple: true
		}
	},
	afterClosed: async (selectionWindowResult) => {
		let rowsOffset = 0;
        const rowCount = 2;
        const pagingConfig = { rowsOffset, rowCount };
        let lookupValues = await selectionWindowResult.getLookupValues({ pagingConfig });
        while (lookupValues.length) {
            /*
              fn(lookupValues); // do something with received lookupValues pair
            */
            rowsOffset += 2;
            lookupValues = await selectionWindowResult.getLookupValues({ pagingConfig: { rowsOffset, rowCount }});
        }
        if (!lookupValues.length) {
            /*
              Do some logic here on end of list - when there are no more lookupValues
            */
        }
	}
});

 

Selection state


and SelectionState is:

{
    type: 'specific';
    selected: unknown[]; // array of id's
}

 

So user can predefine selected rows, which will be pre-selected

devkit.HandlerChainService.instance.process({
	type: "crt.OpenSelectionWindowRequest",
	...
	selectionState: {
		type: 'specific',
		selected: [
			'9d06bf9f-eb7a-4849-b83d-cbba994f185d',
			'49ba9a9e-2e28-48cb-b1bc-81b7871acb9d',
		],
	},
});

 

showDeactivatedRecords


When set to true, deactivated entries of the object are shown.

 

This is all the information that we have on the lookup page handling cases, I hope it helps.

Show all comments

I'm getting below error while installing "SMPageRefresh",

The INSERT statement conflicted with the FOREIGN KEY constraint "FKYru8eiQRBeFoEfawvRwKSlCy2o". The conflict occurred in database "SaEENU_5379138_0529", table "dbo.SysCulture", column 'Id'.

Kindly let me know how to proceed further.  

Like 0

Like

1 comments

Hello,

 

Please contact the developer of this connector directly at support@solutionsmetrix.com for further assistance with this matter.

 

Best regards,

Yuliya

Show all comments

We are finding that changes made to text colors on home page labels does not appear to change after saving and viewing in the UI.  The only color that shows is black or white.  This is on the latest version of creatio.  anyone else seeing this issue?  Support ticket has been entered but just curious.

Like 0

Like

1 comments

Hi Chris!

 

We noticed that you have sent us a request on our support email. 

We have provided you with the answer in that request.

 

The main cause is overrides in specificity of custom CSS styles.

 

Have a nice day!

Alina

Show all comments

Hi,

I have a problem with the new open Activity in an already created Lead.

I create a new lead, I add an activity on that lead and after that, I change the owner of the Lead. Unfortunately the activity owner changes too.

I want to know if it's a core functionality that changes the owner of the activity after I change the owner of it's Lead and if so, how can I deactivate it?

Thank you,

 

Rares

Like 0

Like

8 comments

Hi Ivan,

 

I think, this can be switched off with feature "ChangeEntityActivitiesAndProcessOwner"



Kind regards,

Vladimir

Vladimir Sokolov,

Hi! 

Thank you Vladimir for your response. 

I changed the state into 0 and nothing happens. I changed the code in "ActivityPageV2" and the I have the same result as before. 

Should I make other changes? 

 

Thank you, 

Rares

Could you please check if feature is switched off for every role and cache is cleared?



There is nothing to change in the Page, this functinality is implemented in the EventListener



And it would be nice if Creatio describes all implemented feature in the field 'Description'...



Kind regards,

Vladimir

Hi!

I have an older version of Creatio (8.0.0.5476) and the Feature Toggle doesn't  exists. Is there any possibility to change that from somewhere else?

 

Best regards, 

Rares 

Vladimir Sokolov,

Ivan Rares Marian,

You can find them in database and update:

Select * from "AdminUnitFeatureState" Where "FeatureId" = (Select "Id" from "Feature"

Where "Name" = 'ChangeEntityActivitiesAndProcessOwner')

 

Vladimir Sokolov,

 

Hi,

I checked and in the database the FeatureState is 1 for both of them.

What should I try now?

Best regards, 

Rares 

Update it with 0

Show all comments

Hello, could anyone help how to add Print button on freedom UI page for MS word reports that we have

Like 0

Like

2 comments

Hello!

 

Unfortunately, the printables section in Freedom UI is not available now, but it will be available in the 8.1.1 version.



As for now, as a workaround, you can try to generate reports through the business process. We provided the following articles below.



Creating a business process: https://academy.creatio.com/docs/developer/integrations_and_api/business_process_service/overview?_gl=1



I am also sending you a link to a post in our community where you can also read the information that may help you: https://community.creatio.com/questions/generate-word-printable-outside

 

Best regards, 

Maria

Unfortunately, there's no exact date for this update yet. Our team is still working on the development of this update.

 

Best regards, 

Maria

Show all comments

Hi,

I am able to create the feed entry, but what I would like to include is the @user function. Simply using the Formula in the message and constructing the text in the following way does not work.

"Hey @" + [#variable for contact] 

 

Does anyone know a way to make this active notification work in a business process to the Feed message?

Like 0

Like

3 comments

anyone?

 

I really want to be able to @someone in a feed message created in a business process and I am sure others would love to be able to do this too.

Mark Roberts,



Probably you have to add record to the SocialMention object as well, as there are stored all @'s

 

Kind regards,

Vladimir

Show all comments

Hi all,

 

How would one add a boolean type static filter to a section (similar to the Active flag in the Process Library)?

 





I have a field called UsrActive in my section and I'd like to have this filter applied by default.

 

Nb. I'm not currently using Freedom sections.

Like 0

Like

1 comments
Best reply

Hello,

 

In order to implement such logic in the Classic UI additional development is needed. You may refer to the below post for an example of similar implementation:

https://community.creatio.com/questions/please-help-how-add-custom-filt…

 

Best regards,

Anastasiia

Hello,

 

In order to implement such logic in the Classic UI additional development is needed. You may refer to the below post for an example of similar implementation:

https://community.creatio.com/questions/please-help-how-add-custom-filt…

 

Best regards,

Anastasiia

Show all comments

Hello all,

 

Once we log into the Creatio, there is no name of the current user on the page.

I need to show the current user's name at the top of the page.

Does anyone know how to do it?

 

Thank you.

David.

 

Like 0

Like

2 comments
Best reply

Hi David,

 

User name of the current user can be reviewed in the user profile located at the top of the page:

and

If you still need this on the top of the page and the app version you have is greater than 7.18.0 you need to enable AllowCreateAngularSchema system feature for all employees, override MainShell, add container and string field inside it and create a hanler that will read Terrasoft.SysValue.CURRENT_USER.displayValue property and set this value to the string field.

Hi David,

 

User name of the current user can be reviewed in the user profile located at the top of the page:

and

If you still need this on the top of the page and the app version you have is greater than 7.18.0 you need to enable AllowCreateAngularSchema system feature for all employees, override MainShell, add container and string field inside it and create a hanler that will read Terrasoft.SysValue.CURRENT_USER.displayValue property and set this value to the string field.

Oleg Drobina,

Thank you, it works.

Show all comments

Hi community, 



I have created a detail and now I wanted to convert the detail into an editable list. The option that is provided in the detail setup is disabled. Then I added the required code in the client module. The detail has been converted to editable list but when I click on the record it is throwing the following error. 

The details regarding the issue are attached below.

Could you let me know how can I convert an already existing detail to an editable one?





Thanks in advance

Goparna Nasina.

Like 0

Like

1 comments

Hello,

 

Could you please provide the code you added and specify where exactly it was added?

 

Best regards,

Yuliya

Show all comments

Hello all,

 

I have a page detail that contains item transfer information.

Every item has 2 types of units (uom), big unit and small unit. Every unit has its own conversion to each other.

So, every time the user enters the "ship quantity", I want the system to calculate the big unit and the small unit, and then update it to the UI.

The "ship quantity" uses either the big unit or the small unit.

 

Currently I use a business process to calculate the big and small quantity. 

So, every time the user enters the "ship quantity", a request will be sent to call the business process. All of this is done in the detail page.

Then, once the business process has done the calculation, it sends the message to the UI, which will be captured by the UI script and shows it to the screen. 

The problem is after the "Ship quantity" of the first row is entered, the user clicks on the second row, the first row's big and small quantities are not updated.

Below is the snippet of my code that updating the row.

body is the return from the business process that the system called earlier.

How to solve this problem?

I wish Creatio has "row lost focus" event that might can help to solve this problem.

 

Any ideas will be appreciated.

 

Thanks,

David.

Like 0

Like

1 comments

Hello David,

Most likely your data isn't updating because it wasn't set. this.getGridData will not work on the edit page. I made the logic on the Order page, to do such:

Replace the OrderProductPageV2 module and write code there instead of a business process. Put the business process handler in the editing page module. Add the required parameters to BP and use them later in your custom module by get/set:

var currentPrice = this.get(“Price”);
this.set(“Price”, “some value”)

 

Show all comments