Skip to main content
Kinetic Community

Setting up the DMC to connect to a new or different Remedy form

Explains the process behind creating connection in the Data Management Console (DMC) to a new/different Remedy form than that provided out fo the box. NOTE: This article is in progress...more to come soon.

Goal

In this use case we will be connecting the DMC up to the KS_Sample_People form. This is just as an example of a different Remedy form on the system to connect to. The steps are the same for any Remedy form. Any difference that may take place based on values specific to the form have been noted wherever possible.

Steps

  1. Create the Bridge for/to the data/form
  2. Create the Add Update Service Item
    1. Create the Service item
    2. Create the Model to Support the Add/Update
    3. Create the callback to do the add/update
    4. Create the JS to call the callback and do the add/update
  3. Update the DMC Add Update Item Dataset
  4. Update the New Dataset Definition Service Item (if desired)

Create the Bridge for/to the data/form

The first step is to set up a Bridge connection to the form in question, in this case KS_Sample_People. The first step to this is to set up a Bridge Model. Call it something useful/sensible. You may end up using this bridge/model outside the DMC as well. You want to use whatever standard naming conventions you have in place.

AddBridgeModel.png

The next step is to set up the Model Attributes. These are the data you want to retrieve from the form in question. Remember that these don't have to match the field names for the items. Again, stick to whatever naming conventions you have in place.

AddModelAttributes.png

Then it is time to add the qualifications. Actually here you are giving the names of the qualifications you will use. Add whatever qualifications you seek to use for the DMC for your datasets (whatever criteria you will be using to pull your data uniquely from the form to determine your datasets), but be sure to include one dataset that in By Request ID--This is necessary for the Update Record functionality. 

AddQualification.png

Your qualifications will likely require parameters, so be sure to define those as well. When you define a parameter, be sure to add a comment. This will be displayed in the "Add Dataset" item when that parameter is being added when the bridge qualification is being leveraged by the users. It could help them enter the right thing. For example, in the KS_SRV_Helper dataset, the parameter description tells users to use double quotes around their parameters if their parameter isn't $NULL$.

addParameter.png

Now, onto the Mapping tab, to add the Model Mapping. This will, of course, be specific to your bridge and form name:

AddModelMapping.png

Then the Attribute Mappings. This is where you map the names you have given the data to the form/field names:

AddAttributeMappings.png

AttributeMappingNoMatch.png

And where you define the details of the queries you named:

AddQualification-Detail.png

ByRequestIDQual.png

Once the new bridges are defined, you need to expose any bridge you want to use to look up data for a dataset on the DMC Console item:

exposingNewBridgeOnConsole.png

Note that you don't need to expose the By Record ID bridge this way. That is used to update records and is needed on the Add/Update service item only.

For more information on Bridging, see Kinetic Bridging.

Create the Add Update Service Item

The next step is to create the Add Update Service Item and all of its necessary components.

Create the Service item

The Add Update Service item is a service item that uses the /packages/datamanagement/dmc.jsp should be named <form name> Add Update and have a Display Name for URL of:

<formname>Row

Having this Display Name for URL will allow the DMC Add Row and Update Row buttons to automatically function without any modification to the DMC javascript for the new form.

The first section of the service item is a hidden section of control fields, the most key of which are the recordId (used on Update) and the Data Model helperID (used to determine the dataset).

SectionControlFields.png

The next section is the page header:

SectionHeader.png

And then the next section is the visible section. This section contains the fields that will display for the user depending on the dataset. Note that for most forms you will set up, these fields will all be set up initially in the form as removed and will be added by the javascript that controls the add/update. This is because the user who sets up the dataset usually gets to control which fields on the form are used in that particular dataset, thus which fields are visible for them. If there are fields that are always visible for the user, you'll want to account for that not only when you create the field (not setting it to removed) but in the javascript to make sure that the javascript cannot remove that field.

SectionFields.png

Note that fields are defined by their name as per the what is set up in the bridge (not in the form in Remedy or any particular dataset). Also notice that there are a number of fields that have a matching List+fieldname question. These questions all have an event on them that set the matching non-list question when the list question has a change event. If you want to support the "Text - Selection list" option for any particular field, you need to make sure that that field has this matching "List" field in the Add Update Service Item or there will be an error on add/update.

The full example service item is here.

Create the Model to Support the Add/Update

The add or update actually happens via a Model, so you must create a Model for the form in question if you do not already have one. The one for KS_SAMPLE_People is attached below, and is as appears here:

