We're trying to set it up so that one of our mini pages used for record creation (wherever the record creation is started from, as there are several screens with a button to create the record) always has a default value set. We can't set the default on the entity, as records coming in from the integrations shouldn't have these fields set to any default, only set to whatever comes in through the interface. Is there any configuration that can be done to set default values for pages themselves?

 

We know about setting defaults when calling the crt.CreateRecordRequest request which is done from the calling page, but would ideally like to be able to set it one time for the creation mini page itself to avoid code duplication. We are on 8.1.0

Like 1

Like

5 comments

You can setup a business rule if the attribute is not filled in then you set a static value. This will work only on the interface.

Thanks for the suggestion Franck, and interesting/concerning that the entity-level business rules only apply when creating records through the UI and not for all data!

 

Unfortunately the business rule value setting is much too limited in Creatio for what we need, only being able to set to a constant/static value which is defined when setting up the business rule. We need to be setting the value based on some logic through code, but would ideally be doing so with declarative code rather than imperative code which modifies the fields manually.

Hello Harvey,

The most general way to set the default values for a mini-page is to transfer them in ModelInitConfigs via crt.OpenPageRequest:

modelInitConfigs: [{defaultValues: [{AttributeName: 'AttributeValue'}]}]

But if you want to avoid transferring the values in every place you open the mini-page, consider the following implementation in the mini-page view model:

  1. Set the attribute value in the "crt.HandleViewModelInitRequest":
    request.$context.AttributeName = “AttributeValue”;
  2. Provide it not to be overridden to default null value in "crt.HandleViewModelAttributeChangeRequest":
    if (request.attributeName === "AttributeName" && request.value === null) {
          request.$context.AttributeName = “AttributeValue”;
    }

     

Best regards, Natalia

Hi Natalia,

 

Thanks for the reply, those will definitely be useful - for example I didn't know you could set default values when calling the crt.OpenPageRequest, I thought it was only possible to do so using the crt.CreateRecordRequest, so thanks for that!

 

I believe the workaround for putting the logic in the mini-page would mostly work, but with the following caveats:

1. You would not be able to clear the value of the field manually, which is unfortunate

2. This would make a change to the page that would cause the confirmation dialog to appear if closing the mini-page without the user making any modifications to data - not the end of the world, but it would be nice to avoid that

 

A quick question - what is the difference between simply assigning a request.$context.AttributeName using 

request.$context.AttributeName = "value"

Vs using the _setAttributeValue method in your reply? Is there any functional difference between the two, or is it just preference?

 

Many thanks,

Harvey

Harvey Adcock,

 

Hi, 

Sure, setting the mini page default values via HandleViewModel InitRequest and HandleViewModelAttributeChangeRequest has some disadvantages. That’s why we recommend using ModelInitConfigs in OpenPageRequest.

 

However, it may still be used if the user doesn’t need to set the field value to null. Especially considering the facts that:

- removing the string field means setting a value to an empty string (not null);

- the numeric field value might be set to 0 instead of removing it.

 

The question of silent saving has already been discussed in the separate feed - https://community.creatio.com/questions/it-possible-make-changes-attributes-code-freedom-ui-silently .

 

Regarding your question about setting the attribute value – I clarified it with our R&D department. There is no functional difference between the two approaches, but only the direct assigning is recommended to use as the most stable method:

request.$context.AttributeName = "value"

Thank you for such an important question. I have already changed my examples accordingly.

 

Best regards,

Natalia

Show all comments

We've got a requirement to run some async entity event listener code, but when following the academy article for that ( https://academy.creatio.com/docs/7-18/developer/back_end_development/ob… ) and trying to use the arguments.OldEntityColumnValues property of the EntityEventAsyncOperationArgs arguments parameter passed in, we get the following compilation error which we cannot seem to resolve:

 

From looking online for general resolutions, it looks like we maybe need to add this assembly to the web.config file, but we're on a cloud instance so presume this isn't a feasible resolution.

 

Any advice would be greatly appreciated.

 

Reduced version of the code (without usings etc shown) that throws the error below:

public class UsrAsyncSendLeadAssociation: IEntityEventAsyncOperation
{
    public void Execute(UserConnection userConnection, EntityEventAsyncOperationArgs arguments) {
        var oldModVal = arguments.OldEntityColumnValues;
    }
}

 

Like 0

Like

1 comments

Hello,

