Время создания
Filters
How_to_Add_a_Legend_to_a_Doughnut_Chart_in_Creatio_Freedom_UI_Using_JavaScript?
Studio_Creatio_enterprise_edition
8.0

How to Add a Legend to a Doughnut Chart in Creatio Freedom UI Using JavaScript?

Hi Creatio Community,

I'm working on a doughnut chart in Creatio Freedom UI and would like to display a legend below the chart. However, the chart configuration available in the Freedom UI designer does not provide an option to enable the legend for a doughnut chart.

I would like to explore whether this can be achieved through a client-side JavaScript handler without modifying the underlying chart configuration or affecting the chart's existing functionality.

  • Chart element: HTML inside the ts-chart component
  • Requirement: Display a custom legend below the doughnut chart, showing each series' actual color and label.

Questions:

  1. Is there a supported way to enable or configure a legend for a doughnut chart in Creatio Freedom UI?
  2. If the designer does not support this option, can a custom legend be added using a Freedom UI client-side JavaScript handler?
  3. How can we access the chart's actual labels, dataset values, and colors from the ts-chart component or its underlying chart configuration?
  4. Is there a recommended or supported API for accessing the chart instance without relying on undocumented internal properties?

My preference is to display the legend below the doughnut chart, using the existing chart labels and colors, while keeping the implementation scoped to this widget and preserving its existing interactions.

Any guidance, examples, or recommended approaches would be appreciated.

Thank you!

Like 0

Like

1 comments

Hi,

Thank you for the detailed question. Here are answers to each point, followed by the approach we recommend.

1. Is there a supported way to enable a legend for a doughnut chart?

Unfortunately, no. This is a current platform limitation, not a setting the Freedom UI Designer is missing.

  • The Show legend option is available only for Spline, Line, Bar, Area, Column and Scatter charts. Pie and doughnut charts don’t support a legend.
  • If you add a legend setting to the doughnut series by editing the page schema, the page saves it, but no legend appears. The chart turns off the legend for pie, doughnut, funnel and waterfall charts.
  • You can’t set slice colors either. The series color property is ignored for doughnut charts, and slices take their colors from the built-in palette.

What doughnut charts do show is a “label – NN%” data label next to each slice by default. Long labels wrap. Labels that would overlap are hidden, so very small slices may have no label. The dataLabel.display setting has no effect on doughnut charts.

2. Can a custom legend be added with client-side code?

Yes, as a separate element placed directly under the chart. It can’t be drawn inside the chart, because the chart is a single <canvas> with no extension point for that. This approach leaves the chart widget unchanged, so drilldown, tooltips, data labels and keyboard navigation keep working.

3. How can I get the chart’s labels, values and colors?

Labels and values. When a chart series gets its data through the standard data source (data.providing), the platform creates a page attribute named <ChartElementName>_SeriesData. For example, a chart element named MyDoughnut gets MyDoughnut_SeriesData. The attribute holds one array per series, and each item looks like this:

{
  grouping:    { value, displayValue }, // displayValue is the slice label
  aggregation: { value }                // value is the slice value
}

 

Please keep in mind:

  • The platform generates this attribute and it isn’t part of the documented API, so it may change in future versions.
  • It’s created only when the chart element has no explicit seriesData binding.
  • It’s filled asynchronously, so await it. It holds empty arrays until the data has loaded.

Colors. No API returns the colors the chart draws. Doughnut slices take colors from the built-in palette by slice index, starting again after the last color:

#0058EF, #F9307F, #08857E, #F86700, #4F43C2, #20A959, #009DE3, #FF4013, #B87CCF, #22AC14,
#247EE5, #FF602E, #9641A9, #0B6A32, #E00022, #1566B9, #BE1B5A, #7848EE, #0D2E4E

 

A legend that uses this list matches the chart today. The palette is an internal detail, though, so check the legend after upgrades.

Order. If the chart has a sort order (seriesOrder), sort your legend items the same way before assigning colors. Otherwise the colors won’t match the slices.

4. Is there a supported API to get the chart instance?

