Putting Answers into YUI Tables
Usage
The Description section below explains the service item implementation. To try the service item that is being described, download the attached service item (in .zip format) and use the Kinetic Request Admin Console to import the service item into your environment. The Service Item does not include category/catalog information, so it will need to be copied or moved to an existing catalog to be accessed.
The service item is available here.
Description
This example utilizes the YUI javascript library to automatically build the table from the Simple Data Request response.
For more information about the YUI javascript library, see the Yahoo Developer Network: http://developer.yahoo.com/yui/
Sample Table
This example displays a table of records obtained by the customer entering answers and submitting them as a row to the table. There are four steps necessary to configure a Kinetic Request service item to display a table of user answers:
- Require the javascript and css files necessary for YUI data tables
- Create the questions that have answers entered into the table and the table div
- Build the functions to process the tables
- Create the buttons for adding/removing rows and the events to support table build and save
1. Require the javascript and css files necessary for YUI data tables.
The following code was inserted into the customer header content for this service item to load the javascript and css files necessary for YUI datatables.
<script type="text/javascript" src="/kinetic/resources/js/yui/build/yahoo-dom-event/yahoo-dom-event.js"></script> <script type="text/javascript" src="/kinetic/resources/js/yui/build/element/element-min.js"></script> <script type="text/javascript" src="/kinetic/resources/js/yui/build/datasource/datasource-min.js"></script> <script type="text/javascript" src="/kinetic/resources/js/yui/build/datatable/datatable-min.js"></script> <link rel="stylesheet" type="text/css" href="/kinetic/resources/js/yui/build/datatable/assets/skins/sam/datatable.css" />
- buildTables()
- saveTables()
- deleteTableRows(table_str)
- saveTable(table_obj, save_to)
Then, each table must have it's own function to build the table for display (this converts the saved JSON into an HTML object/table and places it into the specified div) and it's own function to add rows.
<script> //define table variable var tableItems; /*******************Shared Table Functions************************* ** These functions can be extended to handle more than one table ** ******************************************************************/ //Build the table for display on page load function buildTables() { //Build the items table from the indicated stored JSON buildItemTable('itemsTableJSON', 'itemsTable'); } //run saveTables before submit function saveTables() { var toReturn = true; if (!saveTable(tableItems, "itemsTableJSON")) toReturn = false; return toReturn; } //this function is to delete a row from a table function deleteTableRows(table_str) { var selected = false; //Set the table to delete from switch(table_str) { case "tableItems" : table_obj = tableItems; break; } //Get the table object var tbl = table_obj.getTableEl(); //determine which row is seleted var selIdx = 0; for (var x = 0; x < tbl.rows.length; x++) { if(table_obj.isSelected(x)) { selected = true; selIdx = x; } } if (selected == false) { alert("No row selected"); } else { //delete row table_obj.deleteRow(selIdx); } } function saveTable(table_obj, save_to) { //get the records for the given table object var records = table_obj.getRecordSet().getRecords(); //store these records as a json string var str="["; for (var i=0; i < records.length; i++) { str= str+"{\""; var keys = table_obj.getColumnSet().keys; for (var j=0; j < keys.length; j++) { str= str+keys[j].getKey(); str=str+"\":\""; str=str+records[i].getData(keys[j].getKey()); if(j== (keys.length)-1) { if(i== (records.length)-1) { str= str+"\"}"; } else { str= str+"\"},"; } } else { str= str+"\",\""; } } } str=str+"]"; //the size of the full answer field is 4000. We need to make sure //the table saved as a JSON string fits into the available space. var checkSize = str.length; if (checkSize > 4000) { //if the string is too long, alert and return false alert("There are too many rows in the table. This row will not be added."); return false; } else { //if the string isn't too long, save the table KD.utils.Action.setQuestionValue(save_to, str); return true; } } /********************End of Shared Table Functions**************************/ //Build the item table from the provided JSON string and display in provided //div tag function buildItemTable(jsonDataQuestion, divTag) { var oTxt = KD.utils.Action.getQuestionValue(jsonDataQuestion); //Either parse data or, if JSON is empty, set an empty datasource if (oTxt.length == 0) { var myDataSource = new YAHOO.util.DataSource([]); } else { var myDataSource = new YAHOO.util.DataSource(YAHOO.lang.JSON.parse(oTxt)); } myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY; myDataSource.responseSchema = { fields: [ { key: "item" }, { key: "size" }, { key: "color" }, { key: "quantity" }, { key: "comment" } ] }; // CONFIGURE: The following variable defines which element the YUI data table // will be inserted into and will need to be set to an element that exists // in the service item. var containerElement = divTag; // CONFIGURE: The following variable defines what columns will be displayed in // the table and will need to be configured for the specific Simple Data // Response. Note that these are sortable columns var myColumnDefs = [ {key:"item", label:"Item", sortable:true}, {key:"size", label:"Size", sortable:true}, {key:"color", label:"Color", sortable:true}, {key:"quantity", label:"Quantity", sortable:true}, {key:"comment", label:"Comment", sortable:true} ]; // Ensure that the body element has the yui-skin-sam class so that the YUI // css classes for data tables are applied properly. YAHOO.util.Dom.addClass(document.body, 'yui-skin-sam'); // Build the data table widget tableItems = new YAHOO.widget.DataTable(containerElement, myColumnDefs, myDataSource); tableItems.subscribe("rowMouseoverEvent", tableItems.onEventHighlightRow); tableItems.subscribe("rowMouseoutEvent", tableItems.onEventUnhighlightRow); tableItems.subscribe("rowClickEvent", tableItems.onEventSelectRow); tableItems.subscribe("theadLabelClickEvent", tableItems.onEventSortColumn); } //Add a row to the table function addItemRow(use_key) { use_key = (typeof use_key == 'undefined')?true:use_key; var txtId = KD.utils.Action.getQuestionValue('Item'); var txtSize = KD.utils.Action.getQuestionValue('Size'); var txtColor = KD.utils.Action.getQuestionValue('Color'); var txtQuantity = KD.utils.Action.getQuestionValue('Quantity'); //Check that all required items are entered before allowing the row add //In this example, all columns are required except the comment if (txtId == '' || txtSize == '' || txtColor == '' || txtQuantity == '') { alert('Please fill in Item, Size, Color and Quantity before clicking add'); return; } //Check the table to see if a duplicate row exists //In this example, there cannot be the same item, size, and color entered more than once //Note that if duplicates aren't a concern, you don't need this step len = tableItems.getTbodyEl().rows.length for(var i=0; i<len;i++){ var iRecord = tableItems.getRecord(i); var iItem = iRecord.getData('item'); var iSize = iRecord.getData('size'); var iColor = iRecord.getData('color'); if (iItem == txtId && iSize == txtSize && iColor == txtColor){ alert('You have already added '+iSize+', '+iColor+' '+iItem+' to the table'); return; } } //All checks passed, enter the given values into tableItems.addRow({item:txtId, size:txtSize, color:txtColor, quantity:txtQuantity, comment: KD.utils.Action.getQuestionValue('Comment')}); //Clear the previously selected options/reset defaults KD.utils.Action.setQuestionValue('Item', ''); KD.utils.Action.setQuestionValue('Size', ''); KD.utils.Action.setQuestionValue('Color', ''); KD.utils.Action.setQuestionValue('Quantity', '1'); KD.utils.Action.setQuestionValue('Comment', ''); //Save the table. This checks to make sure they haven't exceeded the allowable table size. //If the save fails, build the table to visually clear the row that couldn't be saved. if (!saveTable(tableItems, "itemsTableJSON")) buildItemTable('itemsTableJSON', 'itemsTable'); } </script>

<input type="button" value="Add Item to Table >>" onclick="addItemRow();"> <input type="button" value="<< Remove Selected Row" onclick="deleteTableRows('tableItems');">