As a quick solution, you should disable the option "Compile into a separate assembly" in the package where the schema is located.

After this, the problem should be resolved.

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've noticed there are a lot of HTML Style elements added to the Creatio pages' DOM, and I was wondering what generates and sends these to the browser so that some of them can be modified. This appears to be different from the normal CSS Linking that happens in Creatio, so I presume there must be some different method for overriding them. See below for an example of one of the style elements I want to modify:

Like 1

Like

4 comments

Hello Harvey,

 

The style HTML tag (inside the head tag) usually contains CSS rules, which are crucial for the init page rendering, or the most general CSS rules. These rules could be overridden in a common way:

  1. Create a new module, choose LESS in the left panel, and add the CSS rules.
  2. Add the name of this module to the dependencies in the Page client module, starting with the prefix “css!”

Here is an additional example - https://community.creatio.com/questions/how-can-i-hide-task-properties-pre-config-page .

 

Best regards,

Natalia

Hi Natalia,

 

Unfortunately this doesn't seem to be working for me for 2 reasons:

  1. The style in the CSS is not taking precedent over the OOTB style that is included in the style element in the DOM. Does Creatio have any way of overriding the OOTB elements' styles without resorting to using !important everywhere?
  2. The client module seems to be "compiling" my code and modifying it from what I wrote (first line after this) into what appears in the browser sources (second line after this point) and these are completely different - Creatio cannot take 40 pixels off 100% height and conclude that it's always going to be 60% height:
    1. height: calc(100% - 40px)
    2. height: calc(60%)

 

Do you know of any resolution to these issues?

Hi Harvey

 

You can use this addon to apply CSS styles globally: https://marketplace.creatio.com/app/experceo-global-jscss-editor-creatio

If you can identify the selector, you can easily override the CSS properties values using !important keyword.

I hope this helps!

Mohamed Ouederni,

Thanks Mohamed, generally we're trying to keep add-ons to a minimum unless strictly necessary to avoid too many dependencies and potential points of failure, but worth knowing.

Using Natalia's recommendation, I was able to apply the CSS - for any others having this issue, the resolution to my first issue was just to set the style as being important, though another resolution might be to make the selector more specific (CSS specificity) than the ones acting upon it. And the resolution to my second issue was that it's a LESS CSS issue rather than Creatio's issue, but it can be worked around using the following escaping of the calculation:

height: calc(~"100% - 40px")

Which I found from this Stack Overflow question: https://stackoverflow.com/questions/11972084/how-to-prevent-less-from-t…

Show all comments

Hi Team,



I want to use the below min.js file as a script

https://public.tableau.com/javascripts/api/tableau.embedding.3.latest.min.js

to  load the tableau as a IFrame and use the functions of the scriot file add filter to the loaded URL. 

 

To implement it the min.js file has to be included in Creatio. How do we add this file in Creatio?



Regards,

Adharsh S

Like 0

Like

2 comments

Hello, 

