Using a Bridge Search to Populate Questions using a YUI Table
Usage
The example provided in this solution is a use case for allowing a user to do a search in a service item by keying in a partial or complete match into a question and clicking a button. A search is then done and, if one exact match is found, the desired fields are filled in immediately; if no matches are found, the user is notified; and if there is more than one match the user is presented with the resulting options in a table. In this example, the table is a YUI table. Two key factors are in play for this particular example: (1) a Bridge was used to acquire the data and (2) a YUI table was used to display the data. If you are not already using/relying on YUI tables in your theme, we would strongly suggest you use JQuery DataTables instead. Please see this example.
The Example 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.
You will need an ARS Bridge installed. To use the example, you will need to load either the CTM:People Example People Bridge Model or the KS_SAMPLE_People Example People Bridge Model, both provided on this article. If you use ITSM, you'll want to use the CTM:People Bridge Model. Otherwise, load the KS_SAMPLE_People Bridge Model. If you use the Sample People form, you may have no data in the form. A very small import has been provided to get you started.
Example
This example allows the user to trigger a bridge search to populate questions. To support this there must be:
1. All the necessary code required (the javascript and css files) for jquery and YUI
Note that these are web (http) references. If you were using this as a long-term solution on your server, you'd want to download the sources you need into your theme and reference the local copies.
<!-- Dependencies --> <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script> <script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script> <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script> <link rel="stylesheet" type="text/css" href="resources/css/jquery-ui.css"> <script src="http://yui.yahooapis.com/2.9.0/build/yahoo/yahoo-min.js"></script> <script src="http://yui.yahooapis.com/2.9.0/build/event/event-min.js"></script> <script src="http://yui.yahooapis.com/2.9.0/build/json/json-min.js"></script> <script src="http://yui.yahooapis.com/2.9.0/build/connection/connection-min.js"></script> <script src="http://yui.yahooapis.com/2.9.0/build/get/get-min.js"></script> <script src="http://yui.yahooapis.com/2.9.0/build/datasource/datasource-min.js"></script> <script src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script> <link type="text/css" rel="stylesheet" href="http://yui.yahooapis.com/2.9.0/build/datatable/assets/skins/sam/datatable.css"> <script src="http://yui.yahooapis.com/2.9.0/build/yahoo-dom-event/yahoo-dom-event.js"></script> <script src="http://yui.yahooapis.com/2.9.0/build/json/json-min.js"></script> <script src="http://yui.yahooapis.com/2.9.0/build/dragdrop/dragdrop-min.js"></script> <script src="http://yui.yahooapis.com/2.9.0/build/calendar/calendar-min.js"></script> <script src="http://yui.yahooapis.com/2.9.0/build/datatable/datatable-min.js"></script>
2. A question the user places their query parameter into
In this case, the example uses the field "Search Last Name"
3. Search (and Clear) button(s) and Event(s) to perform the functions.
<div id="search buttons" class="searchButtons"> <button value="Clear" id="b_clearProxy" class="templateButton" >Clear</button> <button value="Search" id="b_searchProxy" class="templateButton" >Search</button> </div>
if (validateSearch('Search By Last Name')) { findPeople(KD.utils.Action.getQuestionValue('Search By Last Name')); }
The bridge being used here is available for download with the example. There are two available, depending on what system you have set up. If you use CTM:People, there is one that uses that; otherwise there is one that uses KS_SAMPLE_People, so you should be able to use the example with or without ITSM.
4. Questions for the results to go in
5. The table div
<div id="peopleTableDialog"><div id="peopleTable"></div></div>
6. A function that defines/does the search (see code comments for details)
function validateSearch(questionName){ //check to make sure the question being used to search on contains a value var lastName = KD.utils.Action.getQuestionValue(questionName); if (lastName == "" || lastName == null) { alert("Please enter all or part of the last name before pressing the Search button"); return false; } return true; } //Define table variable var peopleTable; function findPeople(lastName){ var lastNameAttribute; /* if using Kinetic Request v5.2.8 or greater */ lastNameAttribute = '<%=attribute["Last Name"]%>:ASC'; /* if using Kinetic Request v5.2.7 or lower */ lastNameAttribute = encodeURIComponent('<%=attribute["Last Name"]%>:ASC') //create a new connector to use for a bridge call var connector = new KD.bridges.BridgeConnector(); //Search using the Example People bridge, the By Last Name qualification, connector.search('Example People', 'By Last Name', { //order by the last name attribute in ascending order metadata: {"order": [lastNameAttribute] }, //pass the variable lastName as the parameter 'Last Name' parameters: {'Last Name':lastName}, //get the specified list of parameters as results attributes: ["Company","Department","Email","First Name", "Full Name", "Last Name", "Organization", "Phone", "Region", "Site","User Id"], //and, if successful, run the populatePeopleTable function success: populatePeopleTable }); }
7. A function that processes the search result/populates the table (see code comments for details)
function populatePeopleTable(response) { // 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 = "peopleTable"; // CONFIGURE: The following defines what columns will be displayed in // the table and will need to be configured for the Bridge // Response. var columnDefinitions = [ {key:"Last Name", label:"Last Name"}, {key:"First Name", label:"First Name"}, {key:"Email", label:"Email"}, {key:"Phone", label:"Phone"}, {key:"Organization", label:"Organization"}, {key:"Department", label:"Department"}, {key:"Region", label:"Region"}, {key:"Site", label:"Site", width: "200px"}, {key:"User Id", label:"User Id", className: 'hidden'} ]; var config = { caption:"Search results (click to select one):", scrollable: "y", height: "270px", width: "880px"}; // Build an array from the Bridge results var data = new Array; for (var i=0;i<response.records.length;i++) { data.push(response.records[i].attributes); } if (data.length == 0) { //error if no results were returned alert("No people match the search value."); return; } else if (data.length == 1) { //if one result is returned, no table is needed so just call the setPerson function and return setPerson(data); return; } // CONFIGURE: (fields) // Initialize a dataSource to process the results var dataSource = new YAHOO.util.DataSource(data); dataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY; dataSource.responseSchema = { resultsList: "data", fields: ["Company","Department","Email","First Name", "Full Name", "Last Name", "Organization", "Phone", "Region", "Site","User Id"] }; // 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 peopleTable = new YAHOO.widget.DataTable(containerElement, columnDefinitions, dataSource, config); $('#peopleTableDialog').dialog({ modal: true, draggable: true, width: 900, title: "Search results (click to select one):", position: { my: "left center", at: "left center", of: window } }); definePeopleTableClickEvent(peopleTable); }
8. Functions that populates the questions and to get the data values out of the row (see code comments for details)
function definePeopleTableClickEvent(peopleTable) { peopleTable.subscribe("rowMouseoverEvent", peopleTable.onEventHighlightRow); peopleTable.subscribe("rowMouseoutEvent", peopleTable.onEventUnhighlightRow); peopleTable.subscribe("rowClickEvent", function(oArgs) { // set the person information var tar = oArgs.target; var oRecord = this.getRecord(tar); KD.utils.Action.setQuestionValue("People Login ID", oRecord.getData("User Id")); KD.utils.Action.setQuestionValue("People First Name", oRecord.getData("First Name")); KD.utils.Action.setQuestionValue("People Last Name", oRecord.getData("Last Name")); KD.utils.Action.setQuestionValue("People Email", oRecord.getData("Email")); KD.utils.Action.setQuestionValue("Search By Last Name", ""); // destroy the dialog clearAndClosePeopleTable(); }); } function setPerson(data) { //set the questions out of the data provided, which is an array of length 1 KD.utils.Action.setQuestionValue("People Login ID", data[0]("User Id")); KD.utils.Action.setQuestionValue("People First Name", data[0]("First Name")); KD.utils.Action.setQuestionValue("People Last Name", data[0]("Last Name")); KD.utils.Action.setQuestionValue("People Email", data[0]("Email")); KD.utils.Action.setQuestionValue("Search By Last Name", ""); }
and
9. A function to closes/cleans up the table
function clearAndClosePeopleTable() { $("#peopleTable").html(""); $("#peopleTableDialog").dialog('close'); }