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 0

Like

1 comments

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 1

Like

1 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…

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 0

Like

1 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*/,

 

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 0

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 0

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 0

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

I created a harmony of data which comes from external web services. For example, I retrieved dataA for ColumnA, dataB for ColumnB, dataC for ColumnC etc. I want to INSERT this data to section object table which section page based on.



How can i bind these things?

Like 0

Like

1 comments

Hello,

 

You can create a business process in which you will fill in the required fields received from the web service.

 

Details on the academy website:

https://academy.creatio.com/docs/user/bpm_tools/process_elements_refere…

Show all comments

Hello community,



Can you please advise me how to run the server code (C#) from a client page (JS).

The business process has a delay when launching, so this method is not the best solution in my case.

 

Thank you in advance.

Mariia

Like 0

Like

2 comments
Best reply

Hello,

 

Please check the following link https://academy.creatio.com/docs/developer/back-end_development/configu…;



Best Regards,

Tetiana Bakai

Hello,

 

Please check the following link https://academy.creatio.com/docs/developer/back-end_development/configu…;



Best Regards,

Tetiana Bakai

As Tetiana mentioned, how this is typically done in Creatio is by creating a configuration web service that you call from your client-side js code. It's actually one of my favorite parts of Creatio and makes for a very powerful development experience and allows you to keep the UI very quick by passing things between the client and the server and performing operations on the server rather than the client. Along with the Academy article Tetiana shared, I also have a write up of how to create a configuration web service and call it from client-side code here: https://customerfx.com/article/creating-a-web-service-and-consuming-it-…

Ryan

Show all comments