Hi community, 

Where can I find the source code responsible for this checkbox (Make the list editable). 

I want to make this detail editable only in one section. Here is my use case : I'm using this detail in two sections A and B. In section A, I want the detail to be editable like this : 

 

But in section B, I don't want this behavior (checkbox must be unchecked) like this : 

Like 0

Like

4 comments

You should create 2 separate details. And add them to the separate edit page for section A and for section B.

Thanks Antonii, isn't there any other way than creating two details ? 

Ismail el lahya,

This is the best way to perform this task

Antonii Viazovskyi,

Thank you!

Show all comments

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

5 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!

Show all comments

I tried returning false and not calling next?.handle(request), but the record still seems to get saved. In Classic UI it was possible to prevent saving by not calling the this.callParent method, which I believe is somewhat analogous to the next?.handle(request), but I guess not perfectly? Maybe I'm missing something.

Like 1

Like

1 comments
Best reply

Hello Harvey,

It is possible, and you do it in the right way as I can see from the description. To prevent saving you have to declare this handler in the scheme and simply do not call next?.handle(request). 

Hello Harvey,

It is possible, and you do it in the right way as I can see from the description. To prevent saving you have to declare this handler in the scheme and simply do not call next?.handle(request). 

Show all comments

I'm looking to trigger page data validation in a specific circumstance from code. I've found that you can use

request.$context.validate()

within client event handlers to trigger the OOTB fields validation for the page, but this just returns an object representing any/all errors in validation for the data. What would make sense to do in our use case after that would be to trigger the NotifyService message you usually see when saving fails due to such validation checks, but I can't see how to trigger it/how to fetch the string that should be shown in the message. I located a method that looks like it is performing this task for the OOTB save validation, called getValidationErrorMessage, which would be passed the request context and the error object returned by the validate function, but this method doesn't seem to be available for use.

 

Has anybody had any luck with triggering validation in Freedom UI and then displaying the OOTB message based on that validation result? Any help would be greatly appreciated. We're currently running on 8.1.0

Like 2

Like

3 comments

Hello,

If I'm not mistaken, you can use simple OOTB validation that is described here https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platfor…

Hi Dmytro,

 

This doesn't give us a way to trigger the validation manually though unfortunately. What we were trying to achieve was to show the validation message to users without saving/trying to save the record at that point in time. We ended up making our own very basic error message that shows the results returned by

request.$context.validate()

if there are any and stops the user progressing in our custom path, but it would be good to be able to tap into the OOTB error toast message so it's a little more detailed and polished.

Harvey Adcock,

 

Hello! 

Unfortunately, so far, we don't have the functionality to trigger the OOTB validation snackbar-message without saving /trying to save the record. 

We have registered your suggestion, and our R&D team will consider implementing it in future releases.

Thank you for making our product better!

 

Best regards, 

Natalia

Show all comments

Is there any way to undo/cancel a change that triggers the crt.HandleViewModelAttributeChangeRequest handler? The use case is that a field is set in the crt.HandleViewModelInitRequest handler, but this setting of the value gets immediately overwritten by the OOTB system that sets up the page it seems. So I would like to be able to conditionally cancel the setting of this field by the page. Any help would be greatly appreciated. We're currently on 8.1.0

Like 1

Like

4 comments

Hi Harvey,

 

We can create an attribute to store a value that you want to set in HandleViewModelInitRequest. Then, in HandleViewModelAttributeChangeRequest, we can check if the current field value matches the one you previously set. If it does not match, we can assign the stored value to it. This way, we ensure that the desired value is assigned to the field.



In the given example, we have created an attribute named "UsrInitialValue".

viewModelConfig: /**SCHEMA_VIEW_MODEL_CONFIG*/{
			"attributes": {
				"StringAttribute_ljc6yh6": {
					"modelConfig": {
						"path": "PDS.UsrTestString"
					}
				},
				"UsrInitialValue": {}
			}
		}/**SCHEMA_VIEW_MODEL_CONFIG*/,



