Hello,

I'm trying to add a button to contact page details (Contacts_FormPage), I'm currently using Creatio on cloud version 8.1.3.6734 with Freedom UI
I followed these steps:

  1. Navigated to Settings > Advanced Settings
  2. Created a new package, and added ProductCore dependency
  3. Created a Replacing view model with the code name ContactPageV2
  4. Added the code:
  5. define("ContactPageV2", [], function() {
       console.log("ContactPageV2 module loaded");
       return {
           methods: {
               onGenerateLinkClick: function() {
                   console.log("Generate Link button clicked");
               }
           },
           diff: [
               {
                   "operation": "insert",
                   "name": "GenerateLinkButton",
                   "parentName": "ActionButtonsContainer",
                   "propertyName": "items",
                   "values": {
                       "itemType": Terrasoft.ViewItemType.BUTTON,
                       "caption": "Generate Link",
                       "click": {"bindTo": "onGenerateLinkClick"}
                   }
               }
           ]
       };
    });
  6. After saving, I compiled the package
  7. Emptied the cache of the browser, but nothing is showing not even the console log "ContactPageV2 module loaded"

 

Please help as I'm not sure what I'm doing wrong or what steps am I missing (I'm a newbie to this platform).
Thank you in advance.

Like 0

Like

2 comments
Best reply

Creatio has two types of pages, Freedom UI pages and classic pages. They are completely separate/different pages. The ContactPageV2 is the classic page, not the Freedom UI page which is Contacts_FormPage

To add the button that executes your code on the Freedom UI page:

  1. Go to the contact page, click the small gear on the top right corner of the page to edit
  2. Save it to make a copy in your package (see the Side Note at end of article here to force the save to go into your package, if needed)
  3. Add a button to the page where you want it
  4. Open the code for the page (clicking one of the icons at the top right of the page designer)
  5. Add the request handler for the button (the code that will execute when clicked) following steps here: https://customerfx.com/article/adding-a-button-to-execute-custom-code-o…

Ryan

Creatio has two types of pages, Freedom UI pages and classic pages. They are completely separate/different pages. The ContactPageV2 is the classic page, not the Freedom UI page which is Contacts_FormPage

To add the button that executes your code on the Freedom UI page:

  1. Go to the contact page, click the small gear on the top right corner of the page to edit
  2. Save it to make a copy in your package (see the Side Note at end of article here to force the save to go into your package, if needed)
  3. Add a button to the page where you want it
  4. Open the code for the page (clicking one of the icons at the top right of the page designer)
  5. Add the request handler for the button (the code that will execute when clicked) following steps here: https://customerfx.com/article/adding-a-button-to-execute-custom-code-o…

Ryan

Thank you! 
I was able to add it following your explanation. 
And yes I need to add it to my custom package since I'm trying to create a connector that can be used by anyone later on.
That was very insightful, thanks again!

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

Hi community,

I'm following the available documentation to achieve this but when I try to create the Replacing view model module the system doesn't find any existing "Parent object" with the code OperatorSingleWindowPage.

I already created a custom package called "Test", as you may notice in the previous screenshots and I can't find anymore information about this problem.

I don't know if the more recent versions of Creatio doesn't support this anymore. I would like to know if I'm doing something wrong and if there is any other way to hide that panel.

The version of the environment I'm using is 8.0.8.4807

Thanks in advance for your help! 

Like 0

Like

2 comments
Best reply

Ryan Farley,

It worked, thank you very much!

Show all comments

Good day! Is there a possibility to save summaries profile data for all users like in 'GridSettingsPage'? Permission for such operation must be available only for system administrators

Like 1

Like

1 comments

Hello Sandra,

 

There is no OOB tool that can help you to achieve your business task but you can do some inserts via SQL tools. The table that you need is called 'SysProfileData' and the Key that you need is called 'Section-Account-MainGrid-Summary'. So having this information you can do the insert for some specific Contacts in the system.

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

What is the easiest way to call a method defined in the client module source code of one detail from the client module source code of another detail?  The details are in different tabs.

Like 0

Like

1 comments

You can do this using the sandbox. See https://academy.creatio.com/docs/developer/front_end_development/sandbo…

Basically, if detail1 needs to call a function defined in detail2, in detail1 you'd define a message with mode PTP and direction PUBLISH. In detail2, you'd define the same message with mode PTP and direction SUBSCRIBE. Detail1 would publish the message via the sandbox when it wants to invoke the function in the other detail. Then in detail2, when the message is received, it would execute the function. 

Hope this helps get you started. Here's a sample from an older post of sending messages between details: https://community.creatio.com/articles/implementing-messages-sandbox-de…

Ryan

Show all comments

I am developing an application using a Creatio trial (before implementing on the development server).  I have saved the application as a package, and have imported back into another Creatio trial.  Everything works fine.

 

The problem I have is I am not able to edit the JavaScript I have developed in the package's replacing client modules.  When I view the client module from the Configuration page, I can see the JavaScript that I have developed, but when I try to edit the JavaScript from the section wizard, there is only a 'define' function with empty sections, not the JavaScript that I developed.

 

Is it possible to continue developing client module JavaScript from one trial of Creatio to another?

 

Thanks in advance,

Like 0

Like

1 comments

Dear Gareth, 



The logic behind this behavior is that when any changes comes in the package they should not be directly changed since packages can be distributed by third-party publishers. 

Only way to change functionality installed is to re-define the code or add new methods within the new replacing module in your custom packages. 



Kind regards,

Roman

 

Show all comments

I have this Action Item and onClick of it, want to trigger a Business Process. How can this be achieved?

 

Thanks

Like 0

Like

2 comments

Dear Anu, 



Can you please specify with more details on how exactly would you like to trigger the process? 



Thank you. 

AnuRoman Brown,



Here is the Academy article to call the BP (Business Process) from the Action items menu.

https://academy.creatio.com/docs/developer/integrations_and_api/busines…

 

Sample,

 

define("AccountPageV2", ["ProcessModuleUtilities"], function(ProcessModuleUtilities) {
    return {
        entitySchemaName: "Account",
        methods: {
            // Проверяет, заполнено ли поле [Основной контакт] страницы.
            isAccountPrimaryContactSet: function() {
                return this.get("PrimaryContact") ? true : false;
            },
            // Переопределение базового виртуального метода, возвращающего коллекцию действий страницы редактирования.
            getActions: function() {
                var actionMenuItems = this.callParent(arguments);
                actionMenuItems.addItem(this.getActionsMenuItem({
                    Type: "Terrasoft.MenuSeparator",
                    Caption: ""
                }));
                actionMenuItems.addItem(this.getActionsMenuItem({
                    "Caption": { bindTo: "Resources.Strings.CallProcessCaption" },
                    "Tag": "callCustomProcess"                
                }));
                return actionMenuItems;
            },
            // call you porcess
            callCustomProcess: function() {
                var contactParameter = this.get("PrimaryContact");
                var args = {
                    // Process name
                    sysProcessName: "UsrCustomProcess",
                    // parameters process
                    parameters: {
                        ProcessSchemaContactParameter: contactParameter.value
                    }
                };
                // run process
                ProcessModuleUtilities.executeProcess(args);
            }
        }
    };
});





BR,

Bhoobalan Palanivelu

Show all comments

Hello Comunity! 

 

I know in the last version is restricted the replace of the modules. There is a way to create a new module for LeftPanelTopMenuModule? where is calling this module to remplace the client schema with the new module?

 

Regards,

 

Like 0

Like

4 comments

Hello Frederico,

 

I have the steps written up to override a module here: https://customerfx.com/article/overriding-modules-in-creatio-formerly-bpmonline/

 

Ryan

Ryan Farley,

Thanks Rayan. Regards,

Hello Frederico,

 

Hope you're doing well.

 

Thanking Ryan for creating and sharing the useful article. We can confirm that the steps described in the mentioned instruction can be used for overriding the needed module.

 

At the same time, we don't recommend this way because in the case when you have more than 2 overriding modules, it will not work properly or won't work at all.

 

Best regards,

Roman

Roman Rak,



Since you don't recommend this way, may I know any other way to do this?



Regards,

Solem.

Show all comments

I have read this article regarding adding multiple value to a detail.

Link - https://academy.creatio.com/documents/technic-sdk/7-15/adding-multiple-records-detail

 

 

But I do not understand these variable values. The opportunity and contact are the sections that are already created in the system. I want to know what values should I put in custom detail schema.

 

Details of Objects (every object is custom) -

  1. Client section with a detail of Partners
  2. Partners detail is made from Partner section

I want to change the Partner detail in Client to add multiple records. But I do not understand what should be the values of rootEntitySchemaName, rootColumnName, relatedEntitySchemaName, relatedColumnName.

 

Can anyone please help in this matter?

 

Thanks 

Ram

Like 0

Like

4 comments
Best reply

Hello Ramnath,

 

rootEntitySchemaName is the name of the parent object. This is likely the object for the page where the detail is located, so if the detail is on the Account page, this would be Account

 

rootColumnName is the name of the column on the detail object that relates it to the parent object. In the example of being on the Account page, this would be the name of the column on the detail object that is the account lookup, such as UsrAccount

 

relatedEntitySchemaName is the name of the object you're looking up to add to the detail. So, if the lookup is looking up contacts, this would be Contact

 

relatedColumnName is the name of the column on the detail object that the result from the lookup is stored in. So in the example of looking up contacts, this would be a contact lookup on the detail object, such as UsrContact.

 

Maybe this article will help? https://customerfx.com/article/adding-to-a-detail-from-a-lookup-in-crea…

 

Ryan

Hello Ramnath,

 

rootEntitySchemaName is the name of the parent object. This is likely the object for the page where the detail is located, so if the detail is on the Account page, this would be Account

 

rootColumnName is the name of the column on the detail object that relates it to the parent object. In the example of being on the Account page, this would be the name of the column on the detail object that is the account lookup, such as UsrAccount

 

relatedEntitySchemaName is the name of the object you're looking up to add to the detail. So, if the lookup is looking up contacts, this would be Contact

 

relatedColumnName is the name of the column on the detail object that the result from the lookup is stored in. So in the example of looking up contacts, this would be a contact lookup on the detail object, such as UsrContact.

 

Maybe this article will help? https://customerfx.com/article/adding-to-a-detail-from-a-lookup-in-crea…

 

Ryan

Ryan,

 

Thanks for helping me out.

 

Please guide me in this situation more.

Overview of whole scenario

I created a custom detail in a custom section.  I have created a Section Contacts (neither base object nor replacing object, It is custom made) and Clients Section. Clients section has a detail Contacts. The detail's object name is the Contacts section.

 

Section Page - UsrClients

Detail object - UsrContacts (has lookup of UsrClient for connecting record to UsrClients with other inherited columns present in UsrContacts)

 

Now the name will be

rootEntitySchemaName - UsrClients (section page object name)

rootColumnName - UsrClient  (the referencing lookup present in UsrContacts)

relatedEntitySchemaName - UsrContacts (Section page from where records will be read)

relatedColumnName - UsrContact (lookup present in detail)

 

Now the problem is how can I create a lookup pointing to the same object on which detail is build.

Lookup points to UsrContacts and detail is also created on UsrContacts.

 

RAMNATH SHARMA,

 

The detail should be a separate object. Like in the example on the academy, OpportunityContact object on which the detail is built on contains Opportunity and Contact columns. In your case, you would need to create a separate object for the detail that would contain UsrClients and UscrContacts columns, and build the detail on this object. 

Dennis Hudson,

 

Yes, you are right. I have created a new object with 2 looks fields to add this functionality. And it works.

Thanks

Show all comments