No. @creatio-devkit/common has no API that returns a page element’s component or the underlying Chart.js instance. The chart widget exposes only its configuration inputs, and clicks on the chart are handled inside the widget without reaching the page.

Reading the Chart.js instance from the component or the DOM depends on internal details, and we don’t recommend it. Chart.getChart(canvas) usually doesn’t work from custom code anyway. Custom code loads its own copy of Chart.js, which doesn’t know about the chart the widget created.

Recommended approach

Add a legend element under the chart and leave the chart widget as it is. There are three options, from simplest to most flexible.

Option 1. Text legend with a label (no custom component)

Add a crt.Label under the chart and fill it from a handler:

viewConfigDiff: /**SCHEMA_VIEW_CONFIG_DIFF*/[
  {
    "operation": "insert",
    "name": "MyDoughnutLegend",
    "values": {
      "type": "crt.Label",
      "caption": "$MyDoughnutLegendText",
      "labelType": "body",
      "visible": true
    },
    "parentName": "<container that holds MyDoughnut>",
    "propertyName": "items",
    "index": 1
  }
]/**SCHEMA_VIEW_CONFIG_DIFF*/,
viewModelConfigDiff: /**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/[
  {
    "operation": "merge",
    "path": ["attributes"],
    "values": {
      "MyDoughnutLegendText": {}
    }
  }
]/**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/,
handlers: /**SCHEMA_HANDLERS*/[
  {
    request: "crt.HandleViewModelAttributeChangeRequest",
    handler: async (request, next) => {
      if (request.attributeName === "MyDoughnut_SeriesData") {
        const seriesData = await request.$context.MyDoughnut_SeriesData;
        const items = seriesData?.[0] ?? [];
        request.$context.MyDoughnutLegendText = items
          .map(item => `${item.grouping.displayValue}: ${item.aggregation.value}`)
          .join("  |  ");
      }
      return next?.handle(request);
    }
  }
]/**SCHEMA_HANDLERS*/,

 

This option can’t show colored markers. Please check on your Creatio version that the change request fires for the generated attribute.

Option 2. Legend with colored markers (custom view element)

Create a small Angular component in a remote module (see “Develop a custom UI component using remote module” on Creatio Academy):

import { Component, Input, ViewEncapsulation } from '@angular/core';
import { CrtInput, CrtViewElement } from '@creatio-devkit/common';

const PALETTE = [
  '#0058EF', '#F9307F', '#08857E', '#F86700', '#4F43C2', '#20A959', '#009DE3',
  '#FF4013', '#B87CCF', '#22AC14', '#247EE5', '#FF602E', '#9641A9', '#0B6A32',
  '#E00022', '#1566B9', '#BE1B5A', '#7848EE', '#0D2E4E'
];

interface LegendItem {
  label: string;
  value: unknown;
}

@Component({
  selector: 'usr-chart-legend',
  template: `
    <div class="usr-legend">
      <span *ngFor="let item of legend; let i = index" class="usr-legend-item">
        <i [style.background]="color(i)"></i>{{ item.label }} ({{ item.value }})
      </span>
    </div>`,
  styles: [`
    .usr-legend { display: flex; flex-wrap: wrap; gap: 8px 16px; justify-content: center; }
    .usr-legend-item { display: inline-flex; align-items: center; }
    .usr-legend-item i { width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; }
  `],
  encapsulation: ViewEncapsulation.Emulated
})
@CrtViewElement({
  selector: 'usr-chart-legend',
  type: 'usr.ChartLegend'
})
export class UsrChartLegendComponent {
  public legend: LegendItem[] = [];

  @Input()
  @CrtInput()
  public set items(value: any) {
    Promise.resolve(value).then(data => {
      this.legend = (data?.[0] ?? []).map((item: any) => ({
        label: item.grouping?.displayValue,
        value: item.aggregation?.value
      }));
    });
  }

  public color(index: number): string {
    return PALETTE[index % PALETTE.length];
  }
}

 

Register the component in the remote module the standard way. Then place it under the chart on the Freedom UI page:

