Hello,

I tried to change the width of one of my Freedom UI mini pages, by adding the code below to the page. When I opened from the designer, it has the width that I want for a few seconds before changing back to the default width. What I'm missing?

Thanks,

Jose

 

          {
                "operation": "merge",
                "name": "Main",
                "values": {
                    "fitContent": true,
                    "layoutConfig": {
                        "width": 840
                    }
                }
            },

 

Like 0

Like

2 comments
Best reply

There's a feature you can add/enable called "EnabledAppearanceSettings" that turns on the ability to choose different sizes for the modal/mini pages. See more here: https://customerfx.com/article/changing-the-size-of-freedom-ui-modal-mi…

  1. Go to https://[creatiourl/0/flags
  2. Search to see if you have the feature named "EnabledAppearanceSettings" (you won't have it, but just to make sure. If not, click Add to add it, enter:
    1. Code = EnabledAppearanceSettings
    2. Enabled = checked
    3. Save, then click Clear Cache
  3. Now when you open the designer for a modal/mini page, you'll see some size options

Ryan

There's a feature you can add/enable called "EnabledAppearanceSettings" that turns on the ability to choose different sizes for the modal/mini pages. See more here: https://customerfx.com/article/changing-the-size-of-freedom-ui-modal-mi…

  1. Go to https://[creatiourl/0/flags
  2. Search to see if you have the feature named "EnabledAppearanceSettings" (you won't have it, but just to make sure. If not, click Add to add it, enter:
    1. Code = EnabledAppearanceSettings
    2. Enabled = checked
    3. Save, then click Clear Cache
  3. Now when you open the designer for a modal/mini page, you'll see some size options

Ryan

Ryan Farley,

Thanks. That's exactly what I was looking for.

Show all comments

Hello

I'm trying to mark a boolean as required, but that option doesn't appear in the settings.

Does anyone know how I can mark the checkbox as required?

Fig. 1 Set up a Checkbox field

 

Thank you. 

 

Like 0

Like

2 comments

Making a checkbox required would only mean it can be checked (since there's no difference between unchecked and not filled in). Alternative approach is to use a lookup with Yes/No values (since then there is also a not filled in)

Hello Ryan Farley,

What happens is that I have a set of questions with three answer options each, and for each question, only one option needs to be filled out. I have a business rule that marks the boxes as required, but when one of them is selected, it disables the other two and makes them optional. The problem is that once you select a box and uncheck it, the required  disappears, allowing you to save with the three options blank. That's why I want to make the checkboxes required from the configuration.

 

And the reason for the checkboxes is that I require the checkmarks to appear in the Word report.

 

 

 

Show all comments

Dear,

On the Classic UI we could have a thumbnail of the images in the browser:

Classic UI

But in Freedom the picto is not display:

Freedom UI


Is it possible to display the image thumbnail directly in the browser with Freedom UI?

Thank you !
Nicolas

Like 0

Like

4 comments

Hello,

Unfortunately, currently this is not possible with the out-of-the-box solution. 
If you want to display a certain image for the record, for example company logo for the account record, you can use an Image component.


You can also consider using the following marketplace solution: https://marketplace.creatio.com/app/banza-files-extended-creatio?check_…

I hope this helps! If you have any further questions or need assistance, feel free to reach out.

I have a marketplace addon coming that does this, it is still awaiting the approval for the marketplace to publish the addon - it takes a very long time for them to approve things 👎🏻 - hopefully it will be published soon. 

Hello Nicolas,

The add-on that displays image previews in the attachment list is now available in the marketplace: https://marketplace.creatio.com/app/image-previews-creatio

Ryan

Thank you Ryan
This is exactly what we needed !

Show all comments

Hi Community,

I’m customizing a detail/list view in Creatio where each row includes fields like A1, A2, A3. One of the fields is a single text field, and I want to style individual words within this field — for example, giving each word a different background color.

This is similar to how the multi-select lookup component shows selected values with separate styling (like colored tags). I’m trying to recreate that effect for a regular text field in the list view.

To clarify:

  • I already know how to inject custom CSS using modules and global CSS variables
  • What I’m looking for is a way to apply styling dynamically at runtime, depending on the text content

Thanks in advance for your help!

Like 0

Like

2 comments

CSS alone doesn't work that way. You can't style single word within the same text using CSS. You'd need to manipulate the text so that each word would be wrapped in it's own span/div to be able to style them that way.

Show all comments

Hello,

In my Project's form page, I have two charts that summarize data from a Time Cards object in the form of a bar chart and a column chart. After placing the chart component onto my form page, I had trouble resizing the charts to make them larger. I attached below an image for reference. Any help on how to resize charts would be greatly appreciated. Please let me know if you have any questions or need me to further clarify. 

 

Best,

Shubh

Like 0

Like

2 comments
Best reply

If you drag them taller it will give more room for the chart bars/columns and the text will be more readable.

If you drag them taller it will give more room for the chart bars/columns and the text will be more readable.

Ryan Farley,

Thank you! This worked. I did not see the little square to drag the chart taller before.

Show all comments

Dear,

When starting Creatio we have the following errors :

Classic UI

It seems that Creatio is not finding some language files.

Can these mistakes be corrected ?

Thank you !
Nicolas

Like 0

Like

1 comments

Hello!

Try to change the language of the user to English, recompile the system. Then switch back to French and try to reproduce the error.

Have a nice day!

Show all comments

Hi Creatio Community!
I’m building a custom Freedom UI component and need some advice on how to pass data from the component back to the parent page.
I have a custom component with some internal logic and a variable whose value changes based on user interaction inside the component (e.g. clicks, selections).
Now I want to pass this variable's value back to the parent page where the component is used — for example, to trigger some business logic or store it in a page field.
Is there a way to work with the page context from within the custom component?
Or maybe there's a recommended pattern for passing data upward from a component to the parent page in Freedom UI?

Any examples or best practices would be greatly appreciated!

Thanks in advance

Like 2

Like

0 comments
Show all comments

Hi Creatio Community!
I’m currently working on a custom Angular component (Freedom UI) and ran into an issue I hope someone has already dealt with. I created a custom table component that loads data from a web service — the structure is quite complex with nested records, so I chose to use a service instead of standard object bindings.

I'm receiving the current record ID like this:

@Input()
@CrtInput()
public recordId!: { value: string; displayValue: string };

This is how I set recordId into component

{
	"operation": "insert",
	"name": "CustomTable",
	"values": {
		"recordId": "$UsrContractConditionsGroupDS_UsrContract_c00dfo4",
		"type": "usr.Table"
	},
	"parentName": "ListOfTarrifGroupByPeriod_ExpansionPanel",
	"propertyName": "items",
	"index": 0
},

When I open the page for the first time, everything works fine — the recordId arrives as expected. 

But when I back to section and open this record again, the component throws an error because recordId is undefined, and my table is empty.

I’m calling the service directly in ngOnInit().

Could you please advise on the correct way to store the record ID in the component so that it doesn’t get lost when opening the page a second time?

 

Like 1

Like

2 comments
Best reply

Hello Artem,

 

You can store record ID in the custom attribute and populate its value when the page is opening in the request crt.HandleViewModelInitRequest.

 

viewModelConfigDiff: /**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/[
	{
		"operation": "merge",
		"path": [
			"attributes"
		],
		"values": {
			"RecordId": {}
			...
		}
	}
	...
]
handlers: [
	{
		request: "crt.HandleViewModelInitRequest",
		handler: async (request, next) => {
			await next?.handle(request);
			request.$context.RecordId = request.$context.Id;
		}
	}
]

Then you can use this custom attribute in your component

 

{
	"operation": "insert",
	"name": "CustomTable",
	"values": {
		"recordId": "$RecordId",
		"type": "usr.Table"
	},
	"parentName": "ListOfTarrifGroupByPeriod_ExpansionPanel",
	"propertyName": "items",
	"index": 0
},

Hello Artem,

 

You can store record ID in the custom attribute and populate its value when the page is opening in the request crt.HandleViewModelInitRequest.

 

viewModelConfigDiff: /**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/[
	{
		"operation": "merge",
		"path": [
			"attributes"
		],
		"values": {
			"RecordId": {}
			...
		}
	}
	...
]
handlers: [
	{
		request: "crt.HandleViewModelInitRequest",
		handler: async (request, next) => {
			await next?.handle(request);
			request.$context.RecordId = request.$context.Id;
		}
	}
]

Then you can use this custom attribute in your component

 

{
	"operation": "insert",
	"name": "CustomTable",
	"values": {
		"recordId": "$RecordId",
		"type": "usr.Table"
	},
	"parentName": "ListOfTarrifGroupByPeriod_ExpansionPanel",
	"propertyName": "items",
	"index": 0
},

Iryna Oriyenko,

Thank you very much!

Show all comments

I'm looking for help with setting a default tab in a Freedom UI page.

I want the "Lead Info" tab (which is the first tab) to always be selected by default when opening a lead record. However, after I perform or complete an activity and return to the Lead page, it automatically opens the "Lead Activities" tab instead of the "Lead Info" tab.

Is there a way to set the page to always open the "Lead Info" tab, regardless of the last active tab or navigation history?

Like 0

Like

2 comments

You can set the active tab using something like this (where "Tabs" is the name of the tab control): 

request.$context.Tabs_SelectedTabIndex_Profile = 0;

I've not tried setting that in the crt.HandleViewModelInitRequest, but it could work - although might need to wrap in a setTimeout just to break out of the message loop and let the page load first and for the saved user profile for selected tab is loaded first (I don't believe there is a way to prevent that). Try something like this:

{
    request: "crt.HandleViewModelInitRequest",
    handler: async (request, next) => {
        setTimeout(() => { request.$context.Tabs_SelectedTabIndex_Profile = 0; }, 1000);
        return await next?.handle(request);
    }
}

Might need to play with the timeout interval (the 1000), although it's not 100% it will work.

Ryan

Try using this code in the  handler:

      {

      request: "crt.HandleViewModelInitRequest",

      handler: async (request, next) =>{

        request.$context.Tabs_SelectedTabIndex_Profile=0;

        return next?.handle(request);

      }

    }

Show all comments

Original Reference: Ryan Farley, “Getting Multi‑select Records from a Creatio Freedom UI List via Code” Customer FX, Jan 30, 2024 

 

The Challenge

In Creatio 8.1+, lists support multi‑selection. Ryan’s post shows how to bind a custom bulk‑action button and read the DataTable_SelectionState attribute:

const selectedIds = (await request.$context.DataTable_SelectionState).selected;

However, this only covers the case where users manually pick some rows (“specific” selection). If they click “Select All,” the selected array is empty and selectionState.type === "all", with an unselected array instead. Nor does the basic snippet iterate through all pages of data.

An Alternative, Complete Handler

The code below demonstrates how to:

  1. Detect whether the user chose a subset (“specific”) or all records (“all”).
  2. Extract the true list of record IDs in both cases.
  3. Execute a business process for each record.
  4. Access other context values (e.g. an Opportunity ID wrapped in a  proxy).
{
 request: "cfx.ButtonClicked",
 handler: async (request, next) => {
   // 1. Retrieve selection state
   const selectionState = await request.$context.DataTable_SelectionState;
   // 2. Grab manual selections (if any)
   const selectedIds = selectionState?.selected || [];
   // 3. Retrieve another context value (example: Opportunity ID)
   const opportunityProxy = await request.$context.UsrEntity_66d2fb2DS_UsrOpportunityId_dppjv0g;
   const opportunityId = opportunityProxy?.value;
   // Helper: execute business process
   const runBP = async (recordId) => {
     return request.$context.executeRequest({
       type: "crt.RunBusinessProcessRequest",
       processName: "UsrProcess_4e23e14",
       processParameters: {
         ProcessSchemaParameter1: recordId,
         opportunityId
       },
       $context: request.$context
     });
   };
   // 4. Handle specific selections
   if (selectionState.type === "specific") {
     if (!selectedIds.length || !opportunityId) {
       console.error("No records selected or missing Opportunity ID.");
       return;
     }
     for (const id of selectedIds) {
       await runBP(id);
     }
   // 5. Handle “select all”
   } else if (selectionState.type === "all") {
     // a. Get IDs the user explicitly un‑selected (if any)
     const unselected = selectionState.unselected || [];
     // b. Read the full page of items bound to the list
     const items = await request.$context.Items;
     if (!Array.isArray(items)) {
       console.error("Items binding is not an array.");
       return;
     }
     // c. Build a final list of IDs: include every item not in unselected
     const allIds = items
       .map(item => item.PDS_Id.__zone_symbol__value)
       .filter(id => !unselected.includes(id));
     if (!allIds.length || !opportunityId) {
       console.error("No records to process or missing Opportunity ID.");
       return;
     }
     for (const id of allIds) {
       await runBP(id);
     }
   }
   // 6. Continue the chain
   return next?.handle(request);
 }
}
How This Works
  • selectionState.selected vs. .unselected:
    • When users pick specific rows, selected holds their IDs.
    • When they click the header checkbox (“Select All”), the engine treats it as “all except any I un‑checked,” so selected is empty and type === "all". The unselected array lists exceptions.
  • Reading the full list (Items):
    • You only get the current page of records in the Items binding. If your grid is paginated, you’ll need to iterate through pages server‑side or adjust your viewModel to load all records you intend to process.

 

 

 

Like 1

Like

Share

1 comments

This is fantastic, thanks for sharing! 

For list's that are multi-select I believe there is also the following (with likely the same results, returns an array of Ids):

request.$context.MyList_SelectedRows

At least that was the case, haven't verified that is still present. 

Also, if the list isn't multi-select (meaning no checkboxes), then I don't believe SelectedRows or SelectionState has anything for the single selected row. For non-multi-select lists you'd get the selected row using (return's the row's Id): 

request.$context.MyList_ActiveRow

Ryan

Show all comments