cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - You can change your system assigned username to something more personal in your community settings. X

Adding a Widget in ThingWorx

ale
1-Newbie
1-Newbie

Adding a Widget in ThingWorx

How to add custom widget( eg: jquery widgets) in to thingworx?

15 REPLIES 15

Hi Anthony,

Look at the documentation : http://support.ptc.com/cs/help/thingworx_hc/thingworx_6.5_hc/ on the section ThingWorx Extensibility . If you want to see a sample, also you can download any widget on the marketplace and look inside the .Zip file.

Best Regards,

Carles.

ale
1-Newbie
1-Newbie
(To:CarlesColl)

Hi,

Thanks for the reply.

By seeing this link I understood that there should be .css,.ide.css,.js, .ide.js,metadata.xml,runtime.css,runtime.js files but I have downloaded a jquery widget to display temperature but how can I write those files in these format? Is there any possibility to directly download thingworx widgets?

Thank you

You can include any number of additional files ( .js, .css, .png,... ) on the extension, look at the XML extension definition file ( better you look on an actual real widget from Marketplace ).

Carles.

nlaffargue
1-Newbie
(To:ale)

You have to include the jquery plugin JS file in your JS Files and then do the necessary to build your Thingworx widget (HTML rendering, specific scripts after render, destroy methods...)

metadata.xml is the description of your widget

*.ide files are the files which will be used to setup/display your widget in the Composer

*.runtime are the files which will be used to setup/display your widget at runtime

As Carles said, the best way is to take existing widgets as models.

wardb
1-Newbie
(To:ale)

Hi Anthony

You have to reformat the javascript from your jquery widget.

So for the Metadata.xml file you need to include the the .js from your original javascript:

<?xml version="1.0" encoding="UTF-8"?>
<Entities>

   <ExtensionPackages>

   <ExtensionPackage name="GEWidgets"
   description="Widgets created by General Electric, Inc."
   vendor="General Electric, Inc."
   packageVersion="0.1"
   minimumThingWorxVersion="4.1.0" />

   </ExtensionPackages>

   <StyleDefinitions>

   </StyleDefinitions>

   <Widgets>

   <Widget name="DowntimeChartWidget2">

   <UIResources>

   <!-- Studio ONLY -->
   <FileResource type="CSS" file="DowntimeChartWidget2.ide.css" description="" isDevelopment="true" isRuntime="false" />

   <FileResource type="JS" file="DowntimeChartWidget2.ide.js" description="" isDevelopment="true" isRuntime="false" />

   <!-- Runtime/Squeal ONLY -->
   <FileResource type="CSS" file="DowntimeChartWidget2.runtime.css" description="" isDevelopment="false" isRuntime="true" />

   <FileResource type="JS" file="DowntimeChartWidget2.runtime.js" description="" isDevelopment="false" isRuntime="true" />

   <FileResource type="JS" file="DTChartType2.js" description="" isDevelopment="false" isRuntime="true" />

   <FileResource type="JS" file="chart2.js" description="" isDevelopment="false" isRuntime="true" />

   <FileResource type="JS" file="morechart.js" description="" isDevelopment="false" isRuntime="true" />

   <FileResource type="JS" file="exporting2.js" description="" isDevelopment="false" isRuntime="true" />

   </UIResources>

   </Widget>

   </Widgets>

</Entities>

 

  Now you have all the code in one place.

  Then you have to expose any parameters you are looking for.  As you mentioned it is in the ide.js file.

this.widgetProperties = function () {

   return {

   'name': 'Downtime Widget',

   'description': 'Displays a downtime chart',

   'category': ['Common'],

   'supportsAutoResize': true,

   'defaultBindingTargetProperty': 'Data',

   'properties': {

'BorderStyle': {

   'baseType': 'STYLEDEFINITION',

   'defaultValue': 'DefaultImageBorderStyle'
   },

   'Data': {

   'baseType': 'INFOTABLE',

   'isBindingTarget' :true,

   'warnIfNotBoundAsTarget': true
   },

   'Selected': {

   'baseType': 'STRING',

   'isBindingSource' :true
   },

   'DTServerIP': {

   'baseType': 'STRING',

   'isEditable': true
   },

   'Width':{

   'defaultValue': 200
   },

   'Height':{

   'defaultValue': 200
   }

  }

  };

};

  This will let you bind data from Thingworx ide to the data you will get when you are rendered.

  We start with the renderhtml function:

this.renderHtml = function () {

   var html = '<div class="widget-content widget-downtimeWidget" style><div id="container"></div></div>';

   return html;

};

  You can just call the javascript  you were looking for on data change events

this.updateProperty = function (updatePropertyInfo)

   if (updatePropertyInfo.TargetProperty === 'EndTime')

  {

   this.setProperty('EndTime', updatePropertyInfo.SinglePropertyValue);

   this.receivedEndTime = true;

   if (!this.chartObj && this.receivedCurrentTime) {

   this.createChart();

  }

  } else if (updatePropertyInfo.TargetProperty === 'StartTime') {

   this.setProperty('StartTime', updatePropertyInfo.SinglePropertyValue);

   if (this.receivedCurrentTime && this.receivedEndTime) {

   this.createChart();

  }

  }  else if (updatePropertyInfo.TargetProperty === 'CurrentServerTime') {

   this.setProperty('CurrentServerTime', updatePropertyInfo.SinglePropertyValue);

   this.receivedCurrentTime = true;

   if (!this.chartObj && this.receivedEndTime) {

   this.createChart();

  }

  }

  };

So where we call this.createChart, you would call the function in your thermostat to update the image.