None of this is tested (and I've not used the Tableau embed script to know if it would work this way), but you can try using require for it by adding the following: 

requirejs.config({
	paths: {
		Tableau: 'https://public.tableau.com/javascripts/api/tableau.embedding.3.latest.min.js'
	}
});

Note, you can add this before the page code define and then include as a reference for it: 

define("UsrMyCustomObject1Page", ["Tableau"], function (Tableau) {

Then use as something like: 

const viz = new Tableau.TableauViz();
viz.src = 'https://my-server/views/my-workbook/my-view';
viz.toolbar = 'hidden';
document.getElementById('tableauVizElement').appendChild(viz);

Ryan

Hi Adharsh



You can use this addon to add JS scripts globally: https://marketplace.creatio.com/app/experceo-global-jscss-editor-creatio

 

Go to System Settings -> ExpGlobalJSValue to update the global JavaScript script.

 

require(["https://public.tableau.com/javascripts/api/tableau.embedding.3.latest.min.js], function(lib) { 

       window.Tableau = lib;

});



Then you can use window.Tableau
 in your js code.



Hope this helps!

Show all comments

Is it possible to set up useful number truncation in Creatio for Measure/KPI elements in Freedom UI? OOTB, if a number being shown in the Measure component is too long, it just gets cut off and ellipses put at the end to indicate it's not all showing, but this means the user cannot tell how big the number is at all! It could have 3, 6, 9 or more extra zeroes hidden in the ellipsis. e.g. the following could be showing 191 million, 191 billion, 191 trillion etc:

 

Ideally it would be possible to set it up so that you can choose to have automatic truncation using abbreviations like 10M or 20K if the number is too long, but it would also be nice if we could specify in the number formatting that the number should always be shown in thousands, millions etc - possibly something like specifying "{0k}" in the number format for always showing the number in thousands. Don't know how possible any of this is today or would require changes by Creatio, but any advice appreciated. Currently using Creatio 8.1.0

Like 1

Like

1 comments

Yes this is getting pretty frustrating among metrics and graphs alike for a couple years now, not to be able to set to K or M etc...

Show all comments

Hi,

 

I need to know if we can increase the size of a mini page in Freedom UI?

Like 1

Like

2 comments

Not yet without coding, it is in the pipes for S1 2024 according to the roadmap.

Hello!

 

Unfortunately, there is no such option at the moment. We have created a corresponding request for the development team to reconsider this logic.

 

As for now, we cannot provide you with specific recommendations on your question at this time, as such a scenario has not been studied and we have no examples of such a realization.

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

7 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

Thanks Natalia, it would be really useful to have the functionality for making silent changes from code that existed in Classic UI added back into Freedom UI - see this post for what was possible in Classic: https://community.creatio.com/questions/change-value-field-without-firing-changed-events

 

The utility can be in setting fields from code when a create record page loads based on more complicated conditions than you can define in business rules/by other means, but not causing the user additional clicks to cancel or think that they might lose work.

Possibly some usage of this guide might be able to fulfil the ability to discard such data, though it would probably be quite tedious to implement in this scenario: https://customerfx.com/article/suppressing-the-unsaved-data-prompt-when-canceling-a-creatio-freedom-ui-modal-dialog/

Show all comments

Dear,

On our development environment we are having the following error when we try to run compilation:

Compilation errors

File name: OrderSchema.Custom.cs

Code CS1061 - Line 1727

'IEnumerable<EntityColumnValue>' does not contain a definition for 'Any' and no accessible extension method 'Any' accepting a first argument of type 'IEnumerable<EntityColumnValue>' could be found (are you missing a using directive or an assembly reference?)

We tryed to restore Order and OrderPageV2 from the prod

Recompile all environment

Clear Redis and restart application

I can figure where from is this error coming...

Thank you for help !

Nicolas

Like 0

Like

8 comments
Best reply

Hello,

Yes, indeed, in this case, it is necessary to redesign processes to be interpreted, not compiled.

 

https://academy.creatio.com/docs/8.x/no-code-customization/bpm_tools/pr…

The error was coming from a script in which variables were not well declared

Hello,

Yes, indeed, in this case, it is necessary to redesign processes to be interpreted, not compiled.

 

https://academy.creatio.com/docs/8.x/no-code-customization/bpm_tools/pr…

hello!
I have the same errors during compilation, but in OpportunitySchema.Opportunity.cs file, recompilaiton didnt help

Dmitrii Balashov,

 

Please specify if you already tried to follow the instructions provided above to fix this issue:

"it is necessary to redesign processes to be interpreted, not compiled."

https://academy.creatio.com/docs/8.x/no-code-customization/bpm-tools/pr…

I've only just recently started working with Creatio, but as I understand it this relates to writing Script task correctly


But after deleting all my custom script tasks the problem is still present on after recompiling

I contacted support and it looks like this is an issue with Opportunity package in version 8.1.3, which should be resolved in 8.1.4

Dear Dmitrii Balashov,

These compilation errors are fixed for 8.1.4, but you can go to the workaround solution:

    1) Unlock the Opportunity package for the hotfix.
    2) Open the embedded process in the Opportunity object schema.
    3) Change three lines (8, 10, 11) in the OpportunitySaving method to use the full definition of System.Linq.Enumerable save process and compile the system.
    4) Lock the Opportunity package.



BP

 

Full definition of System.Linq.Enumerable

 

Best regards,

Andrii

Andrii Kurta,

Thank you!

Show all comments

I'm trying to improve a UX flow in one of our clients, and to do so I'm hoping it would be possible to create a modal dialog box which can have a date selected from a date picker, but I can't see any obvious ways - is there anything that can be done for this? I saw this excellent guide on getting a Yes/No type dialog in Freedom UI, but I can't see any extra capabilities for potentially adding more freeform user interaction: https://customerfx.com/article/showing-a-message-dialog-or-confirmation…

 