This attribute is used to store a specific value that we set during the initialization process. In the crt.HandleViewModelInitRequest handler, we set a value for the request.$context.UsrInitialValue. And in crt.HandleViewModelAttributeChangeRequest, we check if the current field value matches the value we set previously in the request.$context.UsrInitialValue. If they don't match, we update the field with the new value.

 

handlers: /**SCHEMA_HANDLERS*/[
			{
				request: "crt.HandleViewModelInitRequest",
				handler: async (request, next) => {
					request.$context.UsrInitialValue = "testInit";
					request.$context.StringAttribute_ljc6yh6 = await request.$context.UsrInitialValue;
					return next?.handle(request);
				}
			},
 
			{
				request: "crt.HandleViewModelAttributeChangeRequest",
				handler: async (request, next) => {
					var srtValue = await request.$context.StringAttribute_ljc6yh6;
					var initVal = await request.$context.UsrInitialValue;
					if (request.attributeName === 'StringAttribute_ljc6yh6' && srtValue != initVal) {
						request.$context.StringAttribute_ljc6yh6 = initVal;
					}
					return next?.handle(request);
				}
			}
		]/**SCHEMA_HANDLERS*/,

 

Artem Smyrnov,

 

I think this would prevent any modification to the data, including intended changing by the user or system. Obviously it could be changed to add some more conditions, but really the main thing we want/frequently need is for the crt.HandleViewModelInitRequest request to be able to initialise a value and not be overwritten by the standard page loading stuff (loading default values for the entity, clearing out the field where there are no default values etc). I'm pretty sure this was possible in Classic UI, it just doesn't seem to be currently in Freedom UI without some pretty nasty hacks.

Harvey Adcock,

There is no logic that could be used to revert changes to the column value that were done by the handler.

As a solution, you need to create a column that will not use any other handler and set the value using your custom handler. This will prevent the value from being overwritten by other handlers or custom logic.

We have a workaround in place, but this capability has been required a few times - it would be good if Creatio supported setting values on the page in the init handler (or some other handler, maybe a new initvalues handler or something) since per-page default values is often required.

Show all comments

I'm overriding the HandleViewModelAttributeChangeRequest request handler in client code, and want to set a hidden parameter used for showing/hiding fields and making them required/not required in this code when the page first loads, but I don't want this change to be detected by Creatio as a save-able change so that it thinks there is a change to be saved when closing the page. Is it possible to do this? I've tried setting the "silent" property of the request to true in the HandleViewModelAttributeChangeRequest handler and also tried setting the "IsChanged" property of the request.$context to false after changing the attribute value, but neither of these seems to prevent the "You have unsaved changes that will be lost. Continue?" dialog from showing when closing the page.

 

I'm currently using Creatio 8.1.0

Like 1

Like

5 comments

Can you please provide some direct example of what you are trying to achieve since unfortunately it's not obvious to us what is performed on the page at the moment, what is the expected result and what is the actual result? Maybe some steps to reproduce it in the local application (like the following:

 

1) Add column A

2) Add attribute B

3) Connect B to A in the following manner

4) Go to the page where the column and the attribute were added

5) Do "this"

6) Expected result is C

7) Actual result is D

 

) .

 

Thank you!

Oleg Drobina,

Basically all I want is to be able to set the value of an attribute in code without triggering the "You have unsaved changes that will be lost. Continue?" message when you leave the page. Is this possible?

Harvey Adcock,

 

I tried to reproduce the issue, but changing the value of the virtual attributes (like attributes created to control the visibility of the field) by itself does not cause this dialog to appear. 

Please ensure that no other changes need to be saved on the page. Or provide us with additional information describing the exact steps to reproduce the issue.

 

Best regards,

Natalia

Natalia Kalynovska,

 

Sorry, I was probably not detailed enough in my abbreviated version - the changes are actually to an attribute that is based over a real column on the entity, so not a virtual attribute. Is there any way to modify such a field in code without triggering the dialog?

Hello Harvey,

To change the field without triggering the dialog, you should save it at once.

It could be implemented by adding the following code to the HandleViewModelAttributeChangeRequest:

if (request.attributeName === “[Name of the attribute]”) {

const saveResult = await this.handlerChain.handlerChain$.process({

           type: "crt.SaveRecordRequest",

           preventCardClose: true,

           $context: request.$context

    });

}

