10

I am setting up a custom tab with custom facet data in the Experience Profile. I am successfully returning text values to the screen.

Now, I want to populate data into a list control. Are there any examples of this.

In my AdditionalInfoPanel, I have a GenericDataProvider and a ListControl.

My list has three columns: for Sent, ContactType, and Message.

My javascript file looks like this:

define(["sitecore", "/-/speak/v1/experienceprofile/DataProviderHelper.js", "/-/speak/v1/experienceprofile/CintelUtl.js"], function (sc, providerHelper, cintelUtil) {
        var app = sc.Definitions.App.extend({
            initialized: function () {
                var localUrl = "/customfields/";
                providerHelper.setupHeaders([
                    { urlKey: localUrl }
                ]);
    
                var url = sc.Contact.baseUrl + localUrl;
                var communicationData;
                var $that = this;
                providerHelper.initProvider(this.AdditionalInfoDataProvider, "", url, this.AdditionalInfoTabMessageBar);
                providerHelper.getData(this.AdditionalInfoDataProvider,
                    $.proxy(function (jsondata) {
                        cintelUtil.setText($that.CompanyValue, renderUrl(jsondata.Company, jsondata.CompanyUrl), true); /* working correctly */
                        cintelUtil.setText($that.IndustryValue, jsondata.Industry, true); /* working correctly */
                        cintelUtil.setText($that.SubIndustryValue, jsondata.SubIndustry, true); /* working correctly */
                        cintelUtil.setText($that.RevenueRangeValue, jsondata.RevenueRange, true); /* working correctly */
                        cintelUtil.setText($that.IsKnownExecutiveValue, jsondata.IsKnownExecutive, true); /* working correctly */
                        cintelUtil.setText($that.IsKnownCustomerValue, jsondata.IsKnownCustomer, true); /* working correctly */
                        cintelUtil.setText($that.IsKnownBlogUserValue, jsondata.IsKnownBlogUser, true); /* working correctly */
                        cintelUtil.setText($that.OptInValue, jsondata.OptIn, true); /* working correctly */
                        communicationData = JSON.stringify(jsondata.Communications);
                        console.log(communicationData); /* SEE NOTE 1 FOR THIS OUTPUT */
                        providerHelper.initProvider(this.AdditionalInfoCommunicationDataProvider, "", url, this.AdditionalInfoCommunicationMessageBar);
                        providerHelper.getListData(this.AdditionalInfoCommunicationDataProvider, communicationData); /* SEE NOTE 2 FOR ERROR */
                    }));
            }
        });
    
        function renderUrl(text, url) {
            if (url !== null && url.length > 0)
            {
                return "<a href=\"" + url + "\" target=\"_blank\">" + text + "</a>";
            }
            else
            {
                return text;
            }
        }
    
        return app;
    });

NOTE 1: The output of this console.log is:

[{"Sent":"2016-10-18T17:25:36.831Z","ContactType":"Product Information","Message":"Looking to get information about software","IsEmpty":false}]

NOTE 2: The resulting error is:

caught TypeError: Cannot read property 'set' of undefined / DataProviderHelper.js:74

I am trying to figure out how to correctly bind the data in jsondata.Communications to the ListControl.

I am using Sitecore 8.1 Update 2


UPDATE 1: Using suggested changes below... this is my JavasScript:

define(["sitecore", "/-/speak/v1/experienceprofile/DataProviderHelper.js", "/-/speak/v1/experienceprofile/CintelUtl.js"], function (sc, providerHelper, cintelUtil) {
    var app = sc.Definitions.App.extend({
        initialized: function () {
            var localUrl = "/customfields/";
            providerHelper.setupHeaders([
                { urlKey: localUrl }
            ]);

            var url = sc.Contact.baseUrl + localUrl;
            var communicationData;
            var $that = this;
            providerHelper.initProvider(this.AdditionalInfoDataProvider, "", url, this.AdditionalInfoTabMessageBar);
            providerHelper.getData(this.AdditionalInfoDataProvider,
                $.proxy(function (jsondata) {
                    cintelUtil.setText($that.CompanyValue, renderUrl(jsondata.Company, jsondata.CompanyUrl), true);
                    cintelUtil.setText($that.IndustryValue, jsondata.Industry, true);
                    cintelUtil.setText($that.SubIndustryValue, jsondata.SubIndustry, true);
                    cintelUtil.setText($that.RevenueRangeValue, jsondata.RevenueRange, true);
                    cintelUtil.setText($that.IsKnownExecutiveValue, convertBooleanToYesNo(jsondata.IsKnownExecutive), true);
                    cintelUtil.setText($that.IsKnownCustomerValue, convertBooleanToYesNo(jsondata.IsKnownCustomer), true);
                    cintelUtil.setText($that.IsKnownBlogUserValue, convertBooleanToYesNo(jsondata.IsKnownBlogUser), true);
                    cintelUtil.setText($that.OptInValue, convertBooleanToYesNo(jsondata.OptIn), true);
                    console.log(JSON.stringify(jsondata.Communications));
                    $that.AdditionalInfoCommunicationDataSource.set('items', jsondata.Communications);
                }));
        }
    });

    function renderUrl(text, url) {
        if (url !== null && url.length > 1) {
            return "<a href=\"" + url + "\" target=\"_blank\">" + text + "</a>";
        }
        else {
            return text;
        }
    }

    function convertBooleanToYesNo(value) {
        if (value == 'true' || value == true) {
            return 'Yes';
        }
        else if (value == 'false' || value == false) {
            return 'No';
        }
        else {
            return value;
        }
    }

    return app;
});

Here you can see the Renderings of my panel: Renderings

Here you can see my List binding: List binding