Any help would be greatly appreciated. Currently on Creatio CRM 8.1.0

Like 0

Like

10 comments
Best reply

Hi Harvey,

I've done this in several areas in our system using modal forms (actually called a Mini Page in the page types dialog you select from when creating a new page). Here's an example of a dialog allowing the case status to be set from a list (we don't use editable lists yet since there's no way to add validators yet to lists):

This is just a modal/mini form created using the form designer. The nice part about this is that it can be bound directly to the object (I have many that aren't bound as well, depending on the scenario).

You can open this specific page for a particular record using this method (also possible with an action in no code designer as well) https://customerfx.com/article/opening-a-record-for-edit-in-a-specific-…

Ryan

Hi Harvey,

I've done this in several areas in our system using modal forms (actually called a Mini Page in the page types dialog you select from when creating a new page). Here's an example of a dialog allowing the case status to be set from a list (we don't use editable lists yet since there's no way to add validators yet to lists):

This is just a modal/mini form created using the form designer. The nice part about this is that it can be bound directly to the object (I have many that aren't bound as well, depending on the scenario).

You can open this specific page for a particular record using this method (also possible with an action in no code designer as well) https://customerfx.com/article/opening-a-record-for-edit-in-a-specific-…

Ryan

Ryan Farley,

Thanks for the reply Ryan, that seems like exactly what we're after! I had wondered about using a Mini Page for it but wasn't sure how that would be hooked in to work. How are you triggering the mini page to be displayed, I take it it's from code? Is it using something like the following when clicking a button or whatever the trigger is:

const handlerChain = sdk.HandlerChainService.instance;
 
await handlerChain.process({
	type: "crt.CreateRecordRequest",
	entityName: "CustomEntity",
	entityPageName: "CustomEntityMiniPage",
	$context: request.$context,
	defaultValues: [{
		attributeName: "Col1",
		value: "Val1"
	}]
});

 

Or are you able to get a Mini Page to appear without some entity it's based over? For our requirements, the data field to be modified would actually be on the entity of the Form Page the user was currently on, so it didn't seem like the crt.CreateRecordRequest would make sense, but the crt.OpenPageRequest always seems to open the Mini Page as though it were a full-sized page, and the crt.UpdateRecordRequest I hadn't tried yet as I didn't already have a Mini Page for the entity and thought it likely wouldn't work as the mini pages are generally used for adding data, not editing?

 

Thanks again.

There's so many uses of modal (mini) pages beyond just what mini pages were used for typically in classic ui. 

IMO It's one of the best additions to Freedom UI, the ability to create dialogs for specific purposes, bound to a record or not, that really enhances the user experience. This is a prompt for selecting parameters for a report.

Ryan

Harvey Adcock,

You would use an "crt.OpenPageRequest". I edited my original post to include a link to an article showing how to open it to edit a record. 

Ryan

Harvey Adcock,

In older versions the "crt.OpenPageRequest" did open the page in full screen, even if a modal page. But I think that was fixed in 8.0.10 and has been working for me (it does open as a modal)

Ryan

Perfect, thanks Ryan, really helpful!

Ryan Farley,

 

One more question, is there a way to pass information from the current page to the page being opened via the OpenPageRequest? Trying defaultValues, similar to what you would use when creating a new record from a page launched by code, doesn't seem to have any effect, and I can't see any other candidates for it.

Harvey Adcock,

I’m not 100% sure but I think you can only pass values for a new record (crt.CreateRecordRequest) only. 

Alternatively, you could write some values to a global or use the StorageUtilities module and then read from the form once opened. See StorageUtilities here: https://customerfx.com/article/persisting-data-between-pages-in-creatio…

Ryan

Harvey Adcock,

You can try something like this to pass defaultValues

request.$context.executeRequest({
	type: "crt.OpenPageRequest",
	$context: request.$context,
	schemaName: "UsrYourCustom_FormPage",
	modelInitConfigs: [
		{
			action: sdk.ModelInPageAction.Edit,
			recordId: yourRecordId
		},
		{
			defaultValues: [
				{
					attributeName: "someName",
					value: "someValue"
				}
			]
		}
	]
});

 

Alex Zaslavsky,

 

Does this passing of values work for passing a value into a Page Parameter? Or is there some way to do so? The value I want to pass to a new page (either through OpenPageRequest or CreateRecordRequest) is not on the entity, it's just a parameter on a page, but we need to set this value when opening the page.

Show all comments