<%!
    public static class KSSamplePeople {
        public static final String FORM_NAME = "KS_SAMPLE_People";
        public static final String FIELD_STATUS = "7";
        public static final String FIELD_EMAIL = "260000002";
        public static final String FIELD_FULL_NAME = "240000001";
        public static final String FIELD_FIRST_NAME = "240000004";
        public static final String FIELD_LAST_NAME = "240000003";
        public static final String FIELD_EMPLOY_ID = "260000007";
        public static final String FIELD_LOGIN = "240000005";
        public static final String FIELD_PHONE = "240000002";
        public static final String FIELD_COMPANY = "720000000";
        public static final String FIELD_REGION = "200000012";
        public static final String FIELD_SITE = "200000007";
        public static final String FIELD_DEPT = "200000006";
        public static final String FIELD_OFFICE = "240000111";
        public static final String FIELD_REQUEST_ID = "1";
        public static final String FIELD_INSTANCE_ID = "179";

        public static final String[] FIELD_IDS = new String[] {
            FIELD_STATUS, FIELD_EMAIL, FIELD_FULL_NAME, FIELD_FIRST_NAME, FIELD_LAST_NAME, FIELD_LAST_NAME, 
            FIELD_EMPLOY_ID, FIELD_LOGIN, FIELD_PHONE, FIELD_COMPANY, FIELD_REGION, FIELD_SITE, FIELD_DEPT, FIELD_OFFICE, 
            FIELD_REQUEST_ID, FIELD_INSTANCE_ID
        };

        public static KSSamplePeople[] find(HelperContext context, String qualification) {
            KSSamplePeople[] results = new KSSamplePeople[0];

            SimpleEntry[] entries = ArsBase.find(context, FORM_NAME, qualification, FIELD_IDS);
            if (entries != null && entries.length > 0) {
                results = new KSSamplePeople[entries.length];
                for(int i=0;i<results.length;i++) {
                    results[i] = new KSSamplePeople(entries[i]);
                }
            }

            return results;

        }

        
        public static KSSamplePeople[] find(HelperContext context, String qualification, String[] sortFields, Integer chunkSize, Integer recordOffset, Integer sortOrder) {
            KSSamplePeople[] results = new KSSamplePeople[0];
            SimpleEntry[] entries = ArsBase.find(context, FORM_NAME, qualification, FIELD_IDS, sortFields, chunkSize, recordOffset, sortOrder);
            if (entries != null && entries.length > 0) {
                results = new KSSamplePeople[entries.length];
                for(int i=0;i<results.length;i++) {
                    results[i] = new KSSamplePeople(entries[i]);
                }
            }

            return results;
        }


        public static KSSamplePeople findSingle(HelperContext context, String qualification) {
            SimpleEntry entry = ArsBase.findSingle(context, FORM_NAME, qualification, FIELD_IDS);
            KSSamplePeople result = new KSSamplePeople(entry);

            return result;

        }


        public static String createPeople(HelperContext context, String firstName, String lastName, String employNum, String login, 
            String fullName, String phone, String email, String company, String region, String site, String dept, String office, 
            String status) {
            
            //System.out.println("TEMP DEBUGGING KSSamplePeople.jspf :: " + t_dtime_1.toString());
            
            SimpleEntry entrySave = new SimpleEntry();
            entrySave.setSchemaName(FORM_NAME);
            entrySave.setEntryItems(new Hashtable());
            entrySave.setEntryFieldValue(FIELD_FIRST_NAME, firstName);
            entrySave.setEntryFieldValue(FIELD_LAST_NAME, lastName);
            entrySave.setEntryFieldValue(FIELD_EMPLOY_ID, employNum);
            entrySave.setEntryFieldValue(FIELD_LOGIN, login);         
            entrySave.setEntryFieldValue(FIELD_FULL_NAME, fullName);
            entrySave.setEntryFieldValue(FIELD_PHONE, phone);
            entrySave.setEntryFieldValue(FIELD_EMAIL, email);
            entrySave.setEntryFieldValue(FIELD_COMPANY, company);
            entrySave.setEntryFieldValue(FIELD_REGION, region);
            entrySave.setEntryFieldValue(FIELD_SITE, site);
            entrySave.setEntryFieldValue(FIELD_DEPT, dept);
            entrySave.setEntryFieldValue(FIELD_OFFICE, office);
            entrySave.setEntryFieldValue(FIELD_STATUS, status);  
    
            // Build the KSSamplePeople
            ArsHelper KSSamplePeople = null;
            try {
                KSSamplePeople = new ArsHelper(context, FORM_NAME);
            } catch (Exception e) {
                throw new RuntimeException("Unable to initialize an ArsHelper instance.", e);
            }
            String createdRecordId = null;
            try {
                createdRecordId = KSSamplePeople.doSetSimpleEntry(entrySave, true);
            } catch (Exception e) {
                throw new RuntimeException("There was a problem saving the "+FORM_NAME+" record.", e);
            }
            return createdRecordId;
       }


        public static String updatePeople(HelperContext context, String recordID, String firstName, String lastName, String employNum, String login, 
            String fullName, String phone, String email, String company, String region, String site, String dept, String office,
            String status) {

            SimpleEntry entrySave = new SimpleEntry();
            entrySave.setSchemaName(FORM_NAME);
            entrySave.setEntryItems(new Hashtable());
            entrySave.setEntryId(recordID);
            entrySave.setEntryFieldValue(FIELD_FIRST_NAME, firstName);
            entrySave.setEntryFieldValue(FIELD_LAST_NAME, lastName);
            entrySave.setEntryFieldValue(FIELD_EMPLOY_ID, employNum);
            entrySave.setEntryFieldValue(FIELD_LOGIN, login);         
            entrySave.setEntryFieldValue(FIELD_FULL_NAME, fullName);
            entrySave.setEntryFieldValue(FIELD_PHONE, phone);
            entrySave.setEntryFieldValue(FIELD_EMAIL, email);
            entrySave.setEntryFieldValue(FIELD_COMPANY, company);
            entrySave.setEntryFieldValue(FIELD_REGION, region);
            entrySave.setEntryFieldValue(FIELD_SITE, site);
            entrySave.setEntryFieldValue(FIELD_DEPT, dept);
            entrySave.setEntryFieldValue(FIELD_OFFICE, office);
            entrySave.setEntryFieldValue(FIELD_STATUS, status); 

    
            // Build the KSSamplePeople
            ArsHelper KSSamplePeople = null;
            try {
                KSSamplePeople = new ArsHelper(context, FORM_NAME);
            } catch (Exception e) {
                throw new RuntimeException("Unable to initialize an ArsHelper instance.", e);
            }

            String updatedRecordId = null;

            try {
                updatedRecordId = KSSamplePeople.doSetSimpleEntry(entrySave, true);
            } catch (Exception e) {
                throw new RuntimeException("There was a problem saving the "+FORM_NAME+" record.", e);
            }

            return updatedRecordId;
       }


        public static String updateStatus(HelperContext context, String recordID, String status) {
 
            // Update the KSSamplePeople record with new Status
            SimpleEntry entrySave = new SimpleEntry();
            entrySave.setEntryId(recordID);
            entrySave.setSchemaName(FORM_NAME);
            entrySave.setEntryItems(new Hashtable());
            entrySave.setEntryFieldValue(FIELD_STATUS, status);                     
            
            // Build the KSSamplePeople
            ArsHelper KSSamplePeople = null;
            try {
                KSSamplePeople = new ArsHelper(context, FORM_NAME);
            } catch (Exception e) {
                throw new RuntimeException("Unable to initialize an ArsHelper instance.", e);
            }

            String updatedRecordId = null;

            try {
                updatedRecordId = KSSamplePeople.doSetSimpleEntry(entrySave, true);
            } catch (Exception e) {
                throw new RuntimeException("There was a problem saving the "+FORM_NAME+" record.", e);
            }

            return updatedRecordId;
        }
        

        private SimpleEntry entry = null;

        public KSSamplePeople(SimpleEntry entry) {
            this.entry = entry;
        }

        public String getRequestID() {return entry.getEntryFieldValue(FIELD_REQUEST_ID);}
    }