{
  "operation": "insert",
  "name": "MyDoughnutLegend",
  "values": {
    "type": "usr.ChartLegend",
    "items": "$MyDoughnut_SeriesData"
  },
  "parentName": "<container that holds MyDoughnut>",
  "propertyName": "items",
  "index": 1
}

 

Option 3. Load the legend data yourself (fully supported API)

If you don’t want to depend on the generated _SeriesData attribute, load the same aggregated data with sdk.Model. Pass the result to the label from Option 1 or the component from Option 2:

const model = await sdk.Model.create("Account");
const rows = await model.load({
  attributes: [
    { name: "Industry", path: "Industry" },
    {
      name: "Count",
      path: "Id",
      type: "function",
      functionConfig: {
        type: "aggregation",
        aggregation: "Count",
        aggregationEval: "all"
      }
    }
  ],
  parameters: [
    /* the same filters the chart uses */
  ]
});

 

Use the same grouping column, filters and sort order as the chart so the legend rows match the slices.

Limitations

  • A custom legend doesn’t react to the chart’s interactive state, such as a hovered or drilled-down slice.
  • The color palette and the <ChartElementName>_SeriesData attribute are internal details that may change in future versions. Please check the legend after upgrades.

Registering the idea

We agree that a built-in legend for pie and doughnut charts would be useful, and adding one needs a platform change. Please send this idea to support@creatio.com so it’s registered with the R&D team and considered for the product roadmap. Including your use case, such as “legend below the doughnut chart with series colors and labels”, will help us prioritize it.

Show all comments
ESQ_Transaction

Hello Community,

I have a question if its possible to have database transaction scope using ESQ instead of direct SQL. From the documentation it is suggested that we as Devs should use ESQ most of the times because of validation etc.

I have a case where I have to modify two entities and for that I need two separate ESQ (maybe there is a better way). My goal is to wrap that in a single transaction so that all changes are made or none (to avoid inconsistency).

Is this code below valid for this case? Is going to work?

```
using System;
using Terrasoft.Core.DB;
using Terrasoft.Core.Entities;

using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection())
{
dbExecutor.StartTransaction();
try
{
var schemaManager = UserConnection.EntitySchemaManager;

// Contact
Entity contact = schemaManager.GetInstanceByName("Contact").CreateEntity(UserConnection);
contact.SetDefColumnValues();
contact.SetColumnValue("Name", "Jane Doe");
contact.Save();

// Case, linked to the new contact
Entity supportCase = schemaManager.GetInstanceByName("Case").CreateEntity(UserConnection);
supportCase.SetDefColumnValues();
supportCase.SetColumnValue("Subject", "Test case");
supportCase.SetColumnValue("ContactId", contact.PrimaryColumnValue);
supportCase.Save();

// ...more entities as needed

dbExecutor.CommitTransaction();
}
catch
{
dbExecutor.RollbackTransaction();
throw;
}
}
```

Thanks for all answers.

Like 1

Like

2 comments
Best reply

Hi,

Yes, this pattern works, and Creatio’s own core code uses it (sync, process completion, AppManager). Using Entity here is correct. ESQ is mainly for reading data; Entity, or Insert/Update queries, are the right tools for writing.

Why it works

  • UserConnection.EnsureDBConnection() doesn’t open a new connection each time. It returns the DBExecutor cached on that UserConnection and adds one to a reference count.
  • Entity.Save() calls UserConnection.EnsureDBConnection() internally, so it gets the same executor. Every command that executor runs is enlisted in its open transaction.
  • That covers more than the main INSERT/UPDATE: default record rights, owner rights, localization rows, change tracking, and DB writes made by synchronous event handlers on the same UserConnection.
  • Save() doesn’t start its own transaction on insert or update. Delete() does, but transactions nest with a depth counter. An inner Commit or Rollback does nothing, so only your outermost call decides.
  • If the using block ends without a commit (for example, an unexpected exception), Dispose() rolls the transaction back. Your explicit RollbackTransaction() is still good practice.

