Hello Community,

 

    I want to display Process Execution custom message on the UI while process in running status. 
    
    How can I display this message using a popup, similar to the one shown in the image below?

 

Like 0

Like

1 comments
Best reply

If you want to display toast messages from a process, you'll need to (1) have a script task in the process that sends the message to the UI and (2) code on the front end that receives the message and displays the toast message. 

For sending the messasge from the process to the UI, see https://customerfx.com/article/sending-a-message-from-server-side-c-to-client-side-javascript-in-bpmonline/

For the toast you can see that here https://customerfx.com/article/displaying-toast-message-popups-from-creatio-freedom-ui-pages/

Ryan

If you want to display toast messages from a process, you'll need to (1) have a script task in the process that sends the message to the UI and (2) code on the front end that receives the message and displays the toast message. 

For sending the messasge from the process to the UI, see https://customerfx.com/article/sending-a-message-from-server-side-c-to-client-side-javascript-in-bpmonline/

For the toast you can see that here https://customerfx.com/article/displaying-toast-message-popups-from-creatio-freedom-ui-pages/

Ryan

Show all comments

Hello Creatio Community,

 

I am currently following Responding to an Change Event When a Field is Changed on a Creatio Freedom UI Page to auto-save the record when a number field is modified.

 

While the auto-save feature works, I’ve encountered an issue when filling in the number field. If I input more than two digits, the system interprets this as multiple changes (e.g., entering "125" is seen as three separate changes: "1", "12", and "125"). This triggers the auto-save and refresh process repeatedly, lasting around 30 seconds.

 

As a result, instead of saving "125", it starts saving and refreshing before I finish entering the complete value.

 

Is there a way to resolve this issue to prevent it from auto-saving prematurely while I'm still entering data?

 

Below is the script I am using for reference. Any guidance or suggestions would be greatly appreciated.

 

Thank you in advance!

 

Best regards,
Jin

Like 1

Like

1 comments

The best option in this case is to make a saving after losing focus from the input. To implement it, you may use the blurred event on the input and add a custom handler, in which you can save the card.

Best regards,

Anhelina!

Show all comments

Hello Community,

 

                  I’ve built a custom page in Freedom UI to display my data in both List View and Calendar View. I implemented the logic in `SCHEMA_HANDLERS` and used `crt.LoadDataRequest` to toggle between the views. The logic works fine when switching to Calendar View for the first time.

 

                              

                              

Issue: 
1] When switching from Calendar View to List View and then back to Calendar View, the data disappears.

I have to refresh the page to make the data reappear in the Calendar.

 

Regards,

Ajay Kuthe

 

 

Like 0

Like

3 comments

Hello,

 

Please describe in detail how exactly this was implemented and provide screenshots of this button's settings.

Mira Dmitruk,

 

I used the 'Refresh data' action to trigger the 'crt.LoadDataRequest' and control the visibility of elements to switch between views (Calender and List).

Button Config

#Code Logic in Handler