%>

Note that the model must have an add and an update method and all of the fields you wish to add or update must be defined. When you do an update the record ID must be passed in so that the system knows what record it is updating. 

Create the callback to do the add/update

Then you need to set up an add and an update callback to leverage this model to make the updates. These are relatively small items that just take in all possible update and add parameters and call the add/create or update functions for the model:

<jsp:useBean id="UserContext" scope="session" class="com.kd.kineticSurvey.beans.UserContext"/>
<%@page import="com.kd.kineticSurvey.impl.RemedyHandler"%>
<%@include file="../../../../core/framework/models/ArsBase.jspf" %>
<%
    /* Defined here because this jsp will be called seperately. That is, not part of the Catalog jsp. */
    HelperContext context = UserContext.getArContext();
    HelperContext defaultContext = UserContext.getArContext();
try {
    defaultContext = RemedyHandler.getDefaultHelperContext();
} catch (Exception e){
    // Handle exception
    throw new RuntimeException(e);
}

%>

<%@include file="../../framework/models/KSSamplePeople.jspf"%>
<%
    String status = request.getParameter("status");
    String firstName = request.getParameter("firstName");
    String lastName = request.getParameter("lastName");
    String fullName = request.getParameter("fullName");
    String employeeNum = request.getParameter("employeeNum");
    String login = request.getParameter("login");
    String phone = request.getParameter("phone");
    String office = request.getParameter("office");
    String email = request.getParameter("email");
    String company = request.getParameter("company");
    String region = request.getParameter("region");
    String site = request.getParameter("site");
    String dept = request.getParameter("dept");

    
    try {
    //Update the record. Error is thrown within this code if the create doesn't happen
    String newRecordId = KSSamplePeople.createPeople(context, firstName, lastName, employeeNum, 
            login, fullName, phone, email, company, region, site, dept, office, status);
    } catch (Exception e){
    // Handle exception
    throw new RuntimeException(e);
}
 %>