Please pay attention that too many saving requests may decrease performance.

 

Another way is to save the necessary changed values to a virtual attribute first, and then extract all of them (set attributes values) and initiate SaveRecordRequest while closing the page (in crt. ClosePageRequest). This approach has some disadvantages:

  1. you need to manually adjust the visibility  of “SaveButton” and “CloseButton“ by adding the corresponding merge operations to “viewConfigDiff” of ListPage and FormPage modules (see example - https://community.creatio.com/questions/how-remove-closesave-button-custom-section);
  2. data would be saved only on a close/back button click.

And again – you should provide some conditions in order not to store too many changes.

 

Additionally, starting from the 8.1.1 Creatio version, the dialog may be prevented by adding to handlers the overridden “crt.CanDiscardUnsavedDataRequest” handler:

{request: "crt.CanDiscardUnsavedDataRequest", handler: async (request, next) => {return true;}},

(see https://community.creatio.com/questions/possible-suppress-message-upon-canceling-freedom-ui-mini-page).

However, it still requires manually adjusting the button's visibility and providing proper data saving.

 

Best regards, 

Natalia

Show all comments

Hi Team,

We have an issue when installing packages in the production environment some js files (Client module) and business Rules are not updated with new fields.

we make an overwrite page and section file properly in the custom package but the issue is only in production can't see new fields and business Rules in page and in js file



also we perform a compile all & Generate for all schemas but still same issue

Like 1

Like

2 comments

Hello,



Could you please elaborate on the issue? 



Are transferring modifications between environments by packages? 

Is it working properly on the website where it was developed?

Bogdan,

Hi  Bogdan, Thanks for reply 

Yes transferring modifications between environments by packages and it is work successfully on my development environment

Show all comments

I have a lookup field on a detail (List of VAT options with an added column for the % values), im trying to use these now to calculate a value, how do I access the other column? I can access the VAT Code using this.get("UsrVatCode"), but want the associated column which as the % amount.

Like 1

Like

2 comments
Best reply
var lookupId = this.get("RecordColumn").value;
 
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
    rootSchemaName: "INSERTOBJECT"
});
 
esq.addColumn("Insert Object column you wish to view");
 
esq.getEntity(lookupId, function(result) {
    if (!result.success) {
        this.showInformationDialog("Error");
        return;
    }
    this.showInformationDialog(result.entity.values.Column You wish to view);
}, this);

This is the code that I used to get it working, if anyone needs it.

var lookupId = this.get("RecordColumn").value;
 
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
    rootSchemaName: "INSERTOBJECT"
});
 
esq.addColumn("Insert Object column you wish to view");
 
esq.getEntity(lookupId, function(result) {
    if (!result.success) {
        this.showInformationDialog("Error");
        return;
    }
    this.showInformationDialog(result.entity.values.Column You wish to view);
}, this);

This is the code that I used to get it working, if anyone needs it.

There is also another approach: in the schema in the attributes property you can specify your column in the following manner:

"Your_column_from_the_page": {
					"dataValueType": this.Terrasoft.DataValueType.LOOKUP,
					"lookupListConfig": {
						"columns": ["column_name_from_the_lookup_object"]
					}
				},

As an example we can see that in the ContractPageV2 there is this attribute:

"Currency": {
					"dataValueType": this.Terrasoft.DataValueType.LOOKUP,
					"lookupListConfig": {
						"columns": ["Division"]
					}
				},

and we have access to the value of the "Division" column from the "Currency" lookup:

Show all comments

