Customize a data-driven widget

From SpinetiX Support Wiki

Jump to: navigation, search

Introduction

This page contains tutorials showing how to create custom data feed widgets, starting from the built-in Elementi widgets. They are usually referencing operations performed within the "XML Tree" view included into Elementi X. If you don't have Elementi X, then you will need to modify the SVG / JavaScript code inside the file - for instance, using a text editor like Notepad++.

See also how to create an Elementi widget from a regular SVG file and the Project:Data feeds page for sample projects using data feeds.

Activate the network cache

By default, the data-driven widgets are not using the built-in network caching mechanism, thus the content is retrieved every time the feed widget document is opened or after the predefined refresh period (i.e. data caching). If you want to instruct the HMP to cache the HTTP response from the server, you can use setGetURLFlags() jSignage function and the flags detailed for the standard getUrl() function.

Adding caching instructions

To start with this example, copy one of the feed widgets from Elementi Library into your current project. Optionally, rename it to something like "RSS Text Ticker with cache". To add the the caching instructions, follow these steps:

  1. Open the feed widget and go to the XML Tree view.
  2. Expand the second <script> element.
  3. Click on the CDATA in green. An editing box will open.
  4. Add the caching instructions:
    • To check the validity of the cache only when the document is opened, use:
      $.setGetURLFlags( GETURL_CACHE_CONTENT );
      
    • To check the validity of the cache using a very short caching time, regardless of the response returned by the server. The data is retrieved only when the document is opened (Need firmware 3.0.1), use:
      $.setGetURLFlags( GETURL_CACHE_CONTENT|GETURL_ALWAYS_CHECK );
      
    • To check the validity of the cache while the document is running (and in case of updates, to immediately start displaying them), use:
      $.setGetURLFlags( GETURL_CACHE_CONTENT|GETURL_TRACK_CHANGES );
      
  5. Press the OK button and save the file.
Note Note:
The behavior of the cache is highly dependent on the headers returned by the server, as explained in the Caching page.

Change the request type to POST

Force POST request

Bt default, the data-driven widgets are doing GET HTTP requests - to force sending a POST request follow these steps:

  1. Open the data-driven widget and click the "XML Tree" tab on the Edit panel.
  2. Find the "jsonParams" definition block and expand the <title> element.
  3. Double-click on the CDATA area in green. An editing dialog opens up.
  4. Find the properties of the "dataSource" object.
  5. Add a new property "requestType": "POST".
    "dataSource": {
    	"fallbacks": { ... },
    	...
    	"parser": {
    		"rows": "",
    		"type": "json"
    	},
    	"refresh": 0,
    	"requestType": "POST",
    	"src": "http://download.spinetix.com/content/elementi/feeds/...",
    	"type": "uri"
    }
    
  6. Click OK button and the save your changes.

Add custom headers to the HTTP request

Custom headers

The most common HTTP headers are used when data-driven widgets are making calls to get the data from the configured source. Some particular web services might require one or more custom headers to be to specified with the request call - for instance, a "Project-Id" could be required to select some specific project data. Here is the easiest way to add such custom headers:

  1. Open the data-driven widget and click the "XML Tree" tab on the Edit panel.
  2. Find the "jsonParams" definition block and expand the <title> element.
  3. Double-click on the CDATA area in green. An editing dialog opens up.
  4. Find the properties of the "dataSource" object.
  5. Add a new object property called "headers", containing your custom headers.
    "dataSource": {
    	...
    	"headers": {
    		"customHeader1": "value1",
    		...
    		"customHeaderN": "valueN",
    	},
    	...
    	"type": "uri"
    }
    
  6. Click OK button and the save your changes.

Create a switch widget

The switch helper present in HMD was not ported into the Elementi Library, since the same functionality can be done using a simple custom parser in Elementi X. To do this, follow these steps:

  1. Create a JS file containing the custom parser function - a sample code is detailed below. (Or use the simple_switch.js included in the sample.)
  2. Import this file into your project.
  3. Import one of the feed widgets into your project and open it.
  4. Open the Data source configuration dialog and configure the data source and parser as usual.
  5. Under the Format section, in the first box select the data column to be used as source for the switch and in the second one select "Script".
  6. Press the Add button. A new tab is created having the name from the first box and the word "Script" afterwards.
  7. Open the newly created tab and enter the name of the script file (for instance simple_switch.js) as URI and a function name (for instance create) as Function.
  8. Press OK and then the "Test" button. A new column is created with the result of the switch as values.

Sample JavaScript code:

function create( data ) {
   var switch_data = {
      "A" : "This is A",
      "B" : "This is not A, but B",
   };    // controls the rules to switch the data.

   var switch_default = "This is the default"; // controls the default value

   // A new column called "switched" will be created.
   if ( data in switch_data )
      return { switched: switch_data[ data ] };
   else
      return { switched: switch_default };
}

The full JavaScript code, including comments, can be downloaded from the link above.

End the widget immediately when there are no data

Whenever there's no data to be displayed, the data-driven widgets are displaying an empty slide for the default slide duration - this is to prevent the widget being reopened in a loop, which could lead to a player reboot and safe mode in some cases. But when that widget is used within a playlist, we might want to end the widget immediately, so that the playlist could advance to the next slide. For that find the code that computes the maximum duration based on the default slide duration and simply use the other value - for instance:

// replace this line
var dur = Math.max( parseInt(jsonParams.defaultSlideDur), document.documentElement.getCurrentTime() );
// with this one
var dur = $.getCurrentTime() || 0.001 ;

or

