Is it possible to intercept using some request handler the event when a user clicks on the green "Complete" button on a Next Steps tile? This is the button in the "next-step-tile-actions" div on the page which only appears when you hover over the next step tile:

 

It would be vey helpful to be able to run some custom code when this button is clicked - in our case, we need it to save the main page record before actioning this next step, as completing the next step might automatically transition the Lead to the next stage, losing any data entered by the user.

Like 220

Like

6 comments

None of the following handlers are triggered by clicking this button, maybe I've missed some candidates but these are the ones I've tried so far:

crt.ChangeNextStepsStateRequest

crt.OpenPageRequest

crt.UpdateRecordRequest

crt.CreateRecordRequest

Also tried "brute forcing" it by overriding every handler I could find in the Creatio code, but literally nothing fires when clicking that button! Not even something like the page's crt.HandleViewModelPauseRequest (since it's a modal popup, I guess the full page doesn't actually pause like it would when navigating to a another page through clicking a lookup for example). Hopefully I've missed something, triggering some action on clicking that button would be useful.

Any thoughts/knowledge on how such a thing could be achieved?

Hi Harvey! 

 

Unfortunately, at the moment, there is no way to intercept the event of clicking on the Next-steps tile buttons. This button can call different requests depending on the type of tile, and these requests are called without the view model context, which will not allow us to intercept them from the card and use them to save card data.

 

We have registered your idea, and the R&D team has already planned the task for this improvement - they will create a special output event for the Next-steps component. This functionality will be available in future releases.

 

Thank you for making our product better!

 

Best regards,

Natalia

Thank you for the information Natalia, this would be a welcome improvement!

Hi Natalia, is there any expected timeline for this improvement known yet? Do you have a reference for the planned task for later follow-up?

Show all comments