handlers: /**SCHEMA_HANDLERS*/[{
    request: "crt.LoadDataRequest",
    handler: async (request, next) => {

 

// Check if the data source name is "ListOrCalenderView"
if (request.dataSourceName === "ListOrCalenderView") {

   // Retrieve the current view mode (Calendar or List)
   const IsCalenderView = await request.$context.IsCalenderView;

   // If the current view is not Calendar (i.e., it's List View)
   if (IsCalenderView === false) {
       // Set the Button caption to "List View"
       request.$context.ListOrCalenderView_caption = "List View";
       request.$context.IsCalenderView = true;
 // Set the ListView flag to false since we are now in Calendar view
       request.$context.IsListView = false;

   } else {
  // If the current view is Calendar, switch to List View
  request.$context.ListOrCalenderView_caption = "Calender View";   request.$context.IsCalenderView = false;
  request.$context.IsListView = true;

 }

}

 

Regards,

Ajay K
 

Mira Dmitruk,

Do you have any alternative solutions besides switching between List and Calendar views?

Show all comments

Dear colleagues,

 

In a Freedom ListPage, I need to process all the records that a user selects AND REPORT THE RESULTS AT THE END.

 

I'm having trouble figuring out how to approach this task. Currently, as I understand it, we call a process with the ID of the record to be processed.

 

Is there a way to know when all the selected records have been processed and know which ones?

 

I'm trying to implement a temporary table to insert the IDs of the selected records, but for this, I need to have a unique ID in that temporary table so that if there are multiple users doing the same thing, the current user's records are not mixed up. To do this, I've edited the code of the page where the service call is made to pass a second parameter to the process, an ID that I need to generate, but the generated ID is always the same "00000000-0000-0000-0000-000000000000":

			"parameterMappings": {
				"NotaCreditoID": "Id",
				"ProcesoID": Terrasoft.utils.generateGUID()
			},

 

What am I doing wrong with this approach?

 

Here is an excerpt of the modified code:

 

define("NdosNotasCredyDeb_ListPage", /**SCHEMA_DEPS*/["@creatio-devkit/common"]/**SCHEMA_DEPS*/, function/**SCHEMA_ARGS*/(sdk)/**SCHEMA_ARGS*/ {

 

"operation": "insert",
"name": "Button_ft2cncy",
"values": {
	"type": "crt.Button",
	"caption": "#ResourceString(Button_ft2cncy_caption)#",
	"color": "default",
	"disabled": false,
	"size": "large",
	"iconPosition": "only-text",
	"visible": true,
	"clicked": {
		"request": "crt.RunBusinessProcessRequest",
		"params": {
			"processName": "NdosLiberaDescartaNC_CC",
			"processRunType": "ForTheSelectedRecords",
			"showNotification": true,
			"dataSourceName": "PDS",
			"parameterMappings": {
				"NotaCreditoID": "Id",
				"ProcesoID": Terrasoft.utils.generateGUID()
			},
			"filters": "$Items | crt.ToCollectionFilters : 'Items' : $DataTable_SelectionState | crt.SkipIfSelectionEmpty : $DataTable_SelectionState",
			"sorting": "$ItemsSorting",
			"selectionStateAttributeName": "DataTable_SelectionState"
		}
	},
	"clickMode": "default"
},

 

On the other hand, has anyone done this in any other way? How?

 

Thank you very much

 

Julio

Like 0

Like

4 comments
Best reply

Hi Julio, 

As of Creatio 8.1.3 you can pass multiple records into a process using a collection parameter. This executes a single process for the collection of selected records. See an example in this article: https://customerfx.com/article/launching-a-process-for-multiple-records-in-a-creatio-list/

Ryan

I'm also tried sdk.generateGuid(), I test it on the console and returns a Guid, but for some reason the parameters is not delivered to the process, what's wrong?

Hi Julio, 

As of Creatio 8.1.3 you can pass multiple records into a process using a collection parameter. This executes a single process for the collection of selected records. See an example in this article: https://customerfx.com/article/launching-a-process-for-multiple-records-in-a-creatio-list/

Ryan

Ryan Farley,

Thanks Ryan,

 

I know and I use them, the problem is the process ran for each record individually and if I need to detect when it processes all selected records, generate a report like "Selected records xxx, processed records yyy" and actually this is not possible 

 

At least I don't know how to do this.

 

Thanks again

 

Julio

Thanks Ryan, your article solves my problem, great job as usual

 

Regards

Julio

Show all comments

Hello community,

I'm experiencing a problem with translations in Freedom UI.

I've a page with widget inside, the label specified in different languages are lost when I deploy the package on another instance.

How can I solve this problem?

 

thank you

Like 0

Like

2 comments

Hi Stefano,

 

We've had many problems with translation to PT_PT  in version  8.1.4, 

upgrading the system to 8.1.5 has solved the issues

Rgds,

Luis

thank you for your feedback!

 

Show all comments

How do I edit this page? For example, I want to add a column that will be displayed on general information.

Like 0

Like

1 comments

Hello Anjar,

Unfortunately, it's impossible to edit the account relationship page.

We've registered the new idea to our R&D team. 

Thank you!

Show all comments

Hi, all senior mentors, 

 

    I'd like to use the system setting for maintaining order gross profit %, however, when I add one new system setting, I found the decimal value with only  two decimal places, which is 0.01, I can't not use 0.015. please see the attachment.

   Any idea how to solve it? please help.

Like 0

Like

2 comments

Believe the column 'FloatValue'  is located in the 'System setting value' object 

Hello! 

Thank you for your question. 

Unfortunately, at the database level, there is a limit of two characters after the dot.

We appreciate your input and will record this suggestion as an idea for consideration.

Alternatively, if you need to use this value in a business process, you can programmatically designate the type as "Text" and convert the string to a decimal format.

Show all comments

Hello. I need to create a QuickFilter on a Freedom UI Page whose value will change dynamically. I found a post https://customerfx.com/article/using-custom-attributes-on-a-creatio-fre… so I try to use the attribute but it does not work. Could you help me please?

{
    "filterType": 1,
    "comparisonType": 3,
    "isEnabled": true,
    "trimDateTimeParameterToDate": false,
    "leftExpression": {
        "expressionType": 0,
        "columnPath": "MyColumn"
    },
    "isAggregative": false,
    "dataValueType": 1,
    "rightExpression": {
        "expressionType": 2,
        "parameter": {
            "dataValueType": 1,
            "value": "$MyAttribute"
        }
    }
}
Like 0

Like

1 comments

Hello,
It seems that the attributes will not work properly with the filter, as an alternative I can suggest applying the full filter in a handler where you can change it as you want, for example:

		handlers: /**SCHEMA_HANDLERS*/[
          {
            request: "crt.HandleViewModelAttributeChangeRequest",
            handler: async (request, next) => {
            	const result = await next?.handle(request);
            	request.$context.DataGrid_7cyakqc_PredefinedFilter={"items": {
								"1893734f-7c93-40a5-9592-8e7231005e10": {
									"filterType": 1,
									"comparisonType": 7,
									"isEnabled": true,
									"trimDateTimeParameterToDate": false,
									"leftExpression": {
										"expressionType": 0,
										"columnPath": "Age"
									},
									"isAggregative": false,
									"dataValueType": 4,
									"rightExpression": {
										"expressionType": 2,
										"parameter": {
											"dataValueType": 4,
											"value": 20
										}
									}
								}
							},
							"logicalOperation": 0,
							"isEnabled": true,
							"filterType": 6,
							"rootSchemaName": "Contact"};
            	return result;
              }
          }
        ]
Show all comments
"PDS_UsrActualFuelRemaining_s06444m": {
                        "modelConfig": {
                            "path": "PDS.UsrActualFuelRemaining"
                        },
                        "validators": {
                            "MyNumberValidator": {
                                "type": "usr.MonthNumberValidator",
                                "params": {
                                    "minValue": "0",
                                    "message": "Допустимі значення від 0 до 500",
                                    "maxValue": "500"
                                }
                            }
                        }
                    },

 

If I specify a range, the validator works. But when I try to use <strong>var OldWorkHour = await request.$context.PDS_UsrWorkHours_sjx2srh;</strong>, I get an error.

Could you please help me figure out why this happens and how to fix it?

 

 "usr.MonthNumberValidator": {
   validator: function(config) {
       return function(control) {
           var controlValue = control.value !== undefined ? parseFloat(control.value) : null; 
 
           var minValue = config.minValue !== undefined ? parseFloat(config.minValue) : Number.MIN_SAFE_INTEGER; 
           var maxValue = config.maxValue !== undefined ? parseFloat(config.maxValue) : Number.MAX_SAFE_INTEGER; 
 
            var OldWorkHour = await request.$context.PDS_UsrWorkHours_sjx2srh;
 
           var isValueValid = controlValue >= minValue && controlValue <= maxValue;
           if (!isValueValid) {
 
               return {
                   "invalid": { 
                       message: config.message || "Введене значення не відповідає умовам"
                   }
               };
           }
 
           // Якщо все добре, повертаємо null (успішна валідація)
           return null;
       };
   },
   params: [
       {
           name: "minValue"
       },
       {
           name: "maxValue"
       },
       {
           name: "message"
       }
   ],
   async: false
},
Like 0

Like

2 comments

Hi,

 

And what is the datatype for the PDS_UsrWorkHours_sjx2srh and UsrActualFuelRemaining? And what is the error message you receive?

Hello,
The ability to add dynamic parameters to a validator is still under development, as a way around you can try using global variables like window. For example

handlers: /**SCHEMA_HANDLERS*/[
{
    request: "dw.StartDateChange",
    handler: async (request, next) => {
        window.StartDate = await request.$context.DateTimeAttribute_lpcf566;
        if(request.$context.IsStartDateInited) {
            request.$context.validate();
        }
        request.$context.IsStartDateInited = true;
        return next?.handle(request);
    }
}]                
...        

"dw.StartDateIsNotNotLessThanProjectStartDate": {
    "validator": function (config) {
        return function (control) {
            return (!control.value || control.value >= window.StartDate)
                ? null
                : {"dw.StartDateValidator": {message: config.message}};
        };
    },
    "params": [
        {
            "name": "message"
        }
    ],
    "async": false
}

Show all comments

Hello,

 

I need to call a code once a record gets created for the first time. This worked using the following:

handlers: /**SCHEMA_HANDLERS*/[
			{
        request: "crt.SaveRecordRequest",
        handler: async (request, next) => {

 

however what this does is execute the code for each attribute value change, which is not what is needed. How can I call this exactly once just when the record is created for the first time and that's it, without having to call it again for each save request? Thanks

 

Note: I have tried replacing SaveRecordRequest with CreateRecordRequest, however the code was not executed once saving, or on any save.

 

Best,

Mohamad

Like 0

Like

10 comments

You can use the CardState to see if the record is in add mode (record is being added, saved for first time) or edit mode:

const mode = await request.$context.CardMode;
if (mode === “add”) {
    //
}

If you need to call some code exactly once when a record is created, I'd suggest moving the whole logic to backend. Specifically EntityEventListener and implement OnInserting or OnInserted methods to call your logic before or after the record is saved

Ryan Farley,

Hey Ryan,

 

Thanks for the reply, however that didn't work. The CardMode returns undefined, and when inspecting it in developer tools (request.$context object) the value is always 'edit' , when inserting the first time or when updating. Is there anything else I can do to fix the issue? Thanks

 

Best,

Mohamad

Yurii Sokil,

Hey Yurii,

 

Thanks for the reply, I have tried moving the logic to backend, however I encountered some issues. The overloaded method OnInserted cannot be async, and therefore I cannot call APIs directly from that method.

There is another option to call asynchronously using this method https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platform/back-end-development/objects-business-logic#title-2173-11 . However that doesn't solve the problem as if there were any errors when executing the asynchronous code, the record gets saved normally without indicating errors. Its a fire and forget operation and I need something that prevents a record from being inserted if the API call failed. Is there any way I can achieve this? Thanks for help

 

Best,

Mohamad

Mohamad Salhani,

If all you're after is to set up an auto number column, you can use the new auto number column default value. See https://customerfx.com/article/working-with-autonumber-fields-in-creatio/

Ryan

Ryan Farley,

No, so basically I need to populate a field once a record is created, and the value comes from an external API that I have to call

Ryan Farley,

Thanks for the support, I was finally able to solve it by checking the createdOn and modifiedOn dates for the record and see if they are equal, this way I can identify if the record was added for the first time or not. 

Thanks again!

Hi Mohamad, 
You can use AsyncPump.Run() to call async methods synchronously in your event listener. Also you can override OnInserting rather than OnInserted so your logic is called before the record is actually saved. 

Yurii Sokil,

Hey Yuri,

 

Thanks for the reply! It did work however I have a question. How can I pass arguments to the method passed in AsyncPump.Run() ? 

I have this code, but I can't pass arguments to the method.

 

[EntityEventListener(SchemaName = "UsrPetolTest")]
public class CustomEntityEventListener : BaseEntityEventListener
{
    public override void OnInserting(object sender, EntityBeforeEventArgs e)
    {
        base.OnInserting(sender, e);
 
        var entity = (Entity)sender;
        var userConnection = entity.UserConnection;
 
        AsyncPump.Run(testing);
 
    }
 
    private async void testing()
    {
        try
        {

 

Best,

Mohamad

Show all comments