Hi Community,

 

We are trying to create a filter for this detail, that will use two conditions (one for each column) and a logical operator of “OR”. So basically, we only want the records that have the main record id on one of these columns (Contrato or Contrato Umbrella).

 

 

To achieve this, we first tried to add the filter using the FreedomUI Page Designer. However, the filter does not work with the logical operator “OR”.

 

 

So we needed to add it manually, through code. By following this post https://community.creatio.com/questions/detail-filter-freedom-ui. But that didn’t work.

 

 

An alternative was to add the filter in the viewModelConfigDiff section, but we don’t know how can we make the value dynamic.

 

 

Could you please help us find a solution to this problem?

 

Thank you.

Like 3

Like

1 comments

Hello Pedro,

Please review one of the community questions to find the example of Terrasoft.LogicalOperatorType.OR usage.

Additionally here is an explanation of how filtration on Detail work for FreedomUI. 

Case description:
On Contacts page there is a Job experience detail with listed companies where the person worked. Our goal is to show only those departments in the department field that are specified for chosen employer (Account object). So, for this case, Alpha Business has only 2 departments listed in the Departments detail. We only want to see those 2 departments when choosing a department for this account on Job experience detail on Contact page. 

For filtering we basically need just 2 base handlers to be triggered:

  1. crt.DataGridActivateRowBusinessRulesRequest – triggered when we click on an existing detail row or add a new one.
  2. crt.HandleViewModelAttributeChangeRequest – triggered when we change a value of fields.

We also need to create our own handler which we can name usr.ApplyDepartmentFilter. This one would find the currently active row of our detail to have access to its manipulations. After that, we check if account field is filled in and if yes, we create a filter for the Department field. To apply it, we need to use setValue method by targeting filterAttributeName that can be created using the formula: 
"{detailName}DS_{targetFieldName}_List_BusinessRule_Filter".
After that, it is important to use markAsPristine method to make sure that the attribute is applied silently, without forcing us to save the row.

As for crt.DataGridActivateRowBusinessRulesRequest, here we just need to filter it by request.dataGridViewElementName === "CareerList" to target only the detail needed and then call the execution of usr.ApplyDepartmentFilter request that was added earlier.

In crt.HandleViewModelAttributeChangeRequest handler we need to cover the situation when the Employer (Account) field is changed to update the filtration for Department field. First of all, we check if request.attributeName === "CareerList". After that we select the active row and get control over Account field. We check if it’s changed by using account?.dirty property and also if it has value with account?.value?.value, because we would want to filter Department field only in case the Employer is filled in. If those 2 conditions are met, we use markAsPristine method for the account field attribute. We use this one here because it will allow us to handle the subsequent changes of the Employer field. Without it, the field will remain dirty until we save the row. Eventually, we need to set value of the Department field to null using: row?.getAttributeControl(attributeName + "DS_Department").setValue(null, {silent: true});
After that, the usr.ApplyDepartmentFilter handler can be executed to apply the filtration of Department field by Employer.

Show all comments

Hello creatio community,

 

I am trying to apply a filter into cases mini page which is developed using freedom ui screens. Code as below:

{
	request: "crt.LoadDataRequest",
	handler: async (request, next) => {
 
		if(request.dataSourceName == "CaseDS_OPCaseType_4943d10_List_DS") {
			const caseType = await request.$context.CaseDS_OPCaseType_4943d10;
 
			var moduleTypesIds = await OPPermissionFunctionsSsp.getModuleTypes();
 
			const filter = new sdk.FilterGroup();
			if(moduleTypesIds.length > 0){
				filter.logicalOperation = sdk.LogicalOperatorType.Or;		
				for (let i = 0; i < moduleTypesIds.length; i++) {
					await filter.addSchemaColumnFilterWithParameter(sdk.ComparisonType.Equal, "Id", moduleTypesIds[i].value);
				}
			}
			else{
				await filter.addSchemaColumnFilterWithParameter(sdk.ComparisonType.Equal, "OPCode", '');
			}
 
			const newFilter = Object.assign({}, filter);
			newFilter.items = filter.items;
 
			request.parameters.push({
				type: "filter",
				value: newFilter
			});
		}
		return await next?.handle(request);
	}
}

 

The filter newFilter shows the right filter condition. I also used sql profiler and it returned the correct values. The issue here is that the CaseDS_OPCaseType_4943d10_List_DS lookup its not showing any value and does not apply the developed filter.

 

This issue happens only in the mini page. I have used this approach in freedom ui form pages and it works fine. Is there something I'm missing?

 

Kind regards

Like 0

Like

2 comments

I assume this is a dropdown lookup and not a lookup that opens the Select dialog? 

I just double-checked and I do have similar code to filter a dropdown on a Freedom UI mini page/dialog and it is working. I don't see anything that looks incorrect in the code you posted - just wanted to confirm that it does work on mini pages (at least in my case it is)

Show all comments

Hello 
It 's possible to add business process buton on Mobile App Freedom Ui in section , or section page.

 

Thank you 

Like 0

Like

1 comments

Hello Safa,

Unfortunately, there is no no-code way to add the custom button. We've already registered the suggestion for the R&D team.

 