Hello fellow creators! I have problems with extending BaseSectionV2 schema. I want to disable View button , so I  created a replacing module of BaseSectionV2 and wrote some code, but it's not working. Any advice would be much appreciated

 define("BaseSectionV2",[],function(){
	 return {
		 entitySchemaName:"Base",
		 details:/**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		 attributes:{},
		 methods:{
			 checkIsAdmin:function() {
				 var user = Terrasoft.SysValue.CURRENT_USER;
				 var name = user.displayValue;
				 if(name==='Supervisor')
					 return true;			 
				 		return false;
			 }
		 },
		 diff:/**SCHEMA_DIFF*/[
				{
					"operation": "merge",
					"name": "AnalyticsModeViewOptionsButton",
					"parentName": "AnalyticsModeActionButtonsRightContainer",
					"propertyName": "items",
					"values": {
						"itemType": Terrasoft.ViewItemType.BUTTON,
						"caption": { "bindTo": "Resources.Strings.ViewOptionsButtonCaption"},
						"enabled": { "bindTo": "checkIsAdmin"},
					 }
				}
 
		 ]/**SCHEMA_DIFF*/
	 };
  });
File attachments
Like 0

Like

2 comments
Best reply

Hi,

You need to override shema BaseDataView and modify the button SeparateModeViewOptionsButton:

  define("BaseDataView",[],function(){
	 return {
		 details:/**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		 attributes:{},
		 methods:{
			 checkIsAdmin:function() {
				 var user = Terrasoft.SysValue.CURRENT_USER;
				 var name = user.displayValue;
				 if(name==='Supervisor')
					 return true;			 
				 		return false;
			 }
		 },
		 diff:/**SCHEMA_DIFF*/[
			 {
				"operation": "merge",
				"name": "SeparateModeViewOptionsButton",
				"values": {
					"enabled": { "bindTo": "checkIsAdmin"}
				}
			}
		 ]/**SCHEMA_DIFF*/
	 };
  });

 

Hi,

You need to override shema BaseDataView and modify the button SeparateModeViewOptionsButton:

  define("BaseDataView",[],function(){
	 return {
		 details:/**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		 attributes:{},
		 methods:{
			 checkIsAdmin:function() {
				 var user = Terrasoft.SysValue.CURRENT_USER;
				 var name = user.displayValue;
				 if(name==='Supervisor')
					 return true;			 
				 		return false;
			 }
		 },
		 diff:/**SCHEMA_DIFF*/[
			 {
				"operation": "merge",
				"name": "SeparateModeViewOptionsButton",
				"values": {
					"enabled": { "bindTo": "checkIsAdmin"}
				}
			}
		 ]/**SCHEMA_DIFF*/
	 };
  });

 

Dmytro Vovchenko,

Thanks a lot! It worked!

Show all comments

Hello!

 

I have these 3 buttons that I want to hide or remove on a condition.

 

This is the code that removes them. 

 

If the Ownership Status (added in the attributes) is 'Inactive', then these buttons should dissapear.

 

Does anybody know how I can do this on a condition in diff?

Like 0

Like

2 comments
Best reply

First of all, rather than using operation: remove, change that to operation: merge, which will let you modify the properties of the element. Then, you'll bind the visible property of them to an attribute. To show or hide them, you'll set the attribute to true or false. See this article here for more details: https://customerfx.com/article/how-to-enable-or-disable-a-field-on-a-pa…

Also, to set the attribute to true or false, you'll either need to add that to a change event for whatever fields use the conditions or when the page opens, using the onEntityInitialized function. To base it on the selection of fields, you can wire a change event as shown here: https://customerfx.com/article/triggering-an-event-when-a-field-is-chan…

Info on the onEntityInitialized function and other basic info on working with page code here: https://customerfx.com/article/getting-started-with-writing-code-for-bp…

Hope this helps get you started.

Ryan

First of all, rather than using operation: remove, change that to operation: merge, which will let you modify the properties of the element. Then, you'll bind the visible property of them to an attribute. To show or hide them, you'll set the attribute to true or false. See this article here for more details: https://customerfx.com/article/how-to-enable-or-disable-a-field-on-a-pa…

Also, to set the attribute to true or false, you'll either need to add that to a change event for whatever fields use the conditions or when the page opens, using the onEntityInitialized function. To base it on the selection of fields, you can wire a change event as shown here: https://customerfx.com/article/triggering-an-event-when-a-field-is-chan…

Info on the onEntityInitialized function and other basic info on working with page code here: https://customerfx.com/article/getting-started-with-writing-code-for-bp…

Hope this helps get you started.

Ryan

Show all comments