views:

1956

answers:

2

Hi,

I am trying to use the YUI datatable to display data from a JSON object which looks like this:

{"results":[{"label":"Column 1","notes":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "},{"label":"Column 2","notes":"Lorem ipsum dolor sit amet, consectetur adipiscing elit."},{"label":"Column 3","notes":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "},{"label":"Column 4","notes":"Lorem ipsum dolor sit amet, consectetur adipiscing elit."},{"label":"Column 5","notes":"Lorem ipsum dolor sit amet, consectetur adipiscing elit."},{"label":"Column 6","notes":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "}]}

I can do this fine with the standard implementation. However, the column names (labels in above object) are dynamic so I will not know them until the data reaches the page. I therefore want to define the column definitions from the datasource which I am doing in doBeforeParseData().

From reading / IRC, it has been suggested that I should be able to add columns to the data table. I want the table to look like this:

Column 1 Column 2.......

note note.....

so the above data should produce one row of data. Here's what I have so far:

function loadTable() {

  YAHOO.example.Basic = function() {


    var myColumnDefs = [];

    var myDataSource = new YAHOO.util.DataSource("/index/testajax");
    myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;


    myDataSource.doBeforeParseData = function (oRequest, oFullResponse, oCallback) {

       // alert(oFullResponse);

     var colDefs = [];
     var len = oFullResponse.results.length;
     for (var i = 0; i < len; i++) {
      var obj = {
       key: oFullResponse.results[i].label,
       sortable: true,
       resizeable: true
      };
      myColumnDefs.push(obj);

     }
      console.log(myColumnDefs); 
        return oFullResponse;
    };

    myDataSource.responseSchema = {
        resultsList:"results",
        fields: ["label","notes"]
    };

    var myDataTable = new YAHOO.widget.DataTable("json",
            myColumnDefs, myDataSource, {caption:"DataTable Caption"});

    return {
        oDS: myDataSource,
        oDT: myDataTable
    };
}();


}

Would be grateful for on any input on HOW to do this rather than why I shouldn't ;-)

thanks,

codecowboy

+2  A: 

I spent a bit of my lunch hour on this, but I got something working for you. I looked at your JSON and the way you did it would not work in the data table. results is a list, every entry is a row, and every attribute is a column. Here is the json that I came up with that I hope works for you.

{
    "resultSet":{
        "columnList":[
            {"key":"Column1","label":"My Col 1"},
            {"key":"Column2","label":"My Col 2"},
            {"key":"Column3","label":"My Col 3"}
        ],
        "results":[
            {
                "Column1":"Row 1 value",
                "Column2":"Row 1 value",
                "Column3":"Row 1 value"
            },
            {
                "Column1":"Row 2 value",
                "Column2":"Row 2 value",
                "Column3":"Row 2 value"
            }
        ]
    }
}

I made a small javascript object for handling what you need to do. What needs to be done is you need to make an ajax call to the server for the data. This is so you can define the columns in the datasource before you MAKE the datasource.

function DataProvider(url){
            this.url = url;
        }

        DataProvider.prototype = {
            url:null,
            data:null,
            ds:null,
            getData:function() {return this.data},
            initialize:function(){
                YAHOO.util.Connect.asyncRequest('GET', this.url, this);
            },
            success:function(response){
                var responseVal = YAHOO.lang.JSON.parse(response.responseText);
                var columnList = responseVal.resultSet.columnList;
                this.data = responseVal.resultSet.results;
                this.ds = new YAHOO.util.FunctionDataSource(function(){return this.dataProvider.getData()});
                this.ds.responseSchema = {
                    resultsList:"resultSet.results",
                    fields:columnList
                }
                this.ds.dataProvider = this;
                /* make call to initialize your table using the data set */
                var myDataTable = new YAHOO.widget.DataTable("basic", columnList, this.ds, {caption:"DataTable Caption"});

                //console.debug(columnList);
                //console.debug(this.data);
            }
        }

So when the page loads do the following

function init(){
    var dataProvider = new DataProvider('testjson.json');
    dataProvider.initialize();
}

And your html should look like this

<body onload="init()" class="yui-skin-sam">
    <div id="basic"></div>
</body>

And you should have the following scripts included

<!-- css -->
    <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.7.0/build/datatable/assets/skins/sam/datatable.css"&gt;
    <!-- js -->
    <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js"&gt;&lt;/script&gt;
    <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/connection/connection-min.js"&gt;&lt;/script&gt;
    <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/datasource/datasource-min.js"&gt;&lt;/script&gt;
    <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/element/element-min.js"&gt;&lt;/script&gt;
    <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/datatable/datatable-min.js"&gt;&lt;/script&gt;
    <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/json/json-min.js"&gt;&lt;/script&gt;

That should work, works for me in both IE and firefox.

Zoidberg
Thanks for the reply. To be clear, would the data coming back from my JSON call contain these meta fields?
codecowboy
Yes, in the answer, the return json is what comes back from the server. This will allow you to define your columns in the meta data that comes back in the json request from the server.
Zoidberg
I get oFullResponse.response is undefined
codecowboy
http://pastie.org/587324
codecowboy
What JSON is coming into your data table? If you need to use Firebug to check it (if you don't already have it). Also try oFullResponse.meta.ColumnList and see if that is defined. I haven't used the meta data in the function you are using. You can also do this after the data is fully loaded and the table is rendered if you'd like.
Zoidberg
I have tried multiple variations. Also, is your 'columnList' supposed to equate to my columnDefs? JSONLint complains at "columnList":[{label:'my column',key:'column1'}] As the label and key need to be in quotes. Which begs the question - is this going to work?
codecowboy
Yeah column list must be in quotes for the JSON parser to parse it properly. The data in column list can be whatever you want it to be, your going to be using it directly to add your columns on the fly. The meta data part of the response schema specifies fields that are in the JSON as pure meta data. This is a list of variable names it will look for in your json. It will then put the data retreived from the fields under the same name in the meta property of the response object. Would you like me to do a complete example and post it? The one I posted was just a quick one.
Zoidberg
if you have the time, that would be legendary! It is driving me mental :-( The important bit for me is that the column names are not known until the JSON data comes back and I need to understand how to add my 'notes' as fields under the columns. thanks!
codecowboy
most recent JSON http://pastie.org/589967
codecowboy
Ahh, i get it now... you don't know the columns at all, so you can't define them in your dataset. Let me think about this and I will update my answer.
Zoidberg
Thanks loads for taking the time to do this. It looks great. I will let you know when I've had a chance to try it.
codecowboy
A: 

Hi,

I was searching through the net for dynamic columns display.It is working fine.Thanks a lot for the code.

I have another problem How to format currency if i given YAHOO.widget.DataTable.formatCurrency

It is not working fine.I got the columns list as below

"ColumnsList":[ {"key":"CustomerName","label":"Customer Name","sortable":true},{"key":"OrderNumber","label":"Order Number","sortable":true},{"key":"ProductType","label":"Product Type","sortable":true}, {"key":"Mar_2009","label":"Mar 2009","sortable":true,"formatter":"YAHOO.widget.DataTable.formatCurrency"},{"key":"Apr_2009","label":"Apr 2009","sortable":true,"formatter":"YAHOO.widget.DataTable.formatCurrency"} ]

But formatting is not effecting.

Please help me to sort it out

Thanks & Regards, Sobha

ask a new question - people will not see this.
codecowboy