Things to watch for

  1. Save() can return false without throwing. This happens when an OnSaving, OnInserting or OnUpdating handler cancels the save. Your try block would then commit the other entities. Check the return value.
  2. Use the same UserConnection for everything. Work done through SystemUserConnection or another connection runs on a different DB connection. It is outside your transaction, and it can block on rows you have locked.
  3. Some side effects are not rolled back. They are sent during Save(), not after commit:

    • async entity event operations (when async execution of entity events is enabled)
    • business processes started by a record signal and run in background mode
    • websocket and cache notifications
    • file content kept in external file storage

    Background work may run before your commit, so it won’t see the new record yet. It may also run after a rollback, against a record that no longer exists.

  4. Keep the work synchronous. Don’t use async/await or extra threads inside the block.
  5. Don’t reuse entity objects after a rollback. They are already marked as saved in memory, so build new instances.
  6. If you’re inside someone else’s transaction, rethrow the exception. Your inner Rollback does nothing in that case. If you swallow the exception, the outer commit still saves everything.

Suggested version

using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection())
{
    dbExecutor.StartTransaction();
    try
    {
        var schemaManager = UserConnection.EntitySchemaManager;

        Entity contact = schemaManager.GetInstanceByName("Contact").CreateEntity(UserConnection);
        contact.SetDefColumnValues();
        contact.SetColumnValue("Name", "Jane Doe");
        if (!contact.Save())
            throw new InvalidOperationException("Contact was not saved.");

        Entity supportCase = schemaManager.GetInstanceByName("Case").CreateEntity(UserConnection);
        supportCase.SetDefColumnValues();
        supportCase.SetColumnValue("Subject", "Test case");
        supportCase.SetColumnValue("ContactId", contact.PrimaryColumnValue);
        if (!supportCase.Save())
            throw new InvalidOperationException("Case was not saved.");

        dbExecutor.CommitTransaction();
    }
    catch
    {
        dbExecutor.RollbackTransaction();
        throw;
    }
}

Hi,

Yes, this pattern works, and Creatio’s own core code uses it (sync, process completion, AppManager). Using Entity here is correct. ESQ is mainly for reading data; Entity, or Insert/Update queries, are the right tools for writing.

Why it works

  • UserConnection.EnsureDBConnection() doesn’t open a new connection each time. It returns the DBExecutor cached on that UserConnection and adds one to a reference count.
  • Entity.Save() calls UserConnection.EnsureDBConnection() internally, so it gets the same executor. Every command that executor runs is enlisted in its open transaction.
  • That covers more than the main INSERT/UPDATE: default record rights, owner rights, localization rows, change tracking, and DB writes made by synchronous event handlers on the same UserConnection.
  • Save() doesn’t start its own transaction on insert or update. Delete() does, but transactions nest with a depth counter. An inner Commit or Rollback does nothing, so only your outermost call decides.
  • If the using block ends without a commit (for example, an unexpected exception), Dispose() rolls the transaction back. Your explicit RollbackTransaction() is still good practice.

Things to watch for

  1. Save() can return false without throwing. This happens when an OnSaving, OnInserting or OnUpdating handler cancels the save. Your try block would then commit the other entities. Check the return value.
  2. Use the same UserConnection for everything. Work done through SystemUserConnection or another connection runs on a different DB connection. It is outside your transaction, and it can block on rows you have locked.
  3. Some side effects are not rolled back. They are sent during Save(), not after commit:

    • async entity event operations (when async execution of entity events is enabled)
    • business processes started by a record signal and run in background mode
    • websocket and cache notifications
    • file content kept in external file storage

    Background work may run before your commit, so it won’t see the new record yet. It may also run after a rollback, against a record that no longer exists.

  4. Keep the work synchronous. Don’t use async/await or extra threads inside the block.
  5. Don’t reuse entity objects after a rollback. They are already marked as saved in memory, so build new instances.
  6. If you’re inside someone else’s transaction, rethrow the exception. Your inner Rollback does nothing in that case. If you swallow the exception, the outer commit still saves everything.

Suggested version