Note that depending on your form you may need to use the default context.

<jsp:useBean id="UserContext" scope="session" class="com.kd.kineticSurvey.beans.UserContext"/>
<%@page import="com.kd.kineticSurvey.impl.RemedyHandler"%>
<%@include file="../../../../core/framework/models/ArsBase.jspf" %>
<%
    /* Defined here because this jsp will be called seperately. That is, not part of the Catalog jsp. */
    HelperContext context = UserContext.getArContext();
    HelperContext defaultContext = UserContext.getArContext();
try {
    defaultContext = RemedyHandler.getDefaultHelperContext();
} catch (Exception e){
    // Handle exception
    throw new RuntimeException(e);
}

%>

<%@include file="../../framework/models/KSSamplePeople.jspf"%>
<%
     String recordId = request.getParameter("recordId");
    String status = request.getParameter("status");
    String firstName = request.getParameter("firstName");
    String lastName = request.getParameter("lastName");
    String fullName = request.getParameter("fullName");
    String employeeNum = request.getParameter("employeeNum");
    String login = request.getParameter("login");
    String phone = request.getParameter("phone");
    String office = request.getParameter("office");
    String email = request.getParameter("email");
    String company = request.getParameter("company");
    String region = request.getParameter("region");
    String site = request.getParameter("site");
    String dept = request.getParameter("dept");

    
    try {
    //Update the record. Error is thrown within this code if the create doesn't happen
    String newRecordId = KSSamplePeople.updatePeople(context, recordId, firstName, lastName, employeeNum, 
            login, fullName, phone, email, company, region, site, dept, office, status);
    } catch (Exception e){
    // Handle exception
    throw new RuntimeException(e);
}
try {
KSSamplePeople.updateStatus(defaultContext, recordId, status);
} catch (Exception e){
    // Handle exception
    throw new RuntimeException(e);
}
 %>

Create the JS to call the callback and do the add/update

The final, and really key, component is the javascript for the Add Update Service Item. This javascript controls display, calls the callbacks, and really does all the work behind the add or update.

function getParameter(param) {
  param = param.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+param+"=([^&]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if ( results == null ) 
    return "";
  else
    return results[1];
}

var dataType;

function loadAddUpdate() {
    var type = getParameter("type");
    var dataModelId = getParameter("dataModel");
    if (dataModelId) {
        KD.utils.Action.setQuestionValue("Data Model helperID", dataModelId);
        //get data model details
        var connector = new KD.bridges.BridgeConnector({templateId: clientManager.templateId});

        //retrieve the data definition and data type from the data definition
        connector.retrieve('Data Management Console - Data Definitions', 'By Record Id', {
          attributes: ["Character Field 13","Character Field 1"],
          parameters: {'Record Id':dataModelId},
          success: function(record) {
                //get the details about the dataset so we can process the page correctly
                KD.utils.Action.setQuestionValue("Data Model", record.attributes["Character Field 13"]);
                KD.utils.Action.setQuestionValue("Data Type", record.attributes["Character Field 1"]);
                dataType = record.attributes["Character Field 1"];
                $('.datatypetext').html(record.attributes["Character Field 1"]);
                
                
                //process the add or update display
                if (type == "add") {
                    loadAdd();
                } else if (type == "update") {
                    var recordId = getParameter("helperId");
                    loadUpdate(recordId);
                } else {
                    //redirect to the console if an inadiquate url was provided
                    alert("Entry type not provided (add/update). You will be redirected");
                    window.open(KD.utils.ClientManager.webAppContextPath + '/DisplayPage?name=datamanagement', '_self');
                }
        
          }
        });
    
    } else {
        //redirect to the console if an inadequate url was provided
        alert("A Data Model was not provided. You will be redirected");
        window.open(KD.utils.ClientManager.webAppContextPath + '/DisplayPage?name=datamanagement', '_self');
    
    }

}

