Skip to main content
Kinetic Community

Searching (for Tables, Lists, Single Results)

This library provides a simple and consistent way to build a search function into a Request service item.  The search.js file contains the main script required to preform the bridge (or Simple Data Request) call and data transfer.  The searchConfig.js (an example config file, with some js to manage the UI in the example Request. It is not part of the library) contains some behavior features that interact with the UI and Search. This is basically an example of how to configure and use your search.  

 
The Search function features:​
  • Execute a search of the specified Bridge or Simple Data Request using the specified qualification when given the required parameter and returns the requested attributes.

  • Multiple results can be returned as an unordered list with classes as specified by the developer or as a dataTable (see http://datatables.net/ for more information on dataTables).

  • Searches are run by running KDSearch.executeSearch(configObject.MainConfig, configObject.OptionalOverrideConfig);  which can be run on command (event) or at initialization (of the page)

  • As with dataTables, callbacks are before, success, success_empty, error, complete and clickCallback.  Any of the DataTables callbacks may be additionally used by including them into the KDSearch config. 

  • Results can be set into questions from single or list/table results.

Requirements

  • search.js file 
  • A file js containing search configuration (or a search configuration in your local advanced header)
  • datatables-1.10.X data tables directory 
  • datatables-responsive-plugin data tables directory 

The library files and examples are available on the Kinetic Community GitHub.

 
Sample Javascript Import requirements (this assumes 1.10.7, use whatever version you downloaded. Also, if the responsive plugin has a different name, you can keep the original name it downloaded with.)
<!-- Page Javascript -->
<script type="text/javascript" src="<%=bundle.bundlePath()%>libraries/kinetic-search/js/search.js"></script>
<script type="text/javascript" charset="utf8" src="<%=bundle.bundlePath()%>libraries/datatables-1.10.7/media/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" charset="utf8" src="<%=bundle.bundlePath()%>libraries/datatables-responsive-plugin/dataTables.responsive.js"></script>
 
Sample CSS import requirements (this assumes 1.10.7, use whatever version you downloaded. Also, if the responsive plugin has a different name, you can keep the original name it downloaded with.)
<!-- Page Stylesheets -->
<link rel="stylesheet" type="text/css" href="<%=bundle.bundlePath()%>libraries/datatables-1.10.7/media/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="<%=bundle.bundlePath()%>libraries/datatables-responsive-plugin/dataTables.responsive.custom.css">

After adding all of the required files to the catalog's library directory they need to be included as shown above by importing them into the service items. It is best to avoid putting the above import requirements in head.jspf, but to place them into service.jsp (or whatever you are using for the service item JSP is that you are using) instead. Included at this level, the library can then be leveraged by any service item. Then a service item that will use the search function can be made. The next steps would depend on how the search was being leveraged. Three example usages follow. These should outline enough of how to use the library to get started.

Example Usage - Bridge Single, Bridge Table

This example is an "On Behalf Of" functionality. The service item automatically, when opened, loads the logged in user as the Requested for, but gives this user the ability to say this request is for someone different by searching for a different individual. There are several components of this setup (1) the initial search on page load that completes the questions with the logged in user's information, (2) the portion of the page the user interacts with to initiate the search for the new requested for, (3) the search triggered on enter or click (or both) for the new user that will, when a user is found/selected, set that new user as the requested for instead. 

The first thing to do is build the service item so all of the questions are in place.

 An input element  or question will need to be added to page to support the behavior for the search for someone else and to let the user know who the request is for. In this example this is done with questions for the Requested For and Manager searches.

The next step is to set up the actual searches. This code (below) can be included in the advanced header or a shared JS. In this particular type of case where the functionality is likely to be reused in many service items, a shared JS file that is loaded in the JSP is recommended. The loadSearch function would, in this case, be called in an on load event of the service item, running the initial search. 


function loadSearch() {
KDSearch.executeSearch(searchConfig.defaultRequestedFor);
KDSearch.executeSearch(searchConfig.defaultMgrConfig);
}


var lastNameAttribute;
/* if using Kinetic Request 5.2.8 or greater */
lastNameAttribute = '<%=attribute["Last Name"]%>:ASC';
/* if using Kinetic Request 5.2.7 or lower */
lastNameAttribute = encodeURIComponent('<%=attribute["Last Name"]%>:ASC');
​​​​​​​

//This is a requested for/manager example
searchConfig ={
    requestedForConfig:{
        // type: "BridgeDataTable", "BridgeList", "BridgeGetSingle", or "performSDRTable".  Determines default values to be used and behavior.
        type: "BridgeDataTable",
        // responsive: OPTIONAL Default for "BridgeDataTable" is true but can be over written.
        //responsive: false,
        bridgeConfig:{
            //The name of the model used is specified here
            model: "People",
            //The qualification mapping used is specified here. Note that this bridge and qualification mapping must be
            //exposed on the service item where this is being used.
            qualification_mapping: "Enabled By Last Name",
            //Params to be created and passed to the Bridge.  VALUE MUST BE JQUERY SELECTOR if specified as a string.
            //This allows you to select values out of any element on the page, question or just dom element.
            //Otherwise, pass a function that returns the desired value. The function allows use of variables, etc.
            //Below is an example of getting the value out of a text question with jQuery (you could also use a function 
            //and KD.utils.Action.getQuestionValue) but getting a value out of a drop down list question is slightly 
            //different '[label="QuestionLabelHere"] select' 
            parameters: {'Last Name': '[label="Search By Last Name"] input'},
            //bridge metadata settings can be passed through
            metadata: {"order": [lastNameAttribute] },
        },
        // processSingleResult does the same thing as the click callback would do if there is just one result
        // found, rather than displaying the one row for the user to click on. For console tables or tables you
        // want to always display, even if there is just one record, this should be set to false.
        processSingleResult: true,
        // Properties in the data must match the attributes of the Bridge Request or have a "notdynamic" option set to true. This would be on
        // the same level as title and className
        data: {
            "Last Name":{
                //This will be the title of the column or the label of the element, depending on the search type
                title:"Last",
                //This will be the class given to the column/cell/div as appropriate for the search type
                className: "all",
                //This is the menu label of the question to be set with the value from this column and row when a row is clicked.
                setQstn:"ReqFor_Last Name",
            },
            "First Name":{
                title:"FIRST",
                //For responsive datatables, a class of all always displays, none is in the subrow data (responsive data), and never is always hidden
                //For non-responsive datatables, a class of hidden will hide the column. see https://datatables.net/extensions/responsive/classes
                //for more details and options
                className: "all",
                setQstn:"ReqFor_First Name"
            },
            "Login ID":{
                title:"LOGIN",
                className: "none",
                setQstn:"ReqFor_Login ID",
            },
            "Phone Number":{
                title:"PHONE",
                className: "none",
                setQstn:"ReqFor_Phone",
            },
            "E-mail":{
                title:"EMAIL",
                className: "all",
                setQstn:"ReqFor_Email",
            },
            "SupervisorID":{
                title:"Manager",
                className: "never",
                setQstn:"Mgr_Login ID",
            }
                                               
        },
        //Where to append the table. This element should exist on the page
        //If a string is returned it will be processed as jQuery. Otherwise
        //return the element in a function.
        appendTo: function(){return $('[label="Search Buttons"]');},
        //ID to give the table when creating it. This should not already exist
        resultsContainerId: 'reqForTable',
        before: function(){ //before search
           //disable the search button so it can't be re-clicked and display a spinner/wait icon
           $('#searchReqFor').prop('disabled',true);
           $('#spinner_searchReqFor').show();
        },
        success: function (){ //this is done when results are returned successfully
          //hide the spinner/wait icon
          $('#spinner_searchReqFor').hide();
        },
        success_empty: function(){  //this is done if a successful search returns no results
          //hide the spinner/wait icon and display an alert
          $('#spinner_searchReqFor').hide();
          alert("Your search criteria did not return any results, please check your criteria and try again.");    
        },
        error: function(){  //this is done if the search errors
           
        },
        complete: function(){  //this is done when the build of the table completes
           //format the resultant table to a particular width, for example.
           $('#reqForTable').width(936);
        },
        clickCallback: function(results){  //this is additional action (beyond set question) that happens on row click.
            //the values of the row are available in results, indexed by the name of the attribute in the bridge
            //in this case, we are setting the returned supervisor ID into an additional question, firing change
            //of that question element, clearing the search field, and re-enabling the search button.
            KD.utils.Action.setQuestionValue('Mgr_Login ID', results['SupervisorID']);
            var MgmrElem = KD.utils.Util.getQuestionInput("Mgr_Login ID");
            KD.utils.Action._fireChange(MgmrElem);
            KD.utils.Action.setQuestionValue("Search By Last Name", "");
            $('#searchReqFor').prop('disabled',false);
        },
        createdRow: function ( row, data, index ) {  //this is done when the row is being built (a pass through to datatables)
           //see https://datatables.net/reference/option/createdRow for details/options
        },
        dom: 'frtip',
    },
    defaultRequestedForConfig:{
        // type: "BridgeDataTable", "BridgeList", "BridgeGetSingle", or "performSDRTable".  Determines default values to be used and behavior.
        type: "BridgeGetSingle",
        bridgeConfig:{
            model: "People",
            qualification_mapping: "By Login ID",
            //Params to be created and passed to the Bridge.  VALUE MUST BE JQUERY SELECTOR if specified as a string.
            //This allows you to select values out of any element on the page, question or just dom element.
            //Otherwise, pass a function that returns the desired value. The function allows use of variables, etc.
            parameters: {'Login ID':  function(){return clientManager.userName;}},
        },
        processSingleResult: true,
        // Properties in the data must match the attributes of the Bridge Request
        data: {
            //Note that title and class are not relevant options for BridgeGetSingle. The only relevant data options
            //are setQstn and Callback.
            "Last Name":{
                //This is the menu label of the question to be set with the value from the record found
                setQstn:"ReqFor_Last Name",
            },
            "First Name":{
                setQstn:"ReqFor_First Name"
            },
            "Login ID":{
                setQstn:"ReqFor_Login ID",
            },
            "Phone Number":{
                setQstn:"ReqFor_Phone",
            },
            "E-mail":{
                setQstn:"ReqFor_Email",
            },
            "SupervisorID":{
                //since there is no row click (no table, no rows), if something should happen when the results are returned/set, a Callback
                //function should be set on one (or more) of the data values.
                callback:function(value){
                    //in this case we are setting the Mgr_Login ID and firing change, as we did on row click in the table above. For this 
                    //default user config, using BridgeGetSingle we need to do it here in a Callback instead.
                    KD.utils.Action.setQuestionValue('Mgr_Login ID', value);
                    var MgmrElem = KD.utils.Util.getQuestionInput("Mgr_Login ID");
                    KD.utils.Action._fireChange(MgmrElem);
                },
                setQstn:"OrigMgr_Login ID",
            }
                                               
        },
        //Where to append the table
        appendTo: function(){return $('[label="This Request is For"]');},
        //ID to give the table when creating it.
        resultsContainerId: 'reqForTable',
        before: function(){ //before search
          
        },
        success: function (){  //this is done when the search returns successfully                           
           
        },
        success_empty: function(){  //this is done when the search returns empty/no result. 
            //Note that if this is empty, no result will "fail" silently
            alert("Your search criteria did not return any results, please check your criteria and try again.");
        },
        error: function(){  //This occurs if there is an error on the search      
        },
        dom: 'frtip',
    },
    mgrConfig:{
        // type: "BridgeDataTable", "BridgeList", "BridgeGetSingle", or "performSDRTable".  Determines default values to be used and behavior.
        type: "BridgeDataTable",
        // responsive: OPTIONAL Default for "BridgeDataTable" is true but can be over written.
        //responsive: false,
        bridgeConfig:{
            model: "People",
            qualification_mapping: "Enabled By Last Name",
            parameters: {'Last Name': '[label="Mgr Search By Last Name"] input'},
        },
        processSingleResult: true,
        // Properties in the data must match the attributes of the Bridge Request or have a "notdynamic" option set to true. This would be on
        // the same level as title and className
        data: {
            "Last Name":{
                //This will be the title of the column or the label of the element, depending on the search type
                title:"Last",
                //This will be the class given to the column/cell/div as appropriate for the search type
                className: "all",
                //This is the menu label of the question to be set with the value from this column and row when a row is clicked.
                setQstn:"Mgr_Last Name",
            },
            "First Name":{
                title:"FIRST",
                //For responsive datatables, a class of all always displays, none is in the subrow data (responsive data), and never is always hidden
                //For non-responsive datatables, a class of hidden will hide the column. see https://datatables.net/extensions/responsive/classes
                //for more details and options
                className: "all",
                setQstn:"Mgr_First Name"
            },
            "Login ID":{
                title:"LOGIN",
                className: "none",
                //callback is also a valid option for type: "BridgeDataTable", "BridgeList". It happens when a row/item is selected
                callback:function(value){
                    KD.utils.Action.setQuestionValue('Mgr_Login ID', value);
                    var MgmrElem = KD.utils.Util.getQuestionInput("Mgr_Login ID");
                    KD.utils.Action._fireChange(MgmrElem);
                },
                setQstn:"Mgr_Login ID",
            },
            "Phone Number":{
                title:"PHONE",
                className: "none",
                setQstn:"Mgr_Phone",
            },
           "E-mail":{
                title:"EMAIL",
                className: "all",
                setQstn:"Mgr_Email",
            },
            
                                               
        },
        //Where to append the table
        appendTo: function(){return $('[label="Mgr Search Buttons"]');},
        //ID to give the table when creating it.
        resultsContainerId: 'MgrTable',
        before: function(){ //before search
            $('#searchMgr').prop('disabled',true);
            $('#spinner_searchMgr').show();
        },
        success: function (){
           $('#spinner_searchMgr').hide();
        },
        success_empty: function(){
            $('#spinner_searchMgr').hide();
            alert("Your search criteria did not return any results, please check your criteria and try again.");
        },
        error: function(){
           
        },
        complete: function(){
          
        },
        clickCallback: function(results){
            $('#searchMgr').prop('disabled',false);
            KD.utils.Action.setQuestionValue("Mgr Search By Last Name", "");
        },
        createdRow: function ( row, data, index ) {
        },
        dom: 'frtip',
    },
    defaultMgrConfig:{
         // type: "BridgeDataTable", "BridgeList", "BridgeGetSingle", or "performSDRTable".  Determines default values to be used and behavior.
        type: "BridgeGetSingle",
        // responsive: OPTIONAL Default for "BridgeDataTable" is true but can be over written.
        //responsive: false,
        bridgeConfig:{
            model: "People",
            qualification_mapping: "By Login ID",
            //Params to be created and passed to the Bridge.  VALUE MUST BE JQUERY SELECTOR if specified as a string.
            //This allows you to select values out of any element on the page, question or just dom element.
            //Otherwise, pass a function that returns the desired value. The function allows use of variables, etc.
            //Below is an example of getting the value out of a text question with jQuery (you could also use a function 
            //and KD.utils.Action.getQuestionValue) but getting a value out of a drop down list question is slightly 
            //different '[label="QuestionLabelHere"] select' 
            parameters: {'Login ID': '[label="Mgr_Login ID"] input'},
        },
        processSingleResult: true,
        // Properties in the data must match the attributes of the Bridge Request
        data: {
            "Last Name":{
                title:"Last",
                className: "all",
                setQstn:"Mgr_Last Name",
            },
            "First Name":{
                title:"FIRST",
                className: "all",
                setQstn:"Mgr_First Name"
            },
            "Login ID":{
                title:"LOGIN",
                className: "none",
                setQstn:"Mgr_Login ID",
            },
            "Phone Number":{
                title:"PHONE",
                className: "none",
                setQstn:"Mgr_Phone",
            },
            "E-mail":{
                title:"EMAIL",
                className: "all",
                setQstn:"Mgr_Email",
            },
                                               
        },
        //Where to append the table
        appendTo: function(){return $('[label="Mgr Search Buttons"]');},
        //ID to give the table when creating it.
        resultsContainerId: 'MgrTable',
        before: function(){ //before search         
        },
        success: function (){  //This occurs when results are found     
        },
        success_empty: function(){  //This occurs when the search is successful, but no results are found                                             
        },
        error: function(){  //This occurs if there is an error on the search      
        },
        complete: function(){   //This occurs when the build of the table is complete  
        },
        clickCallback: function(results){  //This occurs on click
          
        },
        createdRow: function ( row, data, index ) { //This occurs when the row is being built
        },
        dom: 'frtip',
    }
}

At time of page load the search runs (because of the loadSearch function running in an on load page event) and does a search by login ID for his login ID, then uses the set question value setup to set the specified questions, so Demo would see:

Example1PageLoad1.png

And then he can choose to search for "Al"

And he would see this table, where he can expand the individual he is interested in (in this case, one of the Allen Allbrook) to make sure that he is choosing the right person, and then select that row. Note the titles of each column match the "title" provided in the data section and the items that can be expanded are those with a class of "none". If there were no items that were to be hidden and then expanded, there would be no icon to expand the row at all. Responsive is smart enough to know not to do that. 

Which would make the service item look like this:

RequestedForAllen1.1.png

It would also set the Mgr Login field and fire the change on that field.

Example Usage - Bridge Request List

For the bridge list example provided here, an input element  or question will be added to page to support the behavior for the search for someone else and to let the user know who the request is for. In this example this is done with div elements within a Dynamic Text field.

<div id="requested_for" class="search-container">
    <div class="search-btn myself active" data-searchconfig="defaultListContact">
        <div class="fa fa-check"></div>
        <div class="myself">Myself</div>
    </div>
    <div class="search-btn someoneelse" data-searchconfig="listContact">
        <div class="fa fa-check"></div>
        <input placeholder="someone else..." style="">
        <div class="fa fa-search" style="cursor: pointer;"></div>
        <div class="searching fa fa-spinner fa-spin fa-lg" style="display: none;"></div>
    </div>
</div>

This will, using additional styling lead to a search looking like this:

ListSearch2.png

And the code configuration for the search config would look like this instead.


// Define Table objects or list Object and initialize them.
searchConfig ={
    listContact:{
        // type: "BridgeDataTable", "BridgeList", "BridgeGetSingle", or "performSDRTable".  Determines default values to be used and behavior.
        type: "BridgeList",
        bridgeConfig:{
            //bridge model listed here
            model: "Person",
            //bridge qualification. This model/qualification must be exposed on the items/forms where this search is used.
            qualification_mapping: "By Full Name",
            //Params to be created and passed to the Bridge.  VALUE MUST BE JQUERY SELECTOR if specified as a string.
            //This allows you to select values out of any element on the page, question or just dom element.
            //Otherwise, pass a function that returns the desired value. The function allows use of variables, etc.
            //Below is an example of getting the value out of a text element on the page that is NOT a question, but
            //has an id of list-contact
            parameters: {'Full Name': '#list-contact input'},
                },
        // Properties in the data must match the attributes of the Bridge Request or have a "notdynamic" option set to true. This would be on
        // the same level as title and className
        data: {
            "First Name":{
                //The title is in a separate div before the data with a class of title
                title:"First",
                //This is the menu label of the question to be set with the value from this column and row when a row is clicked.
                setQstn:"List Contact First Name",
                //This is added as a class to the div for both the title and the data (see example list below)
                className: "contactName",
            },
            "Last Name":{
                title:"Last",
                setQstn:"List Contact Last Name",
                className: "contactName"
            },
            "Email":{
                title:"Email",
                setQstn:"List Contact Email",
                //callback is also a valid option for type: "BridgeDataTable", "BridgeList". It happens when a row/item is selected
                callback:function(value){
                    console.log(value);
                },
                className: "contactData"
            },
            "Login Id":{
                title:"Login",
                setQstn:"List Contact Login ID",
                className: "contactData"
            },
            "Work Phone Number":{
                title:"Phone",
                setQstn:"List Contact Phone",
                className: "contactData"
            },
        },
        //Where to append the table
        appendTo: '#list-contact-results',
        before: function(){ //before search
            //A function, not included here, to make the search unavailable
            toggleUnclickable($('#list-contact'));
        },
        success: function (){  //This occurs when results are found   
            //this shows/unhides the appendTo element with features on the event
            this.appendTo.show("blind", "swing", 1000);
        },
        success_empty: function(){  //This occurs when the search is successful, but no results are found
            //an alert
            alert("No results Found");
        },
        error: function(){ //This occurs if there is an error on the search 
            //make search available again (function not displayed here)
            toggleUnclickable($('#list-contact'));
        },
        complete: function(){ //This occurs when the build of the list is complete
            //make search available again (function not displayed here)
            toggleUnclickable($('#list-contact'));
        },
        clickCallback: function(results){  //This is what happens on selection/click of a list item--in addition to the setQstn 
                //put the name intothe list contact, someoneelse text input, hide list append to element.
                $('#list-contact .someoneelse input').val(results["First Name"]+ ' ' + results["Last Name"]);
                this.appendTo.hide("blind", "swing", 1000);
        },
    },
//The above would generate a result like this:    
//<div id="list-contact-results">
//<ul id="resultList">
//<li id="result">
//<div class="title contactName">First</div>
//<div>Allen</div>
//<div class="title contactName">Last</div>
//<div>Allbrook</div>
//<div class="title contactData">Email</div>
//<div>A.Allbrook@calbroservices.com</div>
//<div class="title contactData">Login</div>
//<div>Allen</div>
//<div class="title contactData">Phone</div>
//<div>1 212 555-5454 (11)</div>
//</li>
//</ul>
//</div>

};

Note that styles are hiding anything with the class "title". Additional styling can be added quite easily, for example:

<style>
.title{
display:none;
}

.contactName{
font-weight: bold;
}

.contactData{
color:blue;
}
</style>

This small amount of additional formatting will do this:

As you can see, these lists can be formatted as desired, using these classes.

Example Usage - Simple Data Request Table

The same case with a simple data request would be slightly more involved because it would require defining a Simple Data Request (rather than re-using an existing Bridge and Bridge qualification) and accessing that SDR, which you will see, is not quite as simple as the Bridge. Initially we will, other than creating the SDR, define this exactly the same way as the searches above. The SDR will be against KS_SAMPLE_People so we can safely provide the sample.

 

But this time instead of a text element and jQuery events to do the search, an event on Requested For Last Name that will trigger the search.

So, define an event against something on the form (preferably one of the relevant fields or some such so it makes sense.) This is uses the Last Name field so that we can ALSO have a keyup event on that field that I'll be describing later (that is easier to do without hard coding things). Add the fields available:

720000001;AddrLine1, 240000005;AR Login, 200000006;Department, 260000002;Email, 240000004;First Name, 240000003;Last Name, 240000111;Office, 240000002;Phone Number,  720000015;Supervisor Name, 3;Create Date

And sort fields, etc, and save the SDR. Once this is defined, along with the page elements as defined in the first section (search elements, requested for fields, etc), you would configure your page much like the first example except that the search element would look like the below. Notice the Instance ID of the search (which you can find in the SDR when you define or modify it, indicated by the red arrow above), and the instance ID of the question used as the parameter, both hard coded. This is necessary because of the way this is set up in an object and can be overridden on the fly during events, etc. This will be discussed next.

searchConfig ={
    
  requestedForSDRTableConfig:{
        // type: "BridgeDataTable", "BridgeList", "BridgeGetSingle", or "performSDRTable".  Determines default values to be used and behavior.
        type: "performSDRTable",
        //simple data request config
        sdrConfig:{
            //ID of the simple data request
            SDRId: 'KSHAA5V0HJEMVANZR2R0KM2F7LBICP',
            //parameter(s) for the search. This example pulls a value out of an text element on the page.
            //pulling one out of a question would look like return "lname="+KD.utils.Action.getQuestionValue("SDR Requested For");
            params: 
            //"lname=Peterson",
            function(){
                return "lname="+$('#SDR_requested_for input').val();
            },
            //Name of the simple data request
            sdrName: 'CallLastNameSDR'
        },
        // processSingleResult does the same thing as the click callback would do if there is just one result
        // found, rather than displaying the one row for the user to click on. For console tables or tables you
        // want to always display, even if there is just one record, this should be set to false.
        processSingleResult: true,
        //data elements must be elements/fields in the simple data request
        data: {
            "AR Login":{
                //This will be the title of the column or the label of the element, depending on the search type
                title:"Login ID",
                //This will be the class given to the column/cell/div as appropriate for the search type
                className: "all",
                //This is the menu label of the question to be set with the value from this column and row when a row is clicked.
                setQstn:"SDR_ReqFor_Login ID"
            },
            "First Name":{
                title:"First Name",
                //For responsive datatables, a class of all always displays, none is in the subrow data (responsive data), and never is always hidden
                //For non-responsive datatables, a class of hidden will hide the column. see https://datatables.net/extensions/responsive/classes
                //for more details and options
                className: "all",
                setQstn:"SDR_ReqFor_First Name"
            },
            "Last Name":{
                title:"Last Name",
                className: "min-tablet",
                setQstn:"SDR_ReqFor_Last Name"
            },
            "Supervisor Name":{
                title:"Manager Name",
                className: "none"
            },
        },
        //Where to append the table. This element should exist on the page
        //If a string is returned it will be processed as jQuery. Otherwise
        //return the element in a function.
        //appendTo: '#SDR_requested_for',
        appendTo: function(){return $('#SDR_requested_for');},
        //a string of the id to give the created table. This should not exist on the page.
        resultsContainerId: 'SDRRequestedForTable',
        before: function(){ //before search         
        },
        success: function (){  //This occurs when results are found     
        },
        success_empty: function(){  //This occurs when the search is successful, but no results are found    
            alert("No results Found");
        },
        error: function(){  //This occurs if there is an error on the search      
        },
        complete: function(){   //This occurs when the build of the table is complete  
        },
        clickCallback: function(results){  //This occurs when a row is clicked
        }
        createdRow: function ( row, data, index ) {  //This is done when the row is being built
        },
    }

};

But, as mentioned above, say you want to make this more dynamic, less hard coded, and/or call it on an event on a question or text element instead of using a jquery on click event. This is how that would work for a SDR:

The same SDR as above would be defined on the element in question, using the input (usually a question) as the parameter. Then, the custom event on click or keyup would have custom code that would look something like this:


  var lastName = KD.utils.Action.getQuestionValue('SDR_ReqFor_Last Name');
  var lastNameElm = KD.utils.Util.getElementObject('SDR_ReqFor_Last Name');
  var lastNameId = null;
  if (lastNameElm && lastNameElm.id) {
    lastNameId = lastNameElm.id.substr(7);
    var sdrparams = '' + lastNameId + '=' + lastName;
    callSDR(clientAction.actionId, sdrparams);
  }

Where the call SDR function extends the requestedForSDRTableConfig provided above (where the SDRId could be specified or left as null, same with parameters), and the execute search called directly and provided both objects:

function callSDR(actionId, sdrParams) {
   var extendsearchConfig = {
   updatedSDRObject :{
        sdrConfig:{
            SDRId: actionId,
            params: sdrParams,
            }
        }
   }
   KDSearch.executeSearch(searchConfig.requestedForSDRTableConfig, extendsearchConfig.updatedSDRObject );
}

The bulk of the search object is created with the first information, but any details provided in the second object override that provided in the first.

Ways of Initiating the searching

In the examples above, the searches are initiated via a non-question element, that is defined with a data-searchconfig attribute on the div:

<div class="search-btn someoneelse" data-searchconfig="requestedForTableConfig">

On key-up if return is pressed and on click of the search icon, this attribute is used to determine which object use for the search config:

searchConfigObj = searchConfig[$(this).closest('.search-btn').data('searchconfig')];
KDSearch.executeSearch(searchConfigObj);


It is also possible to run the searches directly:

KDSearch.executeSearch(searchConfig.requestedForTableConfig);

Note that there are not quotes. It is the actual object being passed in. This can be called in custom on an event or in any JS called by any event.

When running searches directly, it is possible to use one configuration to override another:

KDSearch.executeSearch(submissionSearch.RequestsConfig, submissionSearch.myOpenRequestsConfig);

Any configuration provided in the second object will override that provided in the first. This allows the majority of the configuration, eg. the data and callbacks, to all be defined just once, but the details, eg. the bridge, to be redefined as necessary. The second object does not need to be complete.

Other Important things to Note

  • Features/abilities/functionality of dataTable, ex. fnFooterCallback or dom, can be added directly into the table config and it will be passed right through to the dataTable.
  • If you want to fire change on something you are setting, you will currently need to do that in the click callback. 
  • When setting up the bridge parameter to pull the information from a question (instead of an element defined within a text element on the page), the parameter would look like this: '[label="requested_for"] input' instead of this:  '#requested_for input' (if requested_for was the menu label of the question), but a drop down question would be found as '[label="question name"] select'