Note this is a terrible example, but we do this on a daily basis.  Purchasing libraries of controls and migrating them to Thingworx, and making Thingworx controls really responsive.

Hope that helps.

qn
1-Newbie
1-Newbie
(To:wardb)

Hi, how can you call a function in another library (chart2.js, morechart.js)... ?

Good reference.Thanks.

I have following requirement

Employee

Designation

Salary

Employee1

<dropdown>

<textbox>

Employee2

<dropdown>

<textbox>

Employee3

<dropdown>

<textbox>

Service: GetEmployeeDetail  Output: Infotable  Datashape: EmployeeId, EmployeeName, Designation, Salary

I have prepared a custom widget which generates above UI with controls inside grid

It has a property "Data" which is bound by GetEmployeeDetail service (All data)

How do I get the updated values (same "Data" property with updated values) from the widget as an infotable? I need to save all the details back to db

I tried using setProperty but no luck.

Actual generic question: How to return an infotable from widget to Thingworx so that I can use it as a source to other service?

Hi Malay Khandhediya​ ,

I don't see the need of building a custom widget for this user interface, you can perfectly build it with a standard ThingWorx Repeater Widget, where each row it's a mashup where you can put simply a Label with the Employer name, a standard List widget ( Dropdown) and a TextBox widget.

About saving the updates, if you implement the way I said, you can save changes atomically when the user changes the DropDown or the TextBox with corresponding SelectedRowChange event and Change event respectively.

Best Regards,

Carles.

jarekw
4-Participant
(To:CarlesColl)

Hi Carles,

Even if Malay doesn't need to create his own widget, could you explain us how to get an infotable from our widgets?

I need to build a widget which will create a set of data (an infotable) and send them to my service

This code works great for 'Label' but not for 'Data'

this.updateProperty = function (updatePropertyInfo) {

        if (updatePropertyInfo.TargetProperty === 'Data') {

                var value = updatePropertyInfo.RawSinglePropertyValue;

                this.setProperty('Data', value);

                this.afterRender();

      }

      if (updatePropertyInfo.TargetProperty === 'Label') {

                var value = updatePropertyInfo.RawSinglePropertyValue;

                this.setProperty('Label', value);

                this.afterRender();

        }

};

Could you tell me please how to get it working?

Thanks,

Jarek

Hi Jaroslaw,

Cheers!! Finally, I am able to pass infotable back to Thingworx. Please refer below code. Hope it helps.

//HTML

<div data-ng-repeat="item in items" >

  <input ng-model='item.Designation' ng-change="updateData();" />

  <input ng-model='item.Salary' ng-change="updateData();" />

</div>

//scope variables, events

$scope.items = [];

$scope.updateData = function(){  /*call this on change of every control eg: <input ng-model='item.Salary' ng-change="updateData();" />*/

  $timeout(function() {

       var updatedData = thisWidget.getProperty('UpdatedData'); //New property of type Infotable

       updatedData.rows = $scope.items;

       this.setProperty('UpdatedData', updatedData);

  },0)

};

//UpdateProperty

this.updateProperty = function (updatePropertyInfo) {

  var item;

  var items = [];

  var currentDataInfo = updatePropertyInfo;

  var currentRows = currentDataInfo.ActualDataRows;

  var infoTableDataShape = currentDataInfo.DataShape;

  var clonedTable = TW.InfoTableUtilities.CloneInfoTable({ "dataShape" : { "fieldDefinitions" : infoTableDataShape}, "rows" : currentRows });

  this.setProperty('UpdatedData',clonedTable);

  for (i = 0; i < updatePropertyInfo.ActualDataRows.length; i++) {

       item = updatePropertyInfo.ActualDataRows;

       items = {

            Employee: item.Employee,

            Designation: item.Designation,

            Salary: item.Salary

       };

  }

  this.scope.updateProperty("items", items);

}

Regards,

Malay

Widget life cycle is followed as per documentation, but stuck with this problem


this.updateProperty = function (updatePropertyInfo) {


// Problem : This call back is not getting executed even when target data has changed


Any suggestions where I'm going wrong?


Thanks,

Ginu

snatarajan-2
6-Contributor
(To:jarekw)

Carles/Jerek,

I was trying to create a custom widget.

RenderHtml,afterRender get's executed.

This callback doesnot get executed for me, even when data via thing service is bound to target Data, any suggestions???

this.updateProperty = function (updatePropertyInfo) {

Thanks,

Ginu

aduarte
6-Contributor
(To:snatarajan-2)

Hello,

It depends of what you are trying to do.

What are you doing on the updateProperty?

I don't know if you have already tried, for example, something like this:

if (updatePropertyInfo.TargetProperty === 'Data') {

   var value = updatePropertyInfo.RawSinglePropertyValue;

   this.setProperty('Data', value);

   this.afterRender();

}

Hi,

I have a similar problems with the Hello World example. I made a TextBox with the text connected to the example's property. At first the text changed when I pressed enter after typing in something. Currently, I'm not able to change the text. What should trigger the updateProperty?

I tried to create expand the example with some services. The services were not working on Firefox but worked on Chrome. When I got the services working (for some reason also now on Firefox) the updateProperty stopped working. I removed the services from the example but still the updateProperty doesn't work.

OT:

If I print something in the widget TW.log.info/error/etc. where should the output go? I have checked the browser's console as well as the ThingWorxMonitor. No results so far.

-Risto Vääräniemi

Hmm, the property setting seems to work now. I have no idea what initially caused the problem or what fixed it. It was probably a weird browser incompatibility / cache problem.

-Risto

Top Tags