function loadAdd() {
    //get Data Model
    var dataModel = KD.utils.Action.getQuestionValue("Data Model");
    var dataModelJSON = JSON.parse(dataModel);

    //handle the fields
    var fieldData = dataModelJSON.formConfig.fielddata;
    for (var key in fieldData)
    {
       if (fieldData.hasOwnProperty(key))
       {
          //insert the question & helptext elements
          var fieldName = fieldData[key].fieldName;
          KD.utils.Action.insertElement(fieldName);
          KD.utils.Action.insertElement(fieldName+" Text");
          //set the label of the field
          var label = fieldData[key].label;
          var questionLabel = $('[label="'+fieldName+'"]').find('.questionLabel').html(label);
          
          //Set field required if specified
          if (fieldData[key].required.toUpperCase() == "YES") {
            if (fieldData[key].type == "Text - Selection list"){
                KD.utils.Action.makeQuestionRequired("List"+fieldName);
            } else {
                KD.utils.Action.makeQuestionRequired(fieldName);
            }
          }
          //Set read only
          if (fieldData[key].readonly.toUpperCase() == "YES") {
            if (fieldData[key].type == "Text - Selection list"){
                KD.utils.Action.setReadOnly("List"+fieldName);
            } else {
                KD.utils.Action.setReadOnly(fieldName);
            }
          }
          //If field type = list change text field to list and populate menu
          //if (fieldData[key].type == "list") {
          if (fieldData[key].type == "Text - Selection list") {
            //Hide the character Field and show the cooresponding list field
            KD.utils.Action.removeElement(fieldName);
            KD.utils.Action.insertElement("List"+fieldName);
            //Update the label on the list field to be correct to the data type
            var questionLabel = $('[label="List'+fieldName+'"]').find('.questionLabel').html(label);
            
            //populate the menu
            //get menu options
            var menuOptions = fieldData[key].menuOptions.split("::");
            //clear out menu
            var answerLayer = KD.utils.Util.getAnswerLayer("List"+fieldName);
            answerLayer.firstChild.length = 0;
            //Populate first menu item as blank
            answerLayer.firstChild.options[0] = new Option("","");
            //populate remaining menu items
            for (i=0; i<menuOptions.length; i++) {
                answerLayer.firstChild.options[i+1] = new Option(menuOptions[i],menuOptions[i]);
            }

          }
          //Set all default values because this is an add
           if (fieldData[key].type == "Text - Selection list"){
             KD.utils.Action.setQuestionValue("List"+fieldName, fieldData[key].defaultValue);
           } else {
             KD.utils.Action.setQuestionValue(fieldName, fieldData[key].defaultValue);
           }
          //set help text
          var helpText = fieldData[key].helpText;
          var helpId = "#"+fieldName.replace(/\s/g, "")+"Help";
          $(helpId).html(helpText);
       }
    }
        
    //show the add button. Submission requires use of a model (because synchronous trees aren't
    //available) so this should be done before the page has submitted. The function called when 
    //clicking add will submit the page, which will allow for tracking/audit trail and redirect
    //the user to the console
    KD.utils.Action.insertElement("Add Button");
}

