Create Custom Components
As described in the topic Component Architecture, each of the ThingWorx Navigate components is made up of two sub-components, the user interface sub-component and the business logic sub-component. The business logic sub-component is also made up of two parts, the Base Business Logic and the Business Logic Implementation, which we’ll refer to in this topic as the base component and the implementation respectively.
Out-of-the-box, each base component comes with one or more implementations. Each implementation is designed to show specific information in the user interface. To show different information, you can customize your component by creating a custom implementation. For example, out of the box the Item Identity base component comes with two implementations, Part Identity and Task Identity. You can also create a custom implementation of the Item Identity base component, such as Document Identity.
Creating a custom implementation for a component involves extending an existing base component or an existing implementation and then overriding the necessary services. The sections below contain detailed steps and an example.
Create a Custom Implementation by Extending a Base Component 
Follow these steps to create a custom implementation from an existing base component:
1. Choose an existing base component to use as a starting point for your custom implementation. Find the base component in the following table and note its Thing Template and Project, according to your version of ThingWorx Navigate. You’ll need this information later.
Base Component
Thing Template
Project (ThingWorx Navigate 9.0)
Project (ThingWorx Navigate 9.1 and later)
Attributes
PTC.Nav.AttributesBusinessLogicThingTemplate
PTC.Nav.AttributesProject
PTC.Nav.AttributesBusinessLogicProject
Item Identity
PTC.Nav.ItemIdentityBusinessLogicThingTemplate
PTC.Nav.ItemIdentityProject
PTC.Nav.ItemIdentityBusinessLogicProject
Item List
PTC.Nav.ItemListBusinessLogicThingTemplate
PTC.Nav.ItemListProject
PTC.Nav.ItemListBusinessLogicProject
Progress
PTC.Nav.ProgressBusinessLogicThingTemplate
PTC.Nav.ProgressProject
PTC.Nav.ProgressBusinessLogicProject
Tiles
PTC.Nav.TilesBusinessLogicThingTemplate
PTC.Nav.TilesProject
PTC.Nav.TilesBusinessLogicProject
2. Create a project for your custom implementation. Under Project Dependencies, enter the project noted in Step 1. Save the project.
3. Create a Thing Template for your custom implementation. Under Project, enter the project created in Step 2. Under Base Thing Template, enter the Thing Template noted in Step 1.
4. Create a Thing for your custom implementation. Under Project, enter the project created in Step 2. Under Base Thing Template, enter the Thing Template created in Step 3.
5. In the Thing you created, click on the Services tab. Then click pencil icon to override the GetImplementationConfigurationVersion service and set a version for your implementation. You can use any value for this version. Save the Thing.
6. Identify which services you need to override for your custom implementation. For more information on services for out-of-the-box components, find the topic for the component you are extending under Available Components, and see the Customization Services table.
7. In the Thing Template you created, click on the Services tab. Then click pencil icon to override the necessary services. It’s recommended that you override the GetConfigurations service before overriding other services.
In the code for the GetConfigurations service, set the version for implementationConfigurationVersion to match the version set for GetImplementationConfigurationVersion in Step 5. Skipping this step may cause compatibility issues in future releases of ThingWorx Navigate.
8. Override the remaining necessary services. When overriding a service that receives the configuration as a parameter, first call the Migrate service in your code and pass the base and implementation versions.
To determine the value to use for targetBaseVersion in the Migrate service, execute the service GetBaseConfigurationVersion on the Thing you created in Step 4. Do not call the GetBaseConfigurationVersion service code and return its value.
When setting targetImplementationVersion in the Migrate service, use the version you set earlier in Step 5.
See the topic Versioning and Migration for more information on calling the Migrate service.
* 
When overriding services, do not override services with the category PTC.Nav.Private.
9. Save the Thing Template. Now your custom implementation is ready to use. To use the implementation, create a mashup. Add the base component for the implementation to the mashup, and click Gear icon. In the Configuration Type drop-down menu, select the configuration that belongs to your custom implementation.
Create a Custom Implementation by Extending an Implementation 
Follow these steps to create a custom implementation from an existing implementation:
1. Choose an existing implementation to use as a starting point for your custom implementation.
If you’re using an out-of-the-box implementation, find it in the following table and note its Thing Template and Project, according to your version of ThingWorx Navigate. You’ll need this information later.
If you’re using a custom implementation, note its Thing Template and Project. You’ll need this information later.
Implementation
Thing Template
Project (ThingWorx Navigate 9.0)
Project (ThingWorx Navigate 9.1 and later)
Activity
PTC.Nav.ActivityBusinessLogicThingTemplate
PTC.Nav.ItemListProject
PTC.Nav.ActivityBusinessLogicProject
Affected Items
PTC.Nav.AffectedItemsBusinessLogicThingTemplate
PTC.Nav.ItemListProject
PTC.Nav.AttachmentsBusinessLogicProject
Attachments
PTC.Nav.AttachmentsBusinessLogicThingTemplate
PTC.Nav.ItemListProject
PTC.Nav.AffectedItemsBusinessLogicProject
Attributes Generic
PTC.Nav.AttributesGenericBusinessLogicThingTemplate
PTC.Nav.AttributesProject
PTC.Nav.AttributesGenericBusinessLogicProject
Part Identity
PTC.Nav.PartIdentityBusinessLogicThingTemplate
PTC.Nav.ItemIdentityProject
PTC.Nav.PartIdentityBusinessLogicProject
Task Identity
PTC.Nav.TaskIdentityBusinessLogicThingTemplate
PTC.Nav.ItemIdentityProject
PTC.Nav.TaskIdentityBusinessLogicProject
Task Progress
PTC.Nav.TaskProgressBusinessLogicThingTemplate
PTC.Nav.ProgressProject
PTC.Nav.TaskProgressBusinessLogicProject
Tasks
PTC.Nav.TaskListBusinessLogicThingTemplate
PTC.Nav.ItemListProject
PTC.Nav.TaskListBusinessLogicProject
Tiles Generic
PTC.Nav.TilesGenericBusinessLogicThingTemplate
PTC.Nav.TilesProject
PTC.Nav.TilesGenericBusinessLogicProject
2. Create a project for your custom implementation. Under Project Dependencies, enter the project noted in Step 1. Save the project.
3. Create a Thing Template for your custom implementation. Under Project, enter the project created in Step 2. Under Base Thing Template, enter the Thing Template noted in Step 1.
4. Create a Thing for your custom implementation. Under Project, enter the project created in Step 2. Under Base Thing Template, enter the Thing Template created in Step 3.
5. In the Thing you created, click on the Services tab.
Click pencil icon to override GetBaseMigrationVersion with your version of ThingWorx Navigate, for example 9.0.0 or 9.1.0.
Click pencil icon to override GetImplementationConfigurationVersion with your version of ThingWorx Navigate, for example 9.0.0 or 9.1.0.
6. Save the Thing.
7. Identify which services you need to override for your custom implementation. For more information on services for out-of-the-box components, find the topic for the component you are extending under Available Components, and see the Customization Services table.
8. In the Thing Template you created, click on the Services tab. Then click pencil icon to override the necessary services. It’s recommended that you override the GetConfigurations service before overriding other services.
* 
When overriding the GetConfigurations service, changing the configuration structure from its out-of-the-box structure is not supported. Only change values for individual JSON properties. For more information, see the topic Examples of Changes to Configuration Properties.
In the configuration, make sure to set the value of the implementationConfigurationVersion property to be the same as the value returned by the GetImplementationConfigurationVersion service.
9. Override the remaining necessary services. When overriding a service that receives the configuration as a parameter, first call the Migrate service in your code and pass the base and implementation versions.
To determine the base version to pass to the Migrate service, execute the service GetBaseConfigurationVersion on the Thing you created in Step 4. Do not call the GetBaseConfigurationVersion service and return its value.
To determine the implementation version to pass to the Migrate service, execute the service GetImplementationConfigurationVersion on the Thing you created in Step 4. Do not call the GetImplementationConfigurationVersion service and return its value.
See the topic Versioning and Migration for more information on calling the Migrate service.
* 
When overriding services, do not override services with the category PTC.Nav.Private.
10. Save the Thing Template. Now your custom implementation is ready to use. To use the implementation, create a mashup. Add the base component for the implementation to the mashup, and click Gear icon. In the Configuration Type drop-down menu, select the configuration that belongs to your custom implementation.
Example: Create a Parts List Implementation 
The following example shows how to create a custom implementation called Parts List, which is an implementation of the Item List base component. Parts List receives a part as input and returns the first level of parts that it contains.
* 
The following example is designed to work in ThingWorx Navigate 9.0, and the version values used in code snippets are correct for that version of ThingWorx Navigate. To follow this example in a later version of ThingWorx Navigate, make sure to use the correct version values in your code.
1. In ThingWorx Composer, create a new project named Demo.PartsListProject.
In ThingWorx Navigate 9.0, enter PTC.Nav.ItemListProject under Project Dependencies.
In ThingWorx Navigate 9.1 and later versions, enter PTC.Nav.ItemListBusinessLogicProject under Project Dependencies.
2. Create a new Thing Template named Demo.PartsListBusinessLogicThingTemplate. Set the Project to Demo.PartsListProject and set the Base Thing Template to PTC.Nav.ItemListBusinessLogicThingTemplate.
3. Create a Thing named Demo.PartsListBusinessLogicThing. Set the Project to Demo.PartsListProject and set the Base Thing Template to Demo.PartsListBusinessLogicThingTemplate.
4. Click on the Services tab and find the GetImplementationConfigurationVersion service. Click to override the service and set the version to 1.0.0 using the following code:
result = "1.0.0";
Click Done. Then click Save to save the Thing.
5. Check the Customization Services table for the Item List and identify the services that need to be overridden on the Thing Template. For this custom implementation, we need to override three services:
GetConfigurations– This service returns the configurations available for the implementation. We’ll edit it to define the configuration for Parts List.
GetImplementationLabel– This service returns the name of the implementation as it appears in the Mashup Builder. We’ll set it to show the name Parts List Demo.
GetItems– This service receives the input and configuration as parameters and returns a JSON in CCO format with the data to display in the Item List user interface. We’ll set it to return the first level parts for a given part, as well as attributes for the first level parts.
6. Open the Demo.ItemListBusinessLogicThingTemplate Thing Template. Click on the Services tab.
7. Click to override theGetConfigurations service. Paste the following code into the service. This code includes one configuration for Parts List which is labelled as Parts List in both the Mashup Builder and in the ThingWorx Navigate user interface.
result = {
"partsList": {
"label": "Parts List",
"configuration": {
"selectionType": {
"selectedKey": "single"
},
"waitForInput": {
"value": true
},
"actionBarConfiguration": {
"value": {
"actionBarConfigurationJSON": {
"value": ""
}
}
},
"baseConfigurationVersion": {
"value": "9.0.0"
},
"implementationConfigurationVersion": {
"value": "1.0.0"
},
"defaultSortFields": {
"selectedValues": {
"data": [{
"itemListsData": [{
"items": [{
"additionalData": {
"itemListDefaultSortFieldDefinition": {
"defaultSortDirection": {
"selectedKey": "asc"
}
}
},
"id": "Name"
}
],
"objectType": "PTC.ProdMgmt.Part"
}
],
"adapter": {
"instanceName": "windchill",
"thingName": "PTC.WCAdapter"
}
}
]
}
},
"attributes": {
"selectedValues": {
"data": [{
"itemListsData": [{
"items": [{
"id": "Name",
"ordinal": 1
}, {
"id": "State#Display",
"ordinal": 2
}, {
"id": "Version",
"ordinal": 3
}, {
"id": "Number",
"ordinal": 0
}, {
"id": "ID",
"ordinal": 4
}
],
"objectType": "PTC.ProdMgmt.Part"
}
],
"adapter": {
"instanceName": "windchill",
"thingName": "PTC.WCAdapter"
}
}
]
},
"inTailoring": false
},
"label": {
"value": "Parts List"
},
"showExportAction": {
"value": true
},
"enableSearch": {
"additionalData": {
"itemListSearchDefinition": {
"searchHintText": {
"value": "Find"
}
}
},
"value": true
},
"maxNumberOfRowsInGrid": {
"inTailoring": false,
"value": 50
}
}

}
};
Here’s another sample code for GetConfigurations which contains two configurations instead of one. The first configuration is the same configuration as in the code above. The second configuration is for a mini version of the Parts List. It only shows three attributes and a maximum of five rows. It’s labelled as Parts List mini in the Mashup Builder and Parts List in the ThingWorx Navigate user interface.
result = {
"partsList": {
"label": "Parts List",
"configuration": {
"selectionType": {
"selectedKey": "single"
},
"waitForInput": {
"value": true
},
"actionBarConfiguration": {
"value": {
"actionBarConfigurationJSON": {
"value": ""
}
}
},
"baseConfigurationVersion": {
"value": "9.0.0"
},
"implementationConfigurationVersion": {
"value": "1.0.0"
},
"defaultSortFields": {
"selectedValues": {
"data": [{
"itemListsData": [{
"items": [{
"additionalData": {
"itemListDefaultSortFieldDefinition": {
"defaultSortDirection": {
"selectedKey": "asc"
}
}
},
"id": "Name"
}
],
"objectType": "PTC.ProdMgmt.Part"
}
],
"adapter": {
"instanceName": "windchill",
"thingName": "PTC.WCAdapter"
}
}
]
}
},
"attributes": {
"selectedValues": {
"data": [{
"itemListsData": [{
"items": [{
"id": "Name",
"ordinal": 1
}, {
"id": "State#Display",
"ordinal": 2
}, {
"id": "Version",
"ordinal": 3
}, {
"id": "Number",
"ordinal": 0
}, {
"id": "ID",
"ordinal": 4
}
],
"objectType": "PTC.ProdMgmt.Part"
}
],
"adapter": {
"instanceName": "windchill",
"thingName": "PTC.WCAdapter"
}
}
]
},
"inTailoring": false
},
"label": {
"value": "Parts List"
},
"showExportAction": {
"value": true
},
"enableSearch": {
"additionalData": {
"itemListSearchDefinition": {
"searchHintText": {
"value": "Find"
}
}
},
"value": true
},
"maxNumberOfRowsInGrid": {
"inTailoring": false,
"value": 50
}
}

},
"partsListMini": {
"label": "Parts List mini",
"configuration": {
"selectionType": {
"selectedKey": "single"
},
"waitForInput": {
"value": true
},
"actionBarConfiguration": {
"value": {
"actionBarConfigurationJSON": {
"value": ""
}
}
},
"baseConfigurationVersion": {
"value": "9.0.0"
},
"implementationConfigurationVersion": {
"value": "1.0.0"
},
"defaultSortFields": {
"selectedValues": {
"data": [{
"itemListsData": [{
"items": [{
"additionalData": {
"itemListDefaultSortFieldDefinition": {
"defaultSortDirection": {
"selectedKey": "asc"
}
}
},
"id": "Name"
}
],
"objectType": "PTC.ProdMgmt.Part"
}
],
"adapter": {
"instanceName": "windchill",
"thingName": "PTC.WCAdapter"
}
}
]
}
},
"attributes": {
"selectedValues": {
"data": [{
"itemListsData": [{
"items": [{
"id": "Name",
"ordinal": 1
}, {
"id": "Version",
"ordinal": 2
}, {
"id": "Number",
"ordinal": 0
}
],
"objectType": "PTC.ProdMgmt.Part"
}
],
"adapter": {
"instanceName": "windchill",
"thingName": "PTC.WCAdapter"
}
}
]
},
"inTailoring": false
},
"label": {
"value": "Parts List"
},
"showExportAction": {
"value": true
},
"enableSearch": {
"additionalData": {
"itemListSearchDefinition": {
"searchHintText": {
"value": "Find"
}
}
},
"value": true
},
"maxNumberOfRowsInGrid": {
"inTailoring": false,
"value": 5
}
}

}
};
Click Done after adding the code.
8. Override the GetImplementationLabel service. Set the implementation label using the following code:
result = "Parts List Demo";
Click Done.
9. The GetItems service will retrieve the first level parts from Windchill using the following process:
a. Convert the attributes portion of the configuration to CCO structure using the service ConvertAttributesToCCO, which we’ll create.
b. Pass the resulting JSON in CCO format to the GetRelatedItems service on the PTC.WCAdapter. This service retrieves the data as UsageLink objects.
c. Convert the UsageLink objects to Part objects, using the ConvertUsageLinkToPart service, which we’ll create
Before overriding the GetItems service, it’s necessary to create the services ConvertAttributesToCCO and ConvertUsageLinkToPart.
10. Create a new service and name it ConvertAttributesToCCO. Under Inputs add the following inputs:
configuration, which has the Base Type of JSON
attributesPrefix, which has the Base Type of STRING
replaceObjectType, which has the Base Type of STRING
Under Output, select JSON from the drop-down menu.
11. Paste the following code into the ConvertAttributesToCCO service:
let attributesData = configuration.attributes.selectedValues;
attributesPrefix = attributesPrefix || "";
let objectType = replaceObjectType || attributesData.data[0].itemListsData[0].objectType;
attributesData.data[0].itemListsData[0].objectType = objectType;
let items = attributesData.data[0].itemListsData[0].items;
let newItems = [];
let newObj = {};
let hasID = false;