Here you can see a couple of my Column Fields: Column fields

I no longer get an error, but the 'Communications' data is still not loaded in the grid. :-( Any ideas?


CLOSING UPDATE

@gorhal had the solution. One further step was to ensure the "Items" property of the ListControl was bound to the datasource items: {Binding AdditionalInfoCommunicationDataSource.Items}

9
+100

I suggest you use a SearchDataSource and then bind it to your ListControl.

Check this post for binding example: https://visionsincode.wordpress.com/2016/10/17/put-json-data-in-your-searchdatasource-and-bind-it-to-searchabledroplist-sitecore-speak/

Now, in your code, if you do this (jsondata.Communications needs to be an array):

providerHelper.getData(
    this.AdditionalInfoDataProvider,
    $.proxy(function (jsondata) {
        cintelUtil.setText($that.CompanyValue, renderUrl(jsondata.Company, jsondata.CompanyUrl), true); /* working correctly */
        cintelUtil.setText($that.IndustryValue, jsondata.Industry, true); /* working correctly */
        cintelUtil.setText($that.SubIndustryValue, jsondata.SubIndustry, true); /* working correctly */
        cintelUtil.setText($that.RevenueRangeValue, jsondata.RevenueRange, true); /* working correctly */
        cintelUtil.setText($that.IsKnownExecutiveValue, jsondata.IsKnownExecutive, true); /* working correctly */
        cintelUtil.setText($that.IsKnownCustomerValue, jsondata.IsKnownCustomer, true); /* working correctly */
        cintelUtil.setText($that.IsKnownBlogUserValue, jsondata.IsKnownBlogUser, true); /* working correctly */
        cintelUtil.setText($that.OptInValue, jsondata.OptIn, true); /* working correctly */

        $that.YourSearchDataSource.set('items', jsondata.Communications);

        providerHelper.initProvider(this.AdditionalInfoCommunicationDataProvider, "", url, this.AdditionalInfoCommunicationMessageBar);
    }));

Since this is SPEAK version 1 (using set) I think you should do this:

$that.YourSearchDataSource.set('items', jsondata.Communications);

SPEAK2 is so much cleaner, so you can use this:

$that.YourSearchDataSource.Items = jsondata.Communications;

You will also need to create column definitions for the list control; here is an example from the LatestVisitors list on the dashboard in the Experience Profile:

LatestVisitors list

Then you will need to create a Columnfield for each column:
Sent, ContactType, and Message

Don't forget to enter the JSON field name (from the JSON array) in the DataField on the Columnfield:

Columnfield

Finally, go to your layout and select your list control to get its properties. Locate the DataSource attribute and point it to your new ColumnDefinitions item:

Speak layout

That should be it, I hope it will help you :-)

| improve this answer | |
  • See my update above. No more errors, but still no data. – eat-sleep-code Oct 20 '16 at 17:08
  • Could you please show how the jsondata.Communications look like? Not all but parts of it – gorhal Oct 20 '16 at 18:21
  • [{"Sent":"2016-10-18T17:25:36.831Z","ContactType":"Product Information","Message":"Looking to get information about software","IsEmpty":false}] – eat-sleep-code Oct 20 '16 at 18:35
  • Hmm... If you would create an array like this: var myArray = []; var myElement = {}; myElement["Sent"] = "2016-10-18T17:25:36.831Z"; myElement["ContactType"] = "Product Information"; myElement["Message"] = ""Looking to get information about software"; myElement["IsEmpty"] = false; myArray.push(myElement); And then set that one instead of jsondata.Communications to the DataSource. Will you still have an empty list? By the way does the list show the column names or is it just empty – gorhal Oct 20 '16 at 18:46
  • 1
    Hmm. Did you bind the datasource to the listcontrol, I can't see that in your screendumps. You should have an Items property on the listcontrol: {Binding AdditionalInfoCommunicationDataSource.Items} – gorhal Oct 20 '16 at 19:03
4

I think you will find your answer in this blog from Jonathan Robbins.

It is quite some code - too much to copy here. An overview of what is all in his example:

  • SubPageCode rendering
  • The Border rendering adds a Placeholder for the other renderings.
  • The MessageBar is used to display messages
  • AdvancedExpander datasources the SampleOrdersAccordion Item we created earlier. The next four renderings are added to this AdvancedExpander‘s placeholder.
  • The ListControl is responsible for displaying the data
    • Set the Datasource the SampleOrders ListControl item
    • Items field looks at the data provider to know what to display e.g. {Binding SampleOrdersDataProvider.cidata}.
  • ProgressIndicator displays a loading indicator for the ListControl
    • Set it’s Target property to the Id of the ListControl
    • IsBusy property is wired to the following GenericDataProvider e.g. {Binding SampleOrdersDataProvider.IsBusy}
    • Finally it datasourced to the out-of-the-box ProgressIndicator Item.
  • GenericDataProvider actually holds the data we are loading and displaying. Datasourced to an Item called DataProviderForListControl{6CD06869-4264-420C-A161-3220DD3AB7BA}
  • Border adds a placeholder for a ‘see more’ button is more data is available than the page size.
    • To set this conditional visibility set the IsVisible field to a property of the DataProvider denoting if there is more data available than the page – {Binding SampleOrdersDataProvider.HasMoreData}
  • The Button facilitates pagination of the data, its Click event field set to a preexisting JavaScript Method – javascript:app.SampleOrdersDataProvider.nextListData().

His result looks like this: enter image description here

| improve this answer | |
  • Thank you. I am already pretty much where this example shows, what I am missing is that his appears to be pulling data from some table. I need to pull mine from the jsondata that would be returned for the contact. – eat-sleep-code Oct 17 '16 at 19:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.