Время создания
Filters

The report recognizes our vision to unify AI, no-code, and vertical CRM. Our leading CRM suite, no-code platform, and pre-built Financial Services workflows enable banks, insurance providers, and financial institutions to accelerate digital transformation and enhance customer experiences with unparalleled agility and efficiency. 

Learn more about this recognition: https://www.creatio.com/company/news/23794 

Like 19

Like

Share

0 comments
Show all comments

Introducing our new partner Perceptiva, a service provider that empowers businesses through “Intelligent Integration” to push forward AI goals!

Learn more about the partner: https://www.creatio.com/company/news/23784

Like 13

Like

Share

0 comments
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

The new alliance to deliver AI-native, no-code solutions to help enterprises rapidly scale intelligent automation with ease.

Read more: https://www.creatio.com/company/news/23764

Like 13

Like

Share

0 comments
Show all comments

Hello, community!

I’ve created a script that helps convert HTML text from a database into plain text.
 

To achieve this, you’ll need to add two libraries to the business process:


 

Then, use the following script task:



string texthtml = Get("texthtml");

if (string.IsNullOrWhiteSpace(texthtml)) {
   Set("DecodedHtmlText", string.Empty);
} else {
   // Remove HTML tags
   string text = Regex.Replace(texthtml, "<.*?>", string.Empty);

   // Decode HTML entities (e.g., & -> &)
   text = WebUtility.HtmlDecode(text);

   // Store the result in a business process variable
   Set("DecodedHtmlText", text);
}
 

return true;

* texthtml - parametr where our html text stored
* DecodedHtmlText - text type parametr to set text



I hope this will be useful!

 

Like 1

Like

Share

0 comments
Show all comments