//convert to CCO
for(var i = 0; i < items.length; i++) {
let item = items[i];
if (item.id === 'ID') {
hasID = true;
}
newObj[attributesPrefix + item.id] = {"value":""};
}
//add ID if needed
if (!hasID) {
newObj[attributesPrefix + 'ID'] = {"value":""};
}
newItems.push (newObj);
attributesData.data[0].itemListsData[0].items = newItems;

//create date
var dateValue = new Date();
var y = dateValue.getFullYear();
var mo = dateValue.getMonth()+1;
if(mo<10) {mo='0'+mo;}
var d = dateValue.getDate();
if(d<10) {d='0'+d;}
//create time
var h = dateValue.getHours();
if(h<10) {h='0'+h;}
var mi = dateValue.getMinutes();
if(mi<10) {mi='0'+mi;}
var s = dateValue.getSeconds();
if(s<10) {s='0'+s;}
var ms = dateValue.getMilliseconds();
if(ms<10) {ms='00'+ms;} else {if(ms>=10 && ms<100) {ms='0'+ms;}}
attributesData.timeStamp = y + "-" + mo + "-" + d + " " + h + ":" + mi + ":" + s + "." + ms;

attributesData.version = "";
attributesData.statusMessage = "OK";
attributesData.status = "200";

result = attributesData;
Click Done.
12. Create a new service and name it ConvertUsageLinkToPart. Under Inputs add the following inputs:
usageLinkCCO, which has the Base Type of JSON
Under Output, select JSON from the drop-down menu.
13. Paste the following code into the ConvertUsageLinkToPart service:
let itemListsData = usageLinkCCO.data[0].itemListsData[0];
let tempMetadata = itemListsData.metadata;
let items = itemListsData.items;