using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection())
{
    dbExecutor.StartTransaction();
    try
    {
        var schemaManager = UserConnection.EntitySchemaManager;

        Entity contact = schemaManager.GetInstanceByName("Contact").CreateEntity(UserConnection);
        contact.SetDefColumnValues();
        contact.SetColumnValue("Name", "Jane Doe");
        if (!contact.Save())
            throw new InvalidOperationException("Contact was not saved.");

        Entity supportCase = schemaManager.GetInstanceByName("Case").CreateEntity(UserConnection);
        supportCase.SetDefColumnValues();
        supportCase.SetColumnValue("Subject", "Test case");
        supportCase.SetColumnValue("ContactId", contact.PrimaryColumnValue);
        if (!supportCase.Save())
            throw new InvalidOperationException("Case was not saved.");

        dbExecutor.CommitTransaction();
    }
    catch
    {
        dbExecutor.RollbackTransaction();
        throw;
    }
}

Oleg Drobina,

Thank you so much for this very thorough answer. That helped me a lot and I think its going to help others too.

Show all comments
Studio_Creatio
8.0

Hi,

I want to open specific page via business process. The button was clicked from mobile and it will run the business process.  I checked the execution diagram and it seems worked. However the mobile does nothing and it seems stucked.

Like 0

Like

1 comments

Hi,

Your process is probably fine. What fails is the hand-off at “Open edit page”: the Creatio mobile app most likely never handles the message that tells a client to open the page. So the process sits waiting on that element, which is why the diagram looks right while the phone does nothing.

How to confirm

  1. In the process log, check the “Buka detail halaman…” element. If it shows “in progress” rather than “completed”, the process is waiting for a client that never answers.
  2. Press the same button in the web app as the same user. If the page opens there, the problem is mobile-only.
  3. Optionally, keep a browser tab open as that user and press the button on the phone. If the page pops up in the browser, the phone is just ignoring the message.
  4. Check your Creatio version. Starting a process from a Freedom UI mobile button (crt.RunBusinessProcessRequest) is only supported in Creatio Mobile 8.3.4 and later (Academy handlers reference).

How to fix it: let the process do data only, and do the navigation on the mobile side

  • A (recommended): no process. Bind the button to a mobile custom request handler, built with @creatio/mobile-common and the EnableMobileSDK feature (overview). The handler:

    1. looks up the record by No Prospect;
    2. if it’s found, opens it with crt.UpdateRecordRequest (or crt.OpenPageRequest);
    3. if not, opens a new record with crt.CreateRecordRequest, with No Prospect pre-filled.

    A handler written for the web (a usr.* schema handler) won’t work on mobile.

  • B (8.3.4 and later): keep the process, but only for data. Remove both “Open edit page” elements and keep Read Data / Add Data. Start the process with crt.RunBusinessProcessRequest, then open the record from the mobile side.
  • C (before 8.3.4): start the process from a record change. Have the button set a field, and let a signal-started process do the data work. Navigation still has to happen on the mobile side.

If the web test (step 2) also fails: the process may be running in background mode, from a background or batch connection, or with “Show execution page” turned off. In those cases the server skips sending the message entirely and the symptom looks the same.

Also cancel the runs already stuck on “Open edit page” in the process log so they don’t pile up.

Show all comments
mobile application
adddatasource
Studio_Creatio
8.0

Hi All,

Question please, how can I add data source in Mobile Page?

I googling, and Creatio said it should be in the left top corner, link :
https://academy.creatio.com/guides/mobile/mobile-app-setup/freedom-ui/freedom-ui-mobile-designer

Need advice please, thank you.

Like 0

Like

1 comments

Hi,

Why you don't see the button

  • One data source per page. The guide says "Each mobile page works with a single data source." In your screenshot, the VERIFICATION group in the Components panel is that data source. Its fields appear under Data model attributes (A. Age, A. CIF No, and so on).
  • The button is only for pages that don't have one yet. You get Add data source → New data source (then Name and Description) when you create a mobile page from a template that has no data source. Creatio then creates a new object and connects it to the page. Your form page was created from the existing app, so it was bound to the Verification object automatically.
  • Version. This designer feature needs Creatio 8.3.2 or later. If you're on an older version, the button won't be there at all.