// replace this line
$("svg").attr("dur", Math.max( $.durInSeconds(jsonParams.defaultSlideDur),totalDur ) );
// with this one
$("svg").attr("dur", totalDur || 0.001 );

Incremental display of data feed items within a playlist

The regular behavior of a looping playlist in which we have included a data feed widget (for instance, RSS Slideshow) at a certain position, is to advance past the slide containing the data feed widget, only when all the items of data set have been displayed.

Let's say that we want to change that and display at every loop only one item of the data set, taking each time the next item in line until the end of the data set, when the first item will be picked again and so on. For that we need to modify the code of widget (see below), more precisely the new_data_handler function, to extract one item from the data set according to a counter that is saved into sessionStorage.

function new_data_handler( data ) {

    //-- extra code to be added at the beginning of the function to select only one item from the data set
    if ( data.length > 0 ){
        var storageName = 'spx-rss-item-cnt-' + document.documentURI, // var unique to this document
            cnt = sessionStorage.getItem( storageName ); // get the counter value from the session storage
        
        // check the counter value
        if ( cnt === null || cnt >= data.length ){
            // reset the counter to 0 if null or larger than the length of the data set
            cnt = 0;
        }
        
        // extract one item from the data set and replace the original data with it
        data = [ data[ cnt ] ];
        
        // increment the counter for the next loop and save it into session storage
        sessionStorage.setItem( storageName, ++cnt );
    }
    //-- end of extra code
    
    //-- the original code goes below
    ...
}
Note Notes:
  • To avoid having the server contacted each time the data feed widget is opened, make sure to set the "Refresh" property to a value other than "never", for instance "1h", within the Data Feed Properties dialog.
  • To extract two items of the data set instead of one, you could use something like data = [ data[cnt], data[ ++cnt ] ]; - for an odd number of items in the data set, a JS exception will be thrown, so you might want to tweak the code some more.

Use a Shared Variable as data source

The data feed widgets are set by default to use an external data source, but they can also be configured to use a Shared Variable as data source. To do this, follow these steps:

Shared variable as data source
  1. Open the "Data source" property of the feed widget.
  2. Set the "Type" option to "Shared variable".
  3. Under "Variable name", enter the name of the shared variable.
    To connect to a remote shared variable, use the variable name followed by '@' and the hostname or IP address of the remote HMP and, optionally, by a TCP port (if the port number on the server is different from the port number on the local host) - e.g., var@remotehost:4567.
  4. Set the "Parser" option to "RegExp".
  5. Press the "OK" button to activate the changes.

For an example, see Instant Messaging project.

Use inline data as data source

The feed widgets included into Elementi Library are set by default to use an external data source, but they can also be configured to use an inline data source (i.e. an element existing in the same document).

Inline Text Ticker

Inline Text Ticker

To start with this example, copy a text ticker widget (for instance "RSS Text Ticker") from the Elementi Library into your current project. Optionally, rename it to something like "Inline Text Ticker".

To create a horizontal text ticker displaying inline data, follow these steps:

  1. Create the inline data placeholder.
    1. Open the XML Tree view and find the <defs> element.
    2. Right-click on it, select "Add Child" and name the new element "title".
    3. On the created <title> element, right-click and select "Enable Content Edit".
      This will add a new <spx:text> entry under <spx:properties>.
    4. Open the <spx:properties> element and find the last <spx:text> child.
    5. Open it and change the name attribute from "title_1" to something more explicit, for instance: "Inline text data".
      The xlink:href attribute should not be changed. Otherwise, make sure to use the new value at step 2.3 below.
    6. Under the "Properties" view, find the (new) entry called "Inline text data" and enter the desired text.
  2. Configure the feed widget to use the inline data element as data source.
    1. Open the Data source dialog.
    2. Set the Type to "inline data".
    3. Set the Selector to "#title_1".
    4. Set the Parser to "RegExp".
    5. Click on OK to see the result on the screen.
  3. Save the file.
Note Note:
The result of this tutorial is the Inline Text Ticker widget.

Inline Text Roll

To start with this example, copy a text roll widget (for instance "RSS Text Roll") from the Elementi Library into your current project. Optionally, rename it to something like "Inline Text Roll".

To create a vertical text ticker / roller displaying inline data, follow these steps:

  1. Create the inline data placeholder.
    1. Open the XML Tree view and find the <defs> element.
    2. Right-click on it, select "Add Child". Replace <new-element> with <title>.
    3. On the newly created <title> element,
      • Right-click and select "Add attribute". Replace new-attribute with xml:id and on the right side column enter title_1.
      • Right-click again and select "Add CDATA". In the "Edit CDATA" window, enter the following JSON code: { "text": "" } and press the OK button.
    4. Find the <spx:properties> element, right-click on it and select "Add child". Replace <new-element> with <spx:json-text>.
    5. Add the following attributes / values pairs on this element (i.e. right-click and select "Add attribute"):
      • Attribute name and value Inline text data;
      • Attribute propertyName and value text;
      • Attribute xlink:href and value #title_1;
    6. Under the "Properties" view, find the (new) entry called "Inline text data" and enter the desired text (for instance "Your scrolling text goes here ...").
  2. Configure the feed widget to use the inline data element as data source.
    1. Open the Data source dialog.
    2. Set the Type to "Inline data", the Selector to "#title_1" and the Parser to "JSON".
    3. Click on OK to see the result on the screen.
  3. Save the file.
Note Note:
The result of this tutorial is the Inline Text Roll widget.
This page was last modified on 6 November 2019, at 12:23.