//convert metadata
delete tempMetadata.ID;
let newMetadata = {};
for (var key in tempMetadata) {
let newKey = key.replace(/^(Uses\|)/,"");
newMetadata[newKey] = tempMetadata[key];
}
newMetadata['id'] = newMetadata.ID;
itemListsData['metadata'] = newMetadata;

//convert Items
let newItems = [];
for (var i=0 ; i<items.length ; i++) {
let item = items[i];
let newItem = {};
for (key in item) {
let newKey = key.replace(/^(Uses\|)/,"");
newItem[newKey] = item[key];
}
newItem['id'] = newItem.ID;
newItems.push(newItem);
}
itemListsData['items'] = newItems;
itemListsData['objectType'] = 'PTC.ProdMgmt.Part';

//update CCO
let partsListCCO = usageLinkCCO;
partsListCCO.data[0].itemListsData = [itemListsData];

result = partsListCCO;
Click Done.
14. Click to override the GetItems service. Paste the following code into the GetItems service:
var migratedConfig = me.Migrate({
targetImplementationVersion: "1.0.0" /* STRING */,
data: configuration /* JSON */,
migrationType: "Configuration" /* STRING */,
targetBaseVersion: "9.0.0" /* STRING */
});

var attributesConfigurationCCO = me.ConvertAttributesToCCO({
configuration:migratedConfig /* JSON */,
attributesPrefix: "Uses|" /* STRING */,
replaceObjectType: "PTC.ProdMgmt.PartUse" /* STRING */
});

