Saturday 5 September 2015

Render JSON Data Using Sightly & Custom MultiFieldPanel


Hi Guys,

I got the task to render the JSON Data which store in JCR via MultiFieldPanel (a custom xtype). Just sharing the solution with you. I usually get the values from the hierarchical nodes & then create the Map and render over the JSP using Custom Tags. Here I am going to demonstrate If your data is store in form of JSON format and nested in form of multiple entries, then how you can fetch and render that data using Sightly.

Below is the snapshot of dialog and how the data is getting store in JCR.



And Below is how the content store in JCR, Here it create the array of multiple JSON entries :





Here we can choose 2 ways to render the data over the html. First one is Java-Use api Second is Javascipt-Use api. Here I am demonstrating using Javascript API

1) Javascript-Use API :

Sightly use the server side Javascript in order to execute the logic in form of USE classes.
Below is the HTML code that render the markup over to browser.

<sly data-sly-test="${wcmmode.edit}">Country Information</sly>
<sly data-sly-use.countryInfo="${'practice/components/clientlibs/convertToJson.js' @ fieldName = 'countryinfo',fieldValue = ''}">
    <ul>
        <sly data-sly-list.countryDetails="${countryInfo.listJson}">
            <li> ${countryDetails.country}
                <ul>
                    <sly data-sly-use.stateInfo="${'/apps/sdsingtel/components/clientlibs/convertToJson.js' @ fieldName = '',fieldValue = countryDetails.states}">
                        <sly data-sly-list.innerlistJson="${stateInfo.listJson}">
                            <li> ${innerlistJson.state} </li>
                            <sly data-sly-use.cityInfo="${'/apps/sdsingtel/components/clientlibs/convertToJson.js' @ fieldName = '',fieldValue = innerlistJson.cities}">
                                <ul>
                                    <sly data-sly-list.citylistJson="${cityInfo.listJson}">
                                        <li>${citylistJson.city}</li>
                                    </sly>
                                </ul>
                            </sly>
                        </sly>
                </ul>
            </li>
            </sly>
    </ul>
    </sly>

Here we are invoking convertToJson file ans passing two parameter : fieldName and fieldValue. 

Here fieldName stands for name of the widget which I assume is the root from where out custom multi-field starts.

Here fieldValue stands for of the nested widget which is the root of next level from where out custom multi-field starts.

As the JSON we are rendering is nested so for one level i passed fieldName but after that its fieldValue.

Below is the JS code which takes the resource and return its corresponding JSON.


"use strict";

use(function () {
    var readJson = null;
    var listArr = [];
    if (this.fieldValue != '') {
        readJson = this.fieldValue;
        var count = 0;
        if (readJson != null && readJson != "") {
            readJson.forEach(function (entry) {
                var itemJson = JSON.parse(entry);
                listArr[count++] = itemJson;
            });
        }
    } else if (this.fieldName != '') {
        readJson = granite.resource.properties[this.fieldName];
        if (typeof readJson != "undefined" && readJson != null && readJson != "") {
            if (readJson.length > 0) {
                var count = 0;
                readJson.forEach(function (entry) {
                    var itemJson = JSON.parse(entry);
                    //    out.println(JSON.stringify(itemJson))
                    listArr[count++] = itemJson;
                });
            } else {
                listArr[0] = JSON.parse(readJson);
            }
        }
    }
    return {
        listJson: listArr
    }
});

Here is the snapshot how data is rendering via this approach.




Hope this will help.





5 comments:

  1. can you please provide the convertToJSON.js file it will be very helpfull for us

    ReplyDelete
  2. Hi,
    readJson = granite.resource.properties[this.fieldName];

    Granite is used for Touch UI. Can we use something for classic UI which serves the same purpose as of granite.

    ReplyDelete
  3. After reading this blog i very strong in this topics and this blog really helpful to all...Ruby on rails Online Course India

    ReplyDelete
  4. this is awesome dude, thanQ very much.. have a good daY

    ReplyDelete