function loadUpdate(recordId) {
//get Data Model
    var dataModel = KD.utils.Action.getQuestionValue("Data Model");
    var dataModelJSON = JSON.parse(dataModel);
    
    //Set the index fields
    //KD.utils.Action.setQuestionValue("Index Field 1", dataModelJSON.bridgedata.paramval1);
    //KD.utils.Action.setQuestionValue("Index Field 2", dataModelJSON.bridgedata.paramval2);
    //KD.utils.Action.setQuestionValue("Index Field 3", dataModelJSON.bridgedata.paramval3);

    //handle the fields
    var fieldData = dataModelJSON.formConfig.fielddata;
    for (var key in fieldData)
    {
       if (fieldData.hasOwnProperty(key))
       {
          //insert the question & helptext elements
          var fieldName = fieldData[key].fieldName;
          KD.utils.Action.insertElement(fieldName);
          KD.utils.Action.insertElement(fieldName+" Text");
          //set the label of the field
          var label = fieldData[key].label;
          var questionLabel = $('[label="'+fieldName+'"]').find('.questionLabel').html(label);
          
          //Set field required if specified
          if (fieldData[key].required.toUpperCase() == "YES") {
            if (fieldData[key].type == "Text - Selection list"){
                KD.utils.Action.makeQuestionRequired("List"+fieldName);
            } else {
                KD.utils.Action.makeQuestionRequired(fieldName);
            }
          }
          //Set read only
          if (fieldData[key].readonly.toUpperCase() == "YES") {
            if (fieldData[key].type == "Text - Selection list"){
                KD.utils.Action.setReadOnly("List"+fieldName);
            } else {
                KD.utils.Action.setReadOnly(fieldName);
            }
          }
          //If field type = list change text field to list and populate menu
          //if (fieldData[key].type == "list") {
          if (fieldData[key].type == "Text - Selection list") {
            //Hide the character Field and show the cooresponding list field
            KD.utils.Action.removeElement(fieldName);
            KD.utils.Action.insertElement("List"+fieldName);
            //Update the label on the list field to be correct to the data type
            var questionLabel = $('[label="List'+fieldName+'"]').find('.questionLabel').html(label);
            
            //populate the menu
            //get menu options
            var menuOptions = fieldData[key].menuOptions.split("::");
            //clear out menu
            var answerLayer = KD.utils.Util.getAnswerLayer("List"+fieldName);
            answerLayer.firstChild.length = 0;
            //Populate first menu item as blank
            answerLayer.firstChild.options[0] = new Option("","");
            //populate remaining menu items
            for (i=0; i<menuOptions.length; i++) {
                answerLayer.firstChild.options[i+1] = new Option(menuOptions[i],menuOptions[i]);
            }

          }
          //Set all default values because this is an add
           if (fieldData[key].type == "Text - Selection list"){
             KD.utils.Action.setQuestionValue("List"+fieldName, fieldData[key].defaultValue);
           } else {
             KD.utils.Action.setQuestionValue(fieldName, fieldData[key].defaultValue);
           }
          //set help text
          var helpText = fieldData[key].helpText;
          var helpId = "#"+fieldName.replace(/\s/g, "")+"Help";
          $(helpId).html(helpText);
       }
    }
    
     //Get values from existing record
    if (recordId) {
        KD.utils.Action.setQuestionValue("recordId", recordId);
        //get data model details
        var connector2 = new KD.bridges.BridgeConnector({templateId: clientManager.templateId});

        connector2.retrieve('Sample People', 'By Record Id', {
          attributes: ["Employee Number","First Name","Last Name","Full Name",
          "Login","Office","Phone","Region",
          "Company","Site","Dept","Email","Status"],
          parameters: {'Record Id':recordId},
          success: function(record) {
                //place the existing values in the relevant fields
                KD.utils.Action.setQuestionValue("First Name", record.attributes["First Name"]);
                KD.utils.Action.setQuestionValue("Last Name", record.attributes["Last Name"]);
                KD.utils.Action.setQuestionValue("Full Name", record.attributes["Full Name"]);
                KD.utils.Action.setQuestionValue("Employee Number", record.attributes["Employee Number"]);
                KD.utils.Action.setQuestionValue("Login", record.attributes["Login"]);
                KD.utils.Action.setQuestionValue("Office", record.attributes["Office"]);
                KD.utils.Action.setQuestionValue("Phone", record.attributes["Phone"]);
                KD.utils.Action.setQuestionValue("Email", record.attributes["Email"]);
                KD.utils.Action.setQuestionValue("Company", record.attributes["Company"]);
                KD.utils.Action.setQuestionValue("ListCompany", record.attributes["Company"]);
                KD.utils.Action.setQuestionValue("Department", record.attributes["Dept"]);
                KD.utils.Action.setQuestionValue("ListDepartment", record.attributes["Dept"]);
                KD.utils.Action.setQuestionValue("Region", record.attributes["Region"]);
                KD.utils.Action.setQuestionValue("ListRegion", record.attributes["Region"]);
                KD.utils.Action.setQuestionValue("Site", record.attributes["Site"]);
                KD.utils.Action.setQuestionValue("ListSite", record.attributes["Site"]);
                KD.utils.Action.setQuestionValue("Status", record.attributes["Status"]);
                
        
          }
        });
    
    }
    
    
    //show the update button. Submission requires use of a model (because synchronous trees aren't
    //available) so this should be done before the page has submitted. The function called when 
    //clicking update will submit the page, which will allow for tracking/audit trail and redirect
    //the user to the console
    KD.utils.Action.insertElement("Update Button");
}



function showConsole(dataType) {
    //redirect to the console referencing the provided data type
    window.open(KD.utils.ClientManager.webAppContextPath + '/DisplayPage?name=datamanagement&dataType='+encodeURIComponent(dataType), '_self');
}