What you can do instead

  1. Add fields to the current data source. In the VERIFICATION group, use the Add new field tiles (Text, Number, Dropdown, …) or drag existing attributes from Data model attributes onto the page.
  2. Show data from another object. Mobile pages share data sources with their desktop Freedom UI pages: "data sources configured for a Freedom UI page are automatically available on the corresponding Freedom UI mobile page." Open the desktop Verification form page in the Freedom UI Designer, add the extra data source there (for example, a list or detail of related records), save it, then reopen the mobile designer.
  3. Use a separate object as the main source. Create a new mobile page from a template. That's where Add data source appears.

Also note that the Academy page recommends the Freedom UI Mobile Designer only for newly created apps, not for adding mobile pages to apps that already existed. If "Mobile Survey" is an older app, that may explain other limitations you run into.

Show all comments
NotUpdadate
Studio_Creatio
datamodels
#enableLiveUpdate
Studio_Creatio
8.0

Hi All, question please, I have form, let say named : MyApplication form page, and there have a business process that using Signal.

And in that Business Process, there have a calculation that can modified value for let say field ABC. The Business Process and Calculation is already fine, but it is not directly change value from ABC field. It must refresh page first, then it is changed.

My expected is, when Signal on Business Process is triggered, the Calculation running, then the output will change ABC field directly, not must to refresh.

I checked Data Model Behaviour already Enabled live data update, but it is not working.

Note : In another form page, it is not happening. I don't know why, this issue only happened in MyApplication form page.

Need advice please, thank you.

 

Like 0

Like

6 comments

Hi,

The live data update checkbox is already on, so the problem is usually that this page is not connected to that object's updates, or the way the process writes the value doesn't send a refresh. Since it works on your other pages, compare MyApplication against a working page on each point below.

1. Is MyApplication a Freedom UI page?

Live data update only works on Freedom UI pages. If MyApplication is a Classic UI page, or the section opens the record in a classic page, the checkbox does nothing. Then you either rebuild the page in Freedom UI or add code to refresh it (a client message plus a page reload).
Check: open the page in the designer. A Freedom UI page uses the drag-and-drop designer with components on the left.

2. Is the checkbox on the right object?

The setting only matters on the object that is the page's primary data source. Common mismatches:

  • The page is based on a different object, such as a replacement or a similarly named object (for example UsrMyApplication versus UsrApplication).
  • Field ABC belongs to a related object (for example Contact.ABC shown through a lookup), and the process updates that related record. Then the related object needs live data update enabled too.
  • The process updates a different object from the one the page is showing.

Check: in the page designer, look at the data source and its object name. Compare it with the object in the process's Modify data element.

3. Was the object saved and published after you ticked the box?

Ticking the box is not enough. You need to Save and Publish the object. Then log out and back in, or clear the browser cache, so the page loads the new setting.

4. How does the process write ABC?

  • Modify data element: sends the update to open pages. ✅
  • Script task that writes with direct SQL (Update, CustomQuery, a raw UPDATE ...): skips the object layer, so no update is sent to the page. ❌

    If you need a script, save through an Entity instead, for example entity.SetColumnValue(...) followed by entity.Save().

5. Signal timing

If the signal fires on Record modified and the user saves from the same page, the process can write ABC while the page is still finishing its own save. The page then keeps the old value it has in memory.

  • In the signal element, make sure "Run following elements in background" is ticked so the calculation runs after the save completes.
  • If the user still has unsaved changes on the page, the incoming value may not overwrite the form. Test with a clean, saved record.

6. Is ABC a real field on the page?

ABC must be bound to the object's column through the page's data source. If it is a page attribute or a custom field filled by a handler, live update won't refresh it.

The first thing to check is publishing and compiling the object, then performing the test after compilation is complete.