// result: JSON
var tempResult = Things["PTC.WCAdapter"].GetRelatedItems({
item: input /* JSON */,
relation: {path:"Uses"} /* JSON */,
attributes: attributesConfigurationCCO /* JSON */
});


var convertedResults = me.ConvertUsageLinkToPart({
usageLinkCCO:tempResult /* JSON */
});

var result = convertedResults;
Click Done. Then click Save to save the Thing Template.
Now the Parts List custom implementation and its configuration are created and ready for use in the Mashup Builder. To use the implementation, add the Item List base component to a mashup and click Gear icon. In the Configuration Type drop-down menu, select the Parts List configuration which is labelled Parts Lists Demo - Parts List.
If you’re using Parts List to create the mashup shown in the video below, here is some additional code:
Code used to configure the Attributes component:
{
"layout": {
"selectedKey": "horizontal",
"additionalData": {
"dimensionDefinition": {
"maxHeight": {
"value": 200,
"version": "1.0.0"
},
"maxWidth": {
"value": 200,
"version": "1.0.0"
}
}
},
"version": "1.0.0"
},
"attributes": {
"sets": [{
"data": {
"selectedValues": {
"data": [{
"itemListsData": [{
"items": [{
"id": "ModifiedBy",
"ordinal": 0
}, {
"id": "GatheringPart",
"ordinal": 1
}, {
"id": "Latest",
"ordinal": 2
}, {
"id": "FolderName",
"ordinal": 3
}
],
"objectType": "PTC.ProdMgmt.Part"
}
],
"adapter": {
"instanceName": "windchill",
"thingName": "PTC.WCAdapter"
}
}
]
}
},
"name": ""
}
],
"inTailoring": true,
"filteredValues": {
"data": [{
"itemListsData": [{
"objectType": ""
}
],
"adapter": {
"instanceName": "",
"thingName": ""
}
}
]
},
"version": "1.0.0"
}
}
Code used for the mashup’s input parameter. Make sure to add a valid part ID:
{
"version": "1.0.0",
"data": [{
"adapter": {
"thingName": "PTC.WCAdapter",
"instanceName": "windchill"
},
"itemListsData": [{
"objectType": "PTC.ProdMgmt.Part",
"items": [{
"id": {
"value": ""
}
}
]
}
]
}
]
}
Video Tutorial: Create a Parts List Implementation
The following two video tutorials show how to create and use the custom implementation Parts List. The first video shows how to create Parts List, following the steps in the example above. The second video shows how to use Parts List in a mashup. You can find all of the code used in the videos in the example above.
To view a video in a larger window, click on the title in the player. This opens the video in YouTube in a new tab.
Was this helpful?