function updateRecord(){

    //Display wait pop-up
    setStatusWAIT =
        new YAHOO.widget.Panel("wait", {
            width: "340px",
            fixedcenter: true,
            close: false,
            draggable: true,
            zindex: 4,
            modal: true,
            visible: false
        });

    setStatusWAIT.setHeader("Updating Record");
    setStatusWAIT.setBody("<img src='http://l.yimg.com/a/i/us/per/gr/gp/rel_interstitial_loading.gif' />");
    setStatusWAIT.render(document.body);

    setStatusWAIT.show();

    //actions done on success of the callback
    success = function (o) {
        setStatusWAIT.hide();
        //submit page
        Dom.getElementsByClassName('templateButton', 'input', KD.utils.Util.getElementObject("Submit"))[0].click();
    };

    //actions done if the callback fails
    failure = function (o) {
        alert("An error has ocurred attempting to save the record");
        setStatusWAIT.hide();
    };

     //get values necessary to pass to the callback here
    var recordId = KD.utils.Action.getQuestionValue("recordId");
    var firstName = KD.utils.Action.getQuestionValue("First Name");
    var lastName = KD.utils.Action.getQuestionValue("Last Name");
    var fullName = KD.utils.Action.getQuestionValue("Full Name");
    var employeeNum = KD.utils.Action.getQuestionValue("Employee Number");
    var login = KD.utils.Action.getQuestionValue("Login");
    var phone = KD.utils.Action.getQuestionValue("Phone");
    var email = KD.utils.Action.getQuestionValue("Email");
    var company = KD.utils.Action.getQuestionValue("Company");
    var region = KD.utils.Action.getQuestionValue("Region");
    var site = KD.utils.Action.getQuestionValue("Site");
    var dept = KD.utils.Action.getQuestionValue("Department");
    var office = KD.utils.Action.getQuestionValue("Office");
    var status = KD.utils.Action.getQuestionValue("Status");
    
    //create connection
    connection = new KD.utils.Callback(success, failure, []);

    // Setup a failure message that is needed by _makeSyncRequest
    connection.failure = failure;
    //get date to help prevent caching
    var now = new Date();
    //Create URL
    var updateRequestUrl = '../datamanagement/interface/callbacks/updateSamplePeople.jsp?recordId=' + recordId
    + '&firstName=' + encodeURIComponent(firstName)  + '&lastName=' + encodeURIComponent(lastName) + '&fullName=' + encodeURIComponent(fullName) 
    + '&employeeNum=' + encodeURIComponent(employeeNum)  + '&login=' + encodeURIComponent(login) + '&phone=' + encodeURIComponent(phone) 
    + '&email=' + encodeURIComponent(email) + '&company=' + encodeURIComponent(company)  
    + '&region=' + encodeURIComponent(region) + '&site=' + encodeURIComponent(site) + '&dept=' + encodeURIComponent(dept) 
    +    '&office=' + encodeURIComponent(office); 
    updateRequestUrl = updateRequestUrl + '&status=' + status + '&noCache=' + now.getTime();
    //make sync request
    KD.utils.Action._makeSyncRequest(BUNDLE.packagePath + updateRequestUrl, connection);

}


function addRecord(){
    //Display wait pop-up
    setStatusWAIT =
        new YAHOO.widget.Panel("wait", {
            width: "340px",
            fixedcenter: true,
            close: false,
            draggable: true,
            zindex: 4,
            modal: true,
            visible: false
        });

    setStatusWAIT.setHeader("Saving new Record");
    setStatusWAIT.setBody("<img src='http://l.yimg.com/a/i/us/per/gr/gp/rel_interstitial_loading.gif' />");
    setStatusWAIT.render(document.body);

    setStatusWAIT.show();

    //actions done on success of the callback
    success = function (o) {
        setStatusWAIT.hide();
        //submit page
        Dom.getElementsByClassName('templateButton', 'input', KD.utils.Util.getElementObject("Submit"))[0].click();
    };

    //actions done if the callback fails
    failure = function (o) {
        alert("An error has ocurred attempting to save the record");
        setStatusWAIT.hide();
    };

    //get values necessary to pass here
    var recordId = KD.utils.Action.getQuestionValue("recordId");
    var firstName = KD.utils.Action.getQuestionValue("First Name");
    var lastName = KD.utils.Action.getQuestionValue("Last Name");
    var fullName = KD.utils.Action.getQuestionValue("Full Name");
    var employeeNum = KD.utils.Action.getQuestionValue("Employee Number");
    var login = KD.utils.Action.getQuestionValue("Login");
    var phone = KD.utils.Action.getQuestionValue("Phone");
    var email = KD.utils.Action.getQuestionValue("Email");
    var company = KD.utils.Action.getQuestionValue("Company");
    var region = KD.utils.Action.getQuestionValue("Region");
    var site = KD.utils.Action.getQuestionValue("Site");
    var dept = KD.utils.Action.getQuestionValue("Department");
    var office = KD.utils.Action.getQuestionValue("Office");
    var status = KD.utils.Action.getQuestionValue("Status");
    
    //create connection
    connection = new KD.utils.Callback(success, failure, []);

    // Setup a failure message that is needed by _makeSyncRequest
    connection.failure = failure;
    //get date to help prevent caching
    var now = new Date();
    //Create URL
    var createRequestUrl = '../datamanagement/interface/callbacks/createSamplePeople.jsp?' 
    + '&firstName=' + encodeURIComponent(firstName)  + '&lastName=' + encodeURIComponent(lastName) + '&fullName=' + encodeURIComponent(fullName) 
    + '&employeeNum=' + encodeURIComponent(employeeNum)  + '&login=' + encodeURIComponent(login) + '&phone=' + encodeURIComponent(phone) 
    + '&email=' + encodeURIComponent(email) + '&company=' + encodeURIComponent(company)  
    + '&region=' + encodeURIComponent(region) + '&site=' + encodeURIComponent(site) + '&dept=' + encodeURIComponent(dept) 
    + '&office=' + encodeURIComponent(office); 
    createRequestUrl = createRequestUrl + '&status=' + status + '&noCache=' + now.getTime();
    //make sync request
    KD.utils.Action._makeSyncRequest(BUNDLE.packagePath + createRequestUrl, connection);

}