Meanwhile, this article explains how to create a custom button. Please follow the release updates to find out when SDK for Mobile will be implemented.

Show all comments

Is it possible to specify mask IDs when showing & hiding body masks while data loads? I'm asking as it seems like my body mask is being hidden by some other process before the process I want the mask to show for has completed, so it grants the user the ability to control the page before it's ready.

 

What I was thinking is that if the body mask was given some ID when shown using showBodyMask, only a hideBodyMask specifying that same ID would hide the body mask - any others doing the same may make their own body mask hidden, but if any of them still remained, you would still see the loading spinner. For some reason I seem to remember this being possible in Classic UI, but I can't remember exactly or find the examples.

Like 0

Like

3 comments
Best reply

It was possible to get the mask Id in classic (it is returned from MaskHelper.ShowBodyMask()), but I don't believe that had any impact on something else not hiding the mask. As far as I am aware, that was only used to get the mask so you could display or change the message (the Freedom UI mask doesn't have a message, only the spinner)

It was possible to get the mask Id in classic (it is returned from MaskHelper.ShowBodyMask()), but I don't believe that had any impact on something else not hiding the mask. As far as I am aware, that was only used to get the mask so you could display or change the message (the Freedom UI mask doesn't have a message, only the spinner)

Makes sense, must have been mis-remembering then, cheers Ryan. Would be nice to be able to show & hide specific body masks, as sometimes there will be multiple sets of data loading in in parallel, with no guarantees of which will finish first/last.

Hello,
Your idea has been registered to our R&D team, thank you for providing us with new ways to improve.

Show all comments

Hi everyone,

Is it possible to change the thumbnail image on the attachment grid to a custom image?


Regards,

Ramya

Like 0

Like

1 comments

Hello Ramya,

Unfortunately, it's impossible to change the image mentioned above.

We've registered the suggestion to the responsible R&D team.

Show all comments

Hello Community,

We have created a button in Leads_FormPage that opens AddTaskMiniPage

Code in Leads_FormPage that opens the AddTaskMiniPage

  {
        request: "usr.OpenTaskModalPageRequest",
        handler: async (request, next) => {
            const handlerChain = sdk.HandlerChainService.instance;
            await handlerChain.process({
                type: 'crt.OpenPageRequest',
                schemaName: 'AddTaskMiniPage',
                $context: request.$context,
                scopes: [...request.scopes]
            });
            return next?.handle(request);
        }
    }		,

 

Our end goal: We want that upon the Activity is created (Save button clicked in AddTaskMiniPage) the value of 'Start' field in AddTaskMiniPage, is copied to another Date field in the Leads_FormPage.

How can this be acheived?

Regards

Sasor

Like 0

Like

3 comments

Hello Sasori,

You can try using BP for this case. For example, when you save a record in a mini page, you also run a business process that will update a value in your lead record. You pass date value to the BP and set (update) relevant field in the lead record. 
 

An easy way to accomplish this is to just use a process with a signal of Activity added with Type=Task, Category=To do, Lead is filled in. Then update the lead with the date. If you have live data updates enabled for the Lead object you'll even see the screen refresh with the value. 

Ryan

Ryan Farley,

Thank you for your input! However, the challenge with this approach is that there might be multiple activities associated with a single Lead that have this specific configuration (Type = Task, Category = To Do, Lead is filled in).

Would it be possible to handle this scenario directly via the Frontend instead?

Looking forward to your thoughts!

Show all comments

Hi Creatio Community,

 

I am developing a client side filter for a lookup in a section page (Freedom UI). I want to reload (re-filter) the lookup when the stage of the current record is updated (when GlbReloadEntityPage message is received).

Base logic for lookup loading:

{
	request: "crt.LoadDataRequest",
	handler: async (request, next) => {
		if(request.dataSourceName == "PDS_LookupCol") {
 
			request = await ModFunctions.filterAssignTo(request);
		}
		return await next?.handle(request);
	}
}

Reload function (Re-triggered ModFunctions.filterAssignTo(request);)

{
	request: "crt.HandleViewModelInitRequest",
	handler: async (request, next) => {
 
		request.$context.ServerMessageReceivedFunc = async function(event, message) {
			if (message.Header.Sender === "GlbReloadEntityPage") {
				await OPGlbReloadEntity.refreshScreen(request, message);
				ModFunctions.filterAssignTo(request);
			}
		};
		Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE, (await request.$context.ServerMessageReceivedFunc), request.$context);
		return next?.handle(request);
	}
},

Filtering function 

		filterAssignTo: async function(request){
		    .... Custom logic .......
			const newFilter = Object.assign({}, filter);				
			newFilter.items = filter.items;
 
			if(request.parameters){
				request.parameters.push({
					type: "filter",
					value: newFilter
				});
			}
			return request;
		},

Even if the function is triggered when "GlbReloadEntityPage" is called the lookup is not reloaded with the new filtering rules. 

How can i reload lookup options from freedom ui client side?

 

 

Like 0

Like

2 comments

Any updates about this topic?

Hello,
Try to reload the data using the following code:

const handlerChain = sdk.HandlerChainService.instance;
await handlerChain.process({
      type: 'crt.LoadDataRequest',
      $context: request.$context,
      config: {
             loadType: 'reload'
      },
      dataSourceName: '{YOUR LOOKUP DATA SOURCE}'
});

Show all comments

Hi, folks. By default, custom angular components have no setting UI panel, as on screen. I haven't found any info in docs, so maybe here somebody knows how to add user-friendly way to set up component?

Like 0

Like

2 comments

Hello,
​​​​​​​
Unfortunately, for now, the system does not support such no-code option. However, already informed our developers about this option, and they will work on this feature in future versions. 

Thank you for helping us improve the system!


Best regards,
Ivan

Ivan Savenko,

ok, thx. Maybe there is some way to detect when page opened in configuration mode?

Show all comments

Today I saw in Creatio 8.2 something long awaited to be available in Freedom, the rule that allows you to designate a formula to a field.

 

But :-( when trying to designate a formula to a field, it doesn't allow me to do so and apparently what I saw is ‘on hard’ and it is not possible to add this element to our business rules yet.

 

I saw it in the OrderProduct object to calculate the total of an order line, you can change the formula, but not add a new one, because the ‘Set up formula’ element is not accessible.

Does anyone know how to access ‘Set values’ using formula?

 

Thanks

Julio

Like 3

Like

3 comments

Hello, some feedback regarding this question?

 

Thanks

Hello, 

 

Thank you for reaching out.

 

This functionality is still in development, so access to it will only be available after the official release, which is currently planned for version 8.2.2.

Sergii Zhmurko,

Thanks for confirming that we will have this feature soon! :-)

Show all comments

Is there a handler used when loading a List element for the first time or when reloading the list, including after changing quick filters? The crt.LoadDataRequest handler appears to only be called when reloading the list or loading in additional records via the infinite scroll mechanic, but not on the first load of the data or when reloading the data after quick filters are changed, so it does not fit the need.

 

What I'm looking to do is to intercept the initial loading of the data for the list to perform some async task, and once that async task has been completed allow the load to resume as usual. This should be triggered when the page first loads the list in, and whenever the user clicks to reload the list manually or changes quick filters that change the list data, but shouldn't be triggered on the infinite scroll.

Like 1

Like

4 comments

Hello,
 

The initial data loading request 'crt.LoadDataRequest' was not included in this step because it’s part of the system's core loading process, ensuring that essential page elements are set up first.

 On subsequent loads, the system publishes 'crt.LoadDataRequest' where users can apply their customizations.
 

Currently, there’s no default handler to directly intercept the system’s initial load, but there are other options for customization depending on the user’s needs.
 

Additional options include:
 

1) System "crt.HandleViewModelInitRequest" on view model initialization.

2) A change request on view model attribute change, more details on this approach below:

! Warning: Theoretically, this approach could cause slower performance when working with the card, as it increases the total number of handler calls (the approach will trigger on every list change: loading, reloading, sorting change, column list change, and column value change).

 

To use this approach, add a change marker to the appropriate DataGrid attribute (example below):


T
hen, add a handler to process the usr.MyRequest in the handlers, similar to how it's done for crt.LoadDataRequest and crt.DataGridCreateItemRequest.
 

As a result, your custom logic will execute when a new column is added, or when a column is deleted, and for other list changes.
 

Hope this helps, and thank you for reaching out!

Hi Pavlo, thank you for the detailed response! I'm sure that functionality will come in handy.

 

Unfortunately, for our use case, we need to perform an action before the data is fetched for the reload, whereas this change triggers only after the data has already been fetched from the database to reload the list. Is there anything that would fire in a similar way but before the data is requested from the server? LoadDataRequest does this, but has the drawbacks of being called only in certain circumstances.

 

Is there any documentation on the event handler "call stack"? This would be really useful, knowing that, for example, when a user clicks the reload button, first handler X is called to do some action, then handler crt.LoadDataRequest is called to handle the outbound data call to the servers, then the data is sent to the user's browser, then handler Y is called to do some action, then handlers that are associated with the change property of viewModelConfig are called when updating the data stored in the List, etc.

 

Many thanks,

Harvey

Harvey Adcock,

Hello,

Thank you for the additional clarification. Unfortunately, at this time, this option is not available.
 

I have created a task for the development team to implement such a handler in the system.
 

Thank you for helping us improve our product.

Best regards,
Pavlo

Hi Pavlo, thanks - I think we really need some more consistency in what triggers handlers and what doesn't. Performance implications of overriding certain handlers is something for the developers to consider (ideally armed with documentation on any things to look out for - the current info on request handlers in the Academy is incredibly limited) and not really something that should be prevented from being done entirely. Why even have the ability to override LoadDataRequest when one of the main times it should be called (first loading data for a List) it doesn't even fire? Developers just end up having to do workarounds that are even worse for performance, such as triggering a reload of the data from code, so the data gets requested twice.

 

There are so many page events which would've previously in Classic UI triggered something in the page code that developers could override as needed, but now it's just flipping a coin to find out if the event you need to capture and handle in some custom way is possible to be overridden or not.

Show all comments