Hello. In a section page, I need to make the case number font bold, but according to a specific field value. I tried to do it based on several articles (https://community.creatio.com/questions/how-add-custom-style-control-pa… https://community.creatio.com/questions/bigger-font-name-list-record-di…). 

But I'm running out of ideas. I would be grateful for your help!

Something like this, but only for case number text.

Like 1

Like

9 comments
Best reply

Сергій Сермакшев,

 

&lt is the html code for < symbol, it's a "feature" of the code editor here in the Community:)

 

As for ModifierType

We have access to items that will be displayed in the grid and their position will be the same as in the response.collection.collection.items. You can pass response to the performStylesChange method and process it there as well and perform the check for the needed ModifierType and change styles only for those records.

 

Something like:

define("CaseSection", [], function() {
	return {
		entitySchemaName: "Case",
		messages: {},
		attributes: {},
		diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
		methods: {
			onGridDataLoaded: function(response) {
				this.callParent(arguments);
				this.performStylesChange(response);
			},
 
			performStylesChange: function(response) {
				var processedItemsIndexes = this.checkResponseCollection(response);
				var recordTitles = document.getElementsByClassName("grid-primary-column");
				for (var i = 0; i &lt; recordTitles.length; i++) {
					for (var j = 0; j &lt; processedItemsIndexes.length; j++) {
						if (processedItemsIndexes[j] == i) {
							var element = recordTitles[i];
							element.style.fontWeight = 'bold';
						}
					}
				}
			},
 
			checkResponseCollection: function(response) {
				var responseItems = response.collection.getItems();
				var processItemsIndexes = [];
				for (var i = 0; i &lt; responseItems.length; i++) {
					if (responseItems[i].values.Status.displayValue == "New") {
						processItemsIndexes.push(i);
					}
				}
				return processItemsIndexes;
			}
		}
	};
});

Here I marked tickets in the New status in bold text:

So you can use the same approach in your task.

Hello Serhiy,

Could you please clarify which step exactly you have problems with? 

Was it possible for you to make the text bold without conditions?

If so then how exactly do you add the specific field value? 

Anhelina writes:

Hello Serhiy,

Could you please clarify which step exactly you have problems with? 

Was it possible for you to make the text bold without conditions?

If so then how exactly do you add the specific field value? 

Thank you for your interest. I have overridden 2 methods: 

initQueryColumns: function(esq) {
	this.callParent(arguments);
 
	esq.addColumn("ModifiedBy.Type.Id", "ModifierType");
 
},
 
prepareResponseCollection: function(collection) {
	this.callParent(arguments);
	// Аor each record returned in the query for the list 		
	// check the Amount field value and then apply style
	collection.each(function(item) {
		if (item.get("ModifierType") == "00783ef6-f36b-1410-a883-16d83cab0980") {
			item.customStyle = Ext.apply(item.customStyle || {}, {
				"background-color": "#FFFFCC",
				"font-weight": "bold"
	        });
		}
	}, this);
}

I understand that I need to change this part of the code:

item.customStyle = Ext.apply(item.customStyle || {}, {
	"background-color": "#FFFFCC",
	"font-weight": "bold"
}

It must be something like this:

.title {
	"background-color": "#FFFFCC",
	"font-weight": "bold"
}

But I have no idea how to apply the style to a specific entry element in the list.

 

Сергій Сермакшев,

 

Hello,

 

Try another approach:

define("CaseSection", [], function() {
	return {
		entitySchemaName: "Case",
		messages: {},
		attributes: {},
		diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
		methods: {
			onGridDataLoaded: function(response) {
				this.callParent(arguments);
				this.performStylesChange();
			},
 
			performStylesChange: function() {
				var recordTitles = document.getElementsByClassName("grid-primary-column");
				for (var i = 0; i &lt; recordTitles.length; i++) {
					var element = recordTitles[i];
					element.style.fontWeight = 'bold';
				}
			}
		}
	};
});

The logic here is simple: once grid data is loaded we go through all elements on the page and change the style for the text to bold to all title columns (which is a case number). This is not the best solution, but it works properly when the list is loaded or sorting\filtering is changed in the list.

Oleg Drobina writes:

i <

Thank you. For some reason, it complained about "i &lt;" had to delete. Everything worked. 

But how to implement this part of the logic?

if (item.get("ModifierType") == "00783ef6-f36b-1410-a883-16d83cab0980")


It is necessary to highlight only those records where some field matches a specific record in the directory.

Сергій Сермакшев,

Hello. Here is an example. It uses jQuery, but you may easily adapt it to Oleg's example. Main idea is that items[i] is viewModel coresponding to recordTitles[i] DOM element from Oleg's example. 

applyCustomCss: function(){
	var gridData = this.getGridData();
	var items = gridData.getItems();
	var uiItems = $("div[column-name='ColorByProductType']");
 
 
	for (var i = 0; i &lt; items.length; i++){
		var height = $(uiItems[0]).css("height");
		var bgColor;
		var category = items[i].get("Product.SxGoodsCategory").value;
		if (category === SxProductConstants.GoodsCategory.Wine){
			var wineColor = items[i].get("Product.SxColor").value;
			if (wineColor === SxProductConstants.WineColor.Red){
				bgColor = "#cc0a0a";
			}
			else if (wineColor === SxProductConstants.WineColor.White){
				bgColor = "gold";
			}
			else if (wineColor === SxProductConstants.WineColor.Pink){
				bgColor = "pink";
			}
		}
		else if (category === SxProductConstants.GoodsCategory.Champagne){
			bgColor = "bisque";
		}
		else if (category === SxProductConstants.GoodsCategory.StrongAlcoholDrink){
			bgColor = "saddlebrown";
		}
		else if (category === SxProductConstants.GoodsCategory.Water){
			bgColor = "blue";
		}
		$(uiItems[i]).css(
			{"background-color": bgColor, 
			"border-radius": "50%",
			"vertical-align:": "middle",
			"margin-top": "7px",
			"margin-right": "2px",
			"width": height});
	}
},

 

And instead of oveeriding initQueryColumns method it is better to override getGridDataColumns

                getGridDataColumns: function () {
                   var baseGridDataColumns = this.callParent(arguments);
                   var gridDataColumns = {
                       "ModifiedBy.Type.Id": {path: "ModifiedBy.Type.Id"}
                   };
                   return Ext.apply(baseGridDataColumns, gridDataColumns);
               },

 

Сергій Сермакшев,

 

&lt is the html code for < symbol, it's a "feature" of the code editor here in the Community:)

 

As for ModifierType

We have access to items that will be displayed in the grid and their position will be the same as in the response.collection.collection.items. You can pass response to the performStylesChange method and process it there as well and perform the check for the needed ModifierType and change styles only for those records.

 

Something like:

define("CaseSection", [], function() {
	return {
		entitySchemaName: "Case",
		messages: {},
		attributes: {},
		diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
		methods: {
			onGridDataLoaded: function(response) {
				this.callParent(arguments);
				this.performStylesChange(response);
			},
 
			performStylesChange: function(response) {
				var processedItemsIndexes = this.checkResponseCollection(response);
				var recordTitles = document.getElementsByClassName("grid-primary-column");
				for (var i = 0; i &lt; recordTitles.length; i++) {
					for (var j = 0; j &lt; processedItemsIndexes.length; j++) {
						if (processedItemsIndexes[j] == i) {
							var element = recordTitles[i];
							element.style.fontWeight = 'bold';
						}
					}
				}
			},
 
			checkResponseCollection: function(response) {
				var responseItems = response.collection.getItems();
				var processItemsIndexes = [];
				for (var i = 0; i &lt; responseItems.length; i++) {
					if (responseItems[i].values.Status.displayValue == "New") {
						processItemsIndexes.push(i);
					}
				}
				return processItemsIndexes;
			}
		}
	};
});

Here I marked tickets in the New status in bold text:

So you can use the same approach in your task.

Oleg Drobina,

Thank you very much. With your help to solve this problem. It also gave me some insight into working with section entries via JavaScript.
Also, if you don't mind, tell me how to compare the "Contact Type" lookup value in the : "ModifiedBy" field. Something like  "ModifiedBy.Type.Id". Thank you again.

Сергій Сермакшев,

 

You are welcome!

 

As for ModifiedBy.Type - the easiest way is to display this column in the section list.

 

Alternatively you can add the initQueryColumns method override to the section methods in the following manner:

initQueryColumns: function(esq) {
				this.callParent(arguments);
				esq.addColumn("Owner.Type", "OwnerType");
			},

What I did here is add the Owner.Type column in the Cases section esq (Case has an Assignee (which is the Owner column that references the Contact entity) and I need to check the contact type specified in this column). As a result

we have access to this OwnerType in the context of the onGridDataLoaded and performStylesChange execution. We can also use it for style recalculation. In your case it should be similar but using another column. 

Oleg Drobina,

You are great. Everything worked out.

Show all comments

Just a quick PSA - either 8.1.2 or 8.1.3 breaks the ability we had before of being able to set Page Parameter values in the crt.HandleViewModelInitRequest request handler, since in the newer versions it appears the value is reset back to the default (similar to how fields based over table columns are) at some time after the init handler runs. This is quite frustrating, as it's reducing the number of options we have for setting values in the code where required (which it still often is with the current options for no code development).

 

A workaround that Ryan Farley has previous mentioned using for setting field values by using a javascript timeout can be used for this too, e.g.

setTimeout(() => {request.$context.TextPageParameter = "Test value";}, 300);
Like 2

Like

8 comments

Hello, Harvey

I also had such an isuue but I resolved it by calling parameter initialization after let result =  await next?.handle(request); And then in the end return result; 

Andrii Orlenko,

 

Mine was already being initialised after awaiting the result of handling the request, so it might be that sometimes this takes long enough to be ok but not always (so would introduce a race condition).

Harvey Adcock,

Thank you for the provided information!
The problem is already registered on the R&D team, and we hope to see the fix in future releases.

Anhelina,

Thank you. 

Just an FYI, I've been reporting this since 8.0.10 (see #SR-01234445). I was told this would be resolved in "the nearest releases (8.1.1-8.1.2)", however, it's still an issue in 8.1.3 without a commitment from Creatio on a specific timeframe for a resolution. This is a pretty huge pain point so it's disappointing that it's still a problem. I do love Freedom UI (and I'll take it any day over classic!) but there's been many instances of my code breaking along the way with new versions and it sometimes seems less urgent for fixes for issues that go beyond the "no code" customizations.

Ryan

Ryan Farley,

I checked that case before replying to Harvey and asked the responsible team to raise the priority for this task. I apologize for the delay and hope to see the fix soon.
Meanwhile, they shared one more workaround, which is better to use with parameters:

add the handler on parameter changing and rewrite it when the default value has appeared:

Example

Anhelina,

Yes, this approach does work if all you need when the form is initialized is to work with a single value on the page. However, that is often not the case and each property initialization can happen at slightly different times, so referencing other attributes in this same handler might not work, depending on the timing of the various attributes being loaded/initialized. Adding a separate handler for each attribute you need to work with can get messy quick.

Ryan

What I think would be nice/match the existing patterns would be to have some new request handler that does the setting of default values on the page, something like "crt.HandleAttributeInitRequest", which would perform the OOTB platform's setting of these values in the next?.handle(request) and then after awaiting the result of that a developer could set their own defaults for fields they need to, which wouldn't be overwritten (since the defaults had already been set).

 

It would also be nice to be able to "silently" set these default values (like you could in Classic UI) so that setting values in that request handler wouldn't cause the "are you sure" dialog to appear if a user closes the page without actually modifying the data themselves. Actually it would be nice to be able to do that generally from within request handler code.

Hi, is there any update on the matter? 
Still when you're trying to read the attributes on crt.HandleViewModelInitRequest the attributes aren't initialized and are all undefined

Show all comments

Hello Creatio Community,

 

I am currently working on a page in Freedom UI which contains a detail. The detail's object resides in Classic UI. I need to apply field validation on this detail while performing inline editing within the Freedom UI.

 

Here's a brief overview of what I'm trying to achieve:

  1. The main page is in Freedom UI.
  2. The detail object is in Classic UI.
  3. I need to implement field validation on the detail during inline editing.

     

I've attempted a few approaches, but none seem to provide the desired results. Has anyone faced a similar challenge or can provide guidance on how to achieve this functionality?

Any help or pointers would be greatly appreciated.

 

Thank you!

Like 0

Like

1 comments

Hello Kumar,
Looks like this task is impossible for now because Freedom UI doesn't allow getting the value of one control (attribute) in the code of custom validator for another control.

We have this task registered on our R&D team and will get this possibility in future releases, please follow the updates.

Best regards, Anhelina!
 

Show all comments

I have a web form created in wordpress using elementor plugin. I would like to upload a file to the via this wordpress form but I can't find documentation for this. Any help would be much appreciated.

Like 0

Like

2 comments

Hi!

We do not currently support file transfers, but we will register a request for a description of the documentation if possible.
 

If you have any further questions, please send them in response. We will be happy to help.
 

Thank you for contacting Creatio Support!
 

It's not very straight forward, but it is possible. Basically, you'd need to encode the file as a Base64 string, then transfer it as a string value to the webhook. Once received decode the Base64 string back to a file byte array to save as an attachment somewhere. 

If this is coming from a web form, you can use Javascript's FileReader to convert the file to a base64 string. See https://stackoverflow.com/questions/36280818/how-to-convert-file-to-base64-in-javascript

Then send the value as a string to the webhook. You could add a process to trigger on record added of your entity. Then decode the string to a byte array. See https://learn.microsoft.com/en-us/dotnet/api/system.convert.frombase64string

Then save the byte array as an attachment on the record. See https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platform/back-end-development/api-for-file-management/examples/file-management-examples

Ryan

Show all comments

Hello Community ,

 

how can we configure the home page as the default login instead of the Desktop page , as well as the workspace?

 

Thanks

Like 0

Like

1 comments

Hello,

Unfortunately, we do not currently have the option to specify a default Home page for all new users. As for now, you can only set a section (Dashboards, Contacts, Accounts, etc.) as the default value for the user. You can view this post:  https://community.creatio.com/questions/default-page-login

However, we have registered it in our R&D team backlog for consideration and implementation in future application releases. 

Show all comments

Hi all,

 

In our project we are producing with Creatio application some printable document (.pdf and .doc).

 

In these document we are inserting some Rich Text fields but in the document produced we are not able to visualize/report all the style changes done on the Rich Text field.

 

Do you have any suggestion?

 

Best Regards

 

Stefano

Like 0

Like

2 comments

Hello,

 

As of now, it's not possible to correctly display the field with HTML formatting in the printable.  


Our R&D team has already been informed and is currently working on the mentioned issue.


As a workaround suggestion, you can replace the rich text field with a simple text field. We understand that it’s missing the format settings and cannot be applied to tables, but it should work for a sentence or two simple comments.  

 

Thank you for being an active part of the community and helping to make Creatio better!

Hello Hanna,

Thank you very much for your response

Regards

Stefano

Show all comments

Hi All,

I have two instances of Creatio and they are both fail to compile.

 

Old Instance 

New Instance 

I do have the c:\windows\system32\inetsrv\NuGet\Migrations folder created.  

 

Both logs show a variegation of the below error messages, 6 in the old and 12 in the new one.

 

2024-05-29 15:36:07,813 [99] INFO IIS APPPOOL\Studio_Assignment Build CaptureOutput - C:\Program Files\dotnet\sdk\8.0.100\NuGet.targets(156,5): error :   No such host is known. (api.nuget.org:443) [C:\Creatio\Studio_Softkey_MSSQL_assinment\Terrasoft.WebApp\Terrasoft.Configuration\Terrasoft.Configuration.ODataEntities.csproj]
2024-05-29 15:36:07,813 [99] INFO IIS APPPOOL\Studio_Assignment Build CaptureOutput - C:\Program Files\dotnet\sdk\8.0.100\NuGet.targets(156,5): error :   No such host is known. [C:\Creatio\Studio_Softkey_MSSQL_assinment\Terrasoft.WebApp\Terrasoft.Configuration\Terrasoft.Configuration.ODataEntities.csproj]

 

I installed sdk\8.0.100 but the problem persists.

 

While looking at the documentation i see that sdk\8.0.100 is not a requirment so I'm a bit confused as to why the logs show this error message. 

 

The old version worked up until yesterday, not sure what changed.

Any help is much appreciated,

Thanks,

Paddy 

 

 

File attachments
Like 1

Like

2 comments
Best reply

It’s working now (the next day), both compile. 

 

My network was filtering some Microsoft traffic, after I removed the network restriction it worked as expected. 

It’s working now (the next day), both compile. 

 

My network was filtering some Microsoft traffic, after I removed the network restriction it worked as expected. 

Hello,
 

We are glad to hear that you managed to solve the compilation issues.

Based on the errors, the dotnet components lacked the necessary files for the application to work correctly and an attempt was made to get the necessary files from the NuGet repository, but since there was no full access to the repository via the Internet, this error occurred.

Show all comments

Report does not generate:
Ideas missing expenses data

Like 0

Like

3 comments

Here is a sucessfull report launch result:

As this shows, the field COmment and Expenses amount is showing a "Null" result.

Have to start over again, any modifications to the original report makes the latest version STOP. It will not RUN.

Show all comments

Hello,

 

I am following this guide (https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platfor…) and I am stuck in the step 2 where I have to register the custom channel in the database.

 

I assume that firstly I need to add a record in the previously created table where I define a specific Username and Token that the external client will need to use in order to authenticate the messages sent within my custom channel. Therefore, I understand that the Id of the created record must be used in the [MsgSettingsId] column of the Channel table. However, I don't know what I must introduce in the [Source] column. As stated in the article:

 

[Source]: The channel ID in the messenger, such as the Facebook page ID or Telegram client ID. Lets you identify the recipient by a messenger message.

 

I noticed that for Facebook, that field stores the Facebook user ID that will be resolved in the URL ">https://facebook.com/[user_id] which redirects to /">https://www.facebook.com/people/[user-name]/[other_id] and in WhatsApp the URL is ">https://wa.me/[phone_number] which redirects to &text&type=phone_number&app_absent=0">https://api.whatsapp.com/send/?phone=%2B[phone_number]&text&type=phone_number&app_absent=0.

 

If I set a random string for the [Source] column and I try to check the information in the ChatSettings I get the following error when I click on the channel name:

 

"invalid channel type"

test

 

But what is the channel type? What does that mean and how is it resolved by Creatio?

 

In my case, I want to setup the communication between Creatio and a external chatbot. What exact value should I set in the [Source] column for my custom channel provider?

 

Regards

Like 0

Like

2 comments

Hi Alejandro! How are you? I hope you're well. The guide you are referring to is related to creating a new integration (channel) with a third-party messaging platform such as Viber, WeChat, etc. For my part I was able to develop a new channel following the guide. If you have questions, feel free to send me a message and we'll get in touch. Another option is to detail your goal and I can give you some tips on how to move forward.

Hello, 
You're right, MsgSettingsId should contain an ID from the record you insert into the table TestMsgSettings created previously. As for the Source, you can find the article on how to get the page ID, for example, https://help.salesforce.com/s/articleView?id=000389501&type=1. As for the other sources like your chatbot, if I'm not mistaken, the Source can be just a simple string, the error appears due to the fact that custom channels weren't expected in code, they need to be configured directly in the DB.

openChannelDialogService(t, n) {
                this.zone.run(()=&gt;{
                    switch (t.typeId) {
                    case v.FacebookMessenger:
                        this.dialogService.open(D, n).subscribe();
                        break;
                    case v.Telegram:
                        this.dialogService.open(K, n).subscribe();
                        break;
                    case v.WhatsApp:
                        this.dialogService.open(X, n).subscribe();
                        break;
                    default:
                        console.error("invalid channel type")
                    }
                }
                )
            }

 

Show all comments