Though they are not used in this particular example, the following functions are included in the add update javascript because they are important for any add/update that does process time, date/time, or dates:

function processTimeForUrl(time) {
    //Remedy stores data in seconds since 12:00:00 AM/00:00:00
    //Take a sting like 5:00:00 PM and turn it into seconds since 12:00:00 AM
    //Start at 0
    var time_s = 0;
    //If the string specifies PM, add 12 hours worth of seconds
    if (time.indexOf("PM") != -1) {
        time_s = 43200;
    }
    //Take the AM/PM value off the end of the string
    var timestrs = time.split(" ");
    //Split the string to gets hours, minutes and seconds
    var timeParts = timestrs[0].split(":");
    //change the hours to 0 if they are 12--necessary for calculation
    if (timeParts[0] == "12") timeParts[0] = "0";
    //add the hours, minutes and seconds to the existing value to get the final value.
    time_s = time_s + (parseInt(timeParts[0])*3600) + (parseInt(timeParts[1])*60) + parseInt(timeParts[2]);
    
    //return the calculated number of seconds
    return time_s; 
}

function processDateTimeForUrl(datetime) {
    //Remedy wants date time data as mm/dd/yyyy HH:mm:ss
    //but it comes from a date time question as YYYY-MM-ddTHH:mm:ssZ
    if (datetime) {
    //Split the date from the time
    var dateTimeParts = datetime.split("T");
    //Take the Z off the time
    var timePart = dateTimeParts[1].replace("Z","");
    //Split the date apart
    var dateParts = dateTimeParts[0].split("-");
    
    //create the new string
    var newDateTime = dateParts[1] +"/"+ dateParts[2] +"/"+ dateParts[0] + " " + timePart;
    //return the calculated number of seconds
    return newDateTime; 
    } else { return datetime; }
}

function processTimeForDisplay(time) { 
    //Remedy stores data in seconds since 12:00:00 AM/00:00:00, but the API returns a military time
    //change time from military time (ex. 17:00:00) to "standard remedy format" for input (ex. 5:00:00 PM)
    var storedTime = time;
    //Split the military time into hours minuts and seconds
    var timeParts = storedTime.split(":");
    //Turn the hours into an integer so it can be manipuated
    var hours = parseInt(timeParts[0]);
    //Figure out whether the time is AM or PM
    var dayPart = " AM";
    if (hours >= 12) { hours = hours - 12; dayPart = " PM";}
    //the military hour for midnight 0, change this to 12
    if (hours == 0) { hours = 12; }
    //put the time string together
    var displayTime = hours.toString() +":"+ timeParts[1] +":"+ timeParts[2] + dayPart;
    
    //return time string for display
    return displayTime;
}

They would be used like this:

encodeURIComponent(processTimeForDisplay(myTime))

Update the DMC Add Update Item Dataset

The DMC manages itself, so the Add Update Service Item is added by adding a row to this dataset:

WhereToAddItem.png

And the new row (in this case) would look like this:

NewAddUpdateItem.png

If you were adding a different form, the form name listed, of course, would reflect your form name.

Update the New Dataset Definition Service Item

If desired, you can edit the New Dataset Definition Service Item so that it will pull the "correct" field automatically for the Record ID and Status field information for a certain form. This is probably only desired if you will be using this form often and/or the users of this form will have no idea how to fill out this information correctly. This is an optional step since it is possible to fill this information in--this is just the option of setting it up to default.