15 Replies Latest reply on Jan 17, 2017 9:22 AM by rvaaraniemi RSS
    ale Newbie

    Adding a Widget in ThingWorx

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

      • Re: Adding a Widget in ThingWorx
        carlesc Heavyweight Champ

        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.

          • Re: Adding a Widget in ThingWorx
            ale Newbie

            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

              • Re: Adding a Widget in ThingWorx
                carlesc Heavyweight Champ

                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.

                • Re: Adding a Widget in ThingWorx
                  nicolasl Explorer

                  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.

                  • Re: Adding a Widget in ThingWorx
                    wardb Newbie

                    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.

                  • Re: Adding a Widget in ThingWorx
                    mkhandhediya Newbie

                    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?

                      • Re: Adding a Widget in ThingWorx
                        carlesc Heavyweight Champ

                        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.

                          • Re: Adding a Widget in ThingWorx
                            jwetoszka Newbie

                            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

                              • Re: Adding a Widget in ThingWorx
                                mkhandhediya Newbie

                                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[i];

                                       items[i] = {

                                            Employee: item.Employee,

                                            Designation: item.Designation,

                                            Salary: item.Salary

                                       };

                                  }

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

                                }

                                 

                                Regards,

                                Malay

                                • Re: Adding a Widget in ThingWorx
                                  snatarajan-2 Newbie

                                  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

                                    • Re: Adding a Widget in ThingWorx
                                      aduarte Explorer

                                      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();
                                      }
                                      
                                        • Re: Adding a Widget in ThingWorx
                                          rvaaraniemi Explorer

                                          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