Quick test to narrow it down: open a MyApplication record in one browser tab. In another tab, open the same record in the section list, or as a different user, and change ABC by hand.

  • If the first tab doesn't update, the cause is points 1 to 3 (page or object setup).
  • If it does update but the process change doesn't show, the cause is points 4 or 5 (how or when the process writes the value).

Hi Oleg, so I already tried to open Form Page with another browser, and login with another account. Then I changed the value from ABC field in that another browser.

  • In another browser = Saved--> In the first browser = the value is not change
  • In another browser = Not saved (only change value) --> In the first browser = the value is not change also

Based on your suspect above, so maybe the cause is points 1 to 3.
I checked from point 1 to 3 :
1. My Form Page is using Freedom UI

2. Yes, it is in the right object. I compare ABC field in the form page (it is from primary data source)

3. Yes, the object I already Save & Published after tick the box "Enable Live Data Update"

 

So, all is correct setup Oleg, any suggestion? Thank you for help.

Dedi Sadikin,

Just to be on the same page: have you tried compiling the object using this option?

It might help, we had tickets related to such behavior in the past and the fix was to compile the object.

Your test shows the problem isn't the business process. A manual change saved from another browser also doesn't reach the first browser, so live update isn't working for this page at all.

The "not saved" case is normal: unsaved changes never go to other users. Only the "saved" case matters.

Step 1: Repeat the test on a page that works

Do the same two-browser test on one of the pages where you said it works. Use two different users, change the field, save, and watch the other browser.

  • If that page also doesn't update: the problem is server or network, not your object. Common causes:

    • The WebSocket connection is blocked by a proxy, load balancer or firewall.
    • Several web servers run without Redis message sharing configured. A save on server A is then never sent to a user connected to server B, so it looks random by page or user.

    To check, open the browser DevTools (F12), go to Network, and filter by WS. There should be an open WebSocket connection, and a message should arrive when the other browser saves. If nothing arrives, give this to your Creatio admin or hosting support.

  • If that page does update: the problem is specific to the Application object or the MyApplication page. Continue with step 2.

Step 2: Check the object and page

  1. The checkbox stayed ticked. Close the object designer, reopen the Application object, and confirm "Enable live data update" is still ticked. If the object has a replacing version in another package, the tick may have been saved somewhere that isn't used.
  2. Clean restart. After publishing, the setting may still be cached. Log out every test user and clear the browser cache. On-site, restart the app or ask your admin to flush Redis. On cloud, ask support to restart the site.
  3. No unsaved changes in the first browser. If you edited anything on the page in browser 1 before the other save, the page may keep its own values. Open the record fresh and touch nothing, then save in browser 2.
  4. Custom code on the page. If MyApplication has handlers added by a developer, temporarily disable them and test again. Look in the page's source code at handlers, especially anything that intercepts data loading or attribute changes.
  5. Isolation test. Create a new Freedom UI page for the same Application object using the default template, add field ABC, and run the two-browser test.
    • It works: the original MyApplication page is the problem. Compare the two, or rebuild the page.
    • It doesn't work: the object is the problem. Raise a ticket with Creatio support and include your Creatio version and this test.

If you need a fix now

Until live update works, add a Refresh button to the page. In the Freedom UI button properties, choose the action that reloads the page data. Users can then see the process result without a full browser refresh.

Your Modify data setup in the screenshot looks correct: the object is Application, the filter is Id = the signal's record, and it sets Monthly Installment. Once live update works for manual edits, the process result should show up as well.

 

Oleg, thank you for the feedback, but is it possible if we have session, maybe 15 minutes on zoom? I hard to explain in this Community. I don't know, I think we have missunderstanding. Thank you, appreciate it.

Dedi Sadikin,

Please register a ticket by emailing us at support@creatio.com, specifying link to the application where the issue occurs with external access to this application (access to data and configuration are needed) under the system administrator and steps to reproduce the issue and the support team will look into it.

Hi Oleg, thank you for the feedback, I already email to support creatio about this, and I upload video how to produce this question, also I already give access until 14 Oct 2026. Thank you for the support Oleg, appreciate it.

Show all comments