UXDE dot Net Wordpress Themes

Posts Selected From the Category "Design Studio"

Data Mining Engine (DME) Code for Design Studio Scripting

in Design Studio, Lawson / No Comments

I am always asked by developers new to Design Studio how to perform a DME call to retrieve data within Lawson S3 applications.  I came across this code years ago and it has proven invaluable for this task. You can attach directly to a form as is or use it as an Include file but it facilitates the processing of a DME API into Lawson for use with an S3 form.  Below the code I have attached a simple example where this code is used.

DME Code (Updated on April 16, 2013, now compatible with 10.0.3 and 10.1 Portal)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/************************************************************
********************* DME OBJECT CODE ***********************
***************** SIMPLIFIES PERFORMING A DME ***************
***************** UPDATED APRIL 2013 for 10.0.3 *************
*************************************************************
*************************************************************   
************************************************************/
 
/************************************************************
    Function: exampleDme()
 
    Purpose:  Simple example usign the dme code
************************************************************/
function exampleDme()
{
    //fetch the effective date used so we can send a change action
    var vCo     = portalWnd.oUserProfile.getAttribute("company");
    var vJobCode    = "110";
 
    //set object and table/prodline
    var empDMEObj   = new DMEObject("JOBCODE", strPDL);
 
    //set an index
    empDMEObj.setIndex("JBCSET1&KEY=" + vCo + "=" + vJobCode);
 
    //tell it what fields to fetch
    empDMEObj.addField("EFFECTIVE-DATE");
 
    //prompt("obj",empDMEObj.toString());
    empDMEObj.execute();
 
    //grab a field from the dme result
    var vEffectDateHR06 = empDMEObj.getField("EFFECTIVE-DATE"); 
 
    alert(vEffectDateHR06);
}
 
/************************************************************
    Function: getVarFromString
 
    Purpose:  get the variables from the search string
 
    Example:  var vCompany = getVarFromString("Company",parent.location.search);
************************************************************/
function getVarFromString(varName,str)
{
    str+='&'
    reStr="(?:\\&|\\?|^)" + varName + "=(.*?)(?:\\&|$)"
    var re=new RegExp(reStr,"gi")
    if(re.test(str))
        return RegExp.$1
    else
        return ""
}
 
/************************************************************
    Function: getDMEColumnIndex(pColumns)
 
    Purpose:  Helper Method used assist in getting DME record data as seen on pg 114 of 
          Design Studio User Guide
************************************************************/
function getDMEColumnIndex(pColumns)
{
    var vIndex = new Array();
    for (var i=0; i<pColumns.length; i++)
    {
        var vLabel = pColumns[i].getAttribute("header").toUpperCase().split("_").join("-");
        vIndex[vLabel] = i;
    }
    return vIndex;
}
 
/************************************************************
    Function: getNodeValue(pNode)
 
    Purpose:  Helper Method used assist in getting DME field data as seen on pg 114 of
          Design Studio User Guide
************************************************************/
function getNodeValue(pNode)
{
    for (var i=0; i<pNode.childNodes.length; i++)
    {
        if (pNode.childNodes[i].nodeType == 4)
        {
            return pNode.childNodes[i].nodeValue;
        }
    }
}
 
/************************************************************
    Function: DMEObject
 
    Purpose:  Constructor.  Return a new DMEObject for a file(table) and productline.
          Initialize your instance variables.
************************************************************/
function DMEObject(pFile, pPDL)
{
    this.file = pFile;
    this.pdl = pPDL;
    this.index = "";
    this.conditions = "";
    this.fields = "";
    this.select = "";
    this.optParams= "";
    this.dmeString = "";
    this.records = null;
    this.columns = new Array();
    this.length = 0;
    this.maxRecords = 9999;
    this.success = false;
}
 
/************************************************************
    Function: setIndex(pIndex)
 
    Purpose:  Instance method for DMEObject.  Takes in a predefined index and sets in in 
          the object..
************************************************************/
DMEObject.prototype.setIndex = function(pIndex)
{
    this.index = pIndex;
 
    return true;
}
 
/************************************************************
    Function: setIndex(pIndex)
 
    Purpose:  Instance method for DMEObject.  Takes in a predefined index and sets in in 
          the object..
************************************************************/
DMEObject.prototype.setOptParams = function(pOptParams)
{
    this.optParams = pOptParams;
 
    return true;
}
 
/************************************************************
    Function: setConditions(pConditions)
 
    Purpose:  Instance method for DMEObject.  Takes in a predefined Conditions and sets in in 
          the object..
************************************************************/
DMEObject.prototype.setConditions = function(pConditions)
{
    this.conditions = pConditions;
 
    return true;
}
 
/************************************************************
    Function: setSelect(pSelect)
 
    Purpose:  Instance method for DMEObject.  Takes in a predefined index and sets in in 
          the object..
************************************************************/
DMEObject.prototype.setSelect = function(pSelect)
{
    this.select= pSelect;
 
    return true;
}
 
/************************************************************
    Function: addField(pField, pFieldValue)
 
    Purpose:  Instance method for DMEObject.  Takes in a field name and adds it to the 
          fields portion of the DME string.
************************************************************/
DMEObject.prototype.addField = function(pField)
{
    this.fields += pField+";";
 
    return true;
}
 
/************************************************************
    Function: getField(pField)
 
    Purpose:  Instance method for DMEObject.  Takes in a field name as a parameter and 
          return's it's value from the DME String.  If pRelRecTable is populated, pField
          will be ignored and an array will be passed back.
************************************************************/
DMEObject.prototype.getField = function(pField, pRow, pRelRecTable)
{
    var rFieldValue;
 
    if ((pRow == undefined) ||
        (pRow == null))
    {
        pRow = 0;
    }
    if ((pRelRecTable == undefined) ||
        (pRelRecTable == null))
    {
        pRelRecTable = "";
    }
 
    //if it's not an empty string, we'll return the value from the related record tables
    if (pRelRecTable != "")
    {
        var vNewRelRecsArray = new Array();
        var vRelRecsArray = this.returnRecords[pRow].getElementsByTagName("RELRECS");
//alert(this.returnRecords[0].getElementsByTagName("RELRECS")[0].getElementsByTagName("RELREC")[1].getElementsByTagName("COL")[1].childNodes[0].nodeValue)
        //search each related table record set for one that matches pRelRecTable
        for(var i=0; i < vRelRecsArray.length; i++)
        {
            if (vRelRecsArray[i].getAttribute("name").toUpperCase().split("_").join("-") == pRelRecTable.toUpperCase())
            {
                var vRelRecArray = vRelRecsArray[i].getElementsByTagName("RELREC");
                //search specific related table record set's values
                for(var j=0; j < vRelRecArray.length; j++)
                {
                    var vNewRelRecArray = new Array();
                    var vRelRecColArray = vRelRecArray[j].getElementsByTagName("COL");
 
                    for(var k=0; k < vRelRecColArray.length; k++)
                    {
                        var vRelRecColValue = vRelRecColArray[k].childNodes[0].nodeValue;
                        vNewRelRecArray.push(vRelRecColValue);
                    }
                    vNewRelRecsArray.push(vNewRelRecArray)
                }
 
                break;
            }
        }
        rFieldValue = vNewRelRecsArray;
    }
    else
    {
        var vRecord = this.returnRecords[pRow].getElementsByTagName("COL");
 
        rFieldValue = getNodeValue(vRecord[this.columns[pField]]);
    }
 
    return (rFieldValue);
}
 
/************************************************************
    Function: BuildDMEString()
 
    Purpose:  Helper class method for DMEObject to build an DME string based on an DMEObject 
          passed in.  Could be used stand-alone.
************************************************************/
DMEObject.BuildDMEString = function(vDMEObject)
{
    var vDMEString = portalWnd.DMEPath 
             + "?PROD=" + vDMEObject.pdl
             + "&FILE=" + vDMEObject.file
             + "&INDEX=" + vDMEObject.index
             + "&COND=" + vDMEObject.conditions
             + "&FIELD=" + vDMEObject.fields
             + "&SELECT=" + vDMEObject.select
             + "&MAX=" + vDMEObject.maxRecords
             + vDMEObject.optParams
             +"&OUT=XML&DELIM="+(new Date()).getTime();
 
    //time was added to the unused field "DELIM" so it forces the DME to not used the cached data
 
    return vDMEString;
}
 
/************************************************************
    Function: execute()
 
    Purpose:  Instance method to execute this DME call.  Returns true on success, false on any 
          failure
************************************************************/
DMEObject.prototype.execute = function()
{
    this.dmeString = DMEObject.BuildDMEString(this);
 
    //execute http post
    var vDMEInfo = portalWnd.httpRequest(this.dmeString);
    //if the status exists, there was an error in the system, otherwise proceed to pull data out
    if (vDMEInfo.status)
    {
        this.success = false;
    }
    else
    {
        var xmlObj = new portalWnd.DataStorage(vDMEInfo);
        this.returnRecords = xmlObj.document.getElementsByTagName("RECORD");
        this.columns = getDMEColumnIndex(xmlObj.document.getElementsByTagName("COLUMN"));
        this.length = this.returnRecords.length;
    }
    //return true if it was successful and false if it wasnt    
    return this.success;
}
 
/************************************************************
    Function: toString()
 
    Purpose:  Instance method to aid in debugging.  Returns the current DME string for the
          the fields that have been added to the object so far.
************************************************************/
DMEObject.prototype.toString = function()
{
    this.dmeString = DMEObject.BuildDMEString(this);
    return this.dmeString;
}
/************************************************************
********************* DME OBJECT CODE ***********************
***************** SIMPLIFIES PERFORMING A DME ***************
***************** UPDATED APRIL 2013 for 10.0.3 *************
*************************************************************
*************************************************************	
************************************************************/

/************************************************************
	Function: exampleDme()

	Purpose:  Simple example usign the dme code
************************************************************/
function exampleDme()
{
	//fetch the effective date used so we can send a change action
	var vCo 	= portalWnd.oUserProfile.getAttribute("company");
	var vJobCode 	= "110";

	//set object and table/prodline
	var empDMEObj 	= new DMEObject("JOBCODE", strPDL);

	//set an index
	empDMEObj.setIndex("JBCSET1&KEY=" + vCo + "=" + vJobCode);

	//tell it what fields to fetch
	empDMEObj.addField("EFFECTIVE-DATE");

	//prompt("obj",empDMEObj.toString());
	empDMEObj.execute();

	//grab a field from the dme result
	var vEffectDateHR06 = empDMEObj.getField("EFFECTIVE-DATE");	

	alert(vEffectDateHR06);
}

/************************************************************
	Function: getVarFromString

	Purpose:  get the variables from the search string

	Example:  var vCompany = getVarFromString("Company",parent.location.search);
************************************************************/
function getVarFromString(varName,str)
{
	str+='&'
	reStr="(?:\\&|\\?|^)" + varName + "=(.*?)(?:\\&|$)"
	var re=new RegExp(reStr,"gi")
	if(re.test(str))
		return RegExp.$1
	else
		return ""
}

/************************************************************
	Function: getDMEColumnIndex(pColumns)

	Purpose:  Helper Method used assist in getting DME record data as seen on pg 114 of 
		  Design Studio User Guide
************************************************************/
function getDMEColumnIndex(pColumns)
{
	var vIndex = new Array();
	for (var i=0; i<pColumns.length; i++)
	{
		var vLabel = pColumns[i].getAttribute("header").toUpperCase().split("_").join("-");
		vIndex[vLabel] = i;
	}
	return vIndex;
}

/************************************************************
	Function: getNodeValue(pNode)

	Purpose:  Helper Method used assist in getting DME field data as seen on pg 114 of
		  Design Studio User Guide
************************************************************/
function getNodeValue(pNode)
{
	for (var i=0; i<pNode.childNodes.length; i++)
	{
		if (pNode.childNodes[i].nodeType == 4)
		{
			return pNode.childNodes[i].nodeValue;
		}
	}
}

/************************************************************
	Function: DMEObject

	Purpose:  Constructor.  Return a new DMEObject for a file(table) and productline.
		  Initialize your instance variables.
************************************************************/
function DMEObject(pFile, pPDL)
{
	this.file = pFile;
	this.pdl = pPDL;
	this.index = "";
	this.conditions = "";
	this.fields = "";
	this.select = "";
	this.optParams= "";
	this.dmeString = "";
	this.records = null;
	this.columns = new Array();
	this.length = 0;
	this.maxRecords = 9999;
	this.success = false;
}

/************************************************************
	Function: setIndex(pIndex)

	Purpose:  Instance method for DMEObject.  Takes in a predefined index and sets in in 
		  the object..
************************************************************/
DMEObject.prototype.setIndex = function(pIndex)
{
	this.index = pIndex;

	return true;
}

/************************************************************
	Function: setIndex(pIndex)

	Purpose:  Instance method for DMEObject.  Takes in a predefined index and sets in in 
		  the object..
************************************************************/
DMEObject.prototype.setOptParams = function(pOptParams)
{
	this.optParams = pOptParams;

	return true;
}

/************************************************************
	Function: setConditions(pConditions)

	Purpose:  Instance method for DMEObject.  Takes in a predefined Conditions and sets in in 
		  the object..
************************************************************/
DMEObject.prototype.setConditions = function(pConditions)
{
	this.conditions = pConditions;

	return true;
}

/************************************************************
	Function: setSelect(pSelect)

	Purpose:  Instance method for DMEObject.  Takes in a predefined index and sets in in 
		  the object..
************************************************************/
DMEObject.prototype.setSelect = function(pSelect)
{
	this.select= pSelect;

	return true;
}

/************************************************************
	Function: addField(pField, pFieldValue)

	Purpose:  Instance method for DMEObject.  Takes in a field name and adds it to the 
		  fields portion of the DME string.
************************************************************/
DMEObject.prototype.addField = function(pField)
{
	this.fields += pField+";";

	return true;
}

/************************************************************
	Function: getField(pField)

	Purpose:  Instance method for DMEObject.  Takes in a field name as a parameter and 
		  return's it's value from the DME String.  If pRelRecTable is populated, pField
		  will be ignored and an array will be passed back.
************************************************************/
DMEObject.prototype.getField = function(pField, pRow, pRelRecTable)
{
	var rFieldValue;

	if ((pRow == undefined) ||
	    (pRow == null))
	{
		pRow = 0;
	}
	if ((pRelRecTable == undefined) ||
	    (pRelRecTable == null))
	{
		pRelRecTable = "";
	}

	//if it's not an empty string, we'll return the value from the related record tables
	if (pRelRecTable != "")
	{
		var vNewRelRecsArray = new Array();
		var vRelRecsArray = this.returnRecords[pRow].getElementsByTagName("RELRECS");
//alert(this.returnRecords[0].getElementsByTagName("RELRECS")[0].getElementsByTagName("RELREC")[1].getElementsByTagName("COL")[1].childNodes[0].nodeValue)
		//search each related table record set for one that matches pRelRecTable
		for(var i=0; i < vRelRecsArray.length; i++)
		{
			if (vRelRecsArray[i].getAttribute("name").toUpperCase().split("_").join("-") == pRelRecTable.toUpperCase())
			{
				var vRelRecArray = vRelRecsArray[i].getElementsByTagName("RELREC");
				//search specific related table record set's values
				for(var j=0; j < vRelRecArray.length; j++)
				{
					var vNewRelRecArray = new Array();
					var vRelRecColArray = vRelRecArray[j].getElementsByTagName("COL");

					for(var k=0; k < vRelRecColArray.length; k++)
					{
						var vRelRecColValue = vRelRecColArray[k].childNodes[0].nodeValue;
						vNewRelRecArray.push(vRelRecColValue);
					}
					vNewRelRecsArray.push(vNewRelRecArray)
				}

				break;
			}
		}
		rFieldValue = vNewRelRecsArray;
	}
	else
	{
		var vRecord = this.returnRecords[pRow].getElementsByTagName("COL");

		rFieldValue = getNodeValue(vRecord[this.columns[pField]]);
	}

	return (rFieldValue);
}

/************************************************************
	Function: BuildDMEString()

	Purpose:  Helper class method for DMEObject to build an DME string based on an DMEObject 
		  passed in.  Could be used stand-alone.
************************************************************/
DMEObject.BuildDMEString = function(vDMEObject)
{
	var vDMEString = portalWnd.DMEPath 
			 + "?PROD=" + vDMEObject.pdl
			 + "&FILE=" + vDMEObject.file
			 + "&INDEX=" + vDMEObject.index
			 + "&COND=" + vDMEObject.conditions
			 + "&FIELD=" + vDMEObject.fields
			 + "&SELECT=" + vDMEObject.select
			 + "&MAX=" + vDMEObject.maxRecords
			 + vDMEObject.optParams
			 +"&OUT=XML&DELIM="+(new Date()).getTime();

	//time was added to the unused field "DELIM" so it forces the DME to not used the cached data

	return vDMEString;
}

/************************************************************
	Function: execute()

	Purpose:  Instance method to execute this DME call.  Returns true on success, false on any 
		  failure
************************************************************/
DMEObject.prototype.execute = function()
{
	this.dmeString = DMEObject.BuildDMEString(this);

	//execute http post
	var vDMEInfo = portalWnd.httpRequest(this.dmeString);
	//if the status exists, there was an error in the system, otherwise proceed to pull data out
	if (vDMEInfo.status)
	{
		this.success = false;
	}
	else
	{
		var xmlObj = new portalWnd.DataStorage(vDMEInfo);
		this.returnRecords = xmlObj.document.getElementsByTagName("RECORD");
		this.columns = getDMEColumnIndex(xmlObj.document.getElementsByTagName("COLUMN"));
		this.length = this.returnRecords.length;
	}
	//return true if it was successful and false if it wasnt	
	return this.success;
}

/************************************************************
	Function: toString()

	Purpose:  Instance method to aid in debugging.  Returns the current DME string for the
		  the fields that have been added to the object so far.
************************************************************/
DMEObject.prototype.toString = function()
{
	this.dmeString = DMEObject.BuildDMEString(this);
	return this.dmeString;
}

 

Add a Textarea counter on KeyUp

in Design Studio, Lawson / No Comments

In this situation, we wanted to place a counter beneath a textarea on the form where we would display a running total of characters as the user typed.  A fairly common thing to come across on the web. This entailed a new function where we hard coded character limit of 240.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function FORM_OnInit()function FORM_OnInit()
{
    lawForm.getFormElement("textarea1").onkeyup = function(){characterCount();};
}
 
function characterCount()
{
    var vCharCount = lawForm.getFormValue("textarea1").length;
 
    if(vCharCount > 240)
    {
        var vSafeValue = lawForm.getFormValue("textarea1").substring(0, 240);
        lawForm.setFormValue("textarea1",vSafeValue);
        lawForm.setFormValue("text6","You hit the max");
    }
    else
    {
        lawForm.setFormValue("text6",vCharCount);
    }
}
function FORM_OnInit()function FORM_OnInit()
{
	lawForm.getFormElement("textarea1").onkeyup = function(){characterCount();};
}

function characterCount()
{
	var vCharCount = lawForm.getFormValue("textarea1").length;

	if(vCharCount > 240)
	{
		var vSafeValue = lawForm.getFormValue("textarea1").substring(0, 240);
		lawForm.setFormValue("textarea1",vSafeValue);
		lawForm.setFormValue("text6","You hit the max");
	}
	else
	{
		lawForm.setFormValue("text6",vCharCount);
	}
}

 

Which looks like this:

Using Script to Create a Process Flow Workunit

in Design Studio, Lawson / No Comments

Design Studio can be a great front-end to a Process Flow, either to collect information from users or to be used to enhance an existing form. Using some simple script it is easy to embed code which will collect variables and create a workunit.

In this example we have a simple function called click() which was tied to a form button.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function click() {
    var vTitle = "mytitle";
    var vItem = "myitem";
    var vDesc = "desc";
    var vRequester = "req";
    var vQty = "qty";
    var vUom = "uom";   
 
    var s = strAGSPath + "?_PDL="+strPDL+"&_TKN=WFWK.1&_LFN=ALL&_RTN=DATA&_TDS=IGNORE&_OUT=XML";
    s += "&_EVT=ADD&FC=A&SERVICE=SpecialRec&WORK-TITLE=" +vTitle
    s += "&VARIABLE-NAMEr0=ITEM"
    s += "&VARIABLE-VALUEr0=" +vItem
    s += "&VARIABLE-NAMEr1=DESCRIPTION"
    s += "&VARIABLE-VALUEr1=" +vDesc
    s += "&VARIABLE-NAMEr2=REQUESTER"
    s += "&VARIABLE-VALUEr2=" +vRequester
    s += "&VARIABLE-NAMEr3=QUANTITY"
    s += "&VARIABLE-VALUEr3=" +vQty
    s += "&VARIABLE-NAMEr4=UOM"
    s += "&VARIABLE-VALUEr4=" +vUom
    s += "&_EOT=TRUE"
 
    portalWnd.httpRequest(s);
}
function click() {
	var vTitle = "mytitle";
	var vItem = "myitem";
	var vDesc = "desc";
	var vRequester = "req";
	var vQty = "qty";
	var vUom = "uom";	

	var s = strAGSPath + "?_PDL="+strPDL+"&_TKN=WFWK.1&_LFN=ALL&_RTN=DATA&_TDS=IGNORE&_OUT=XML";
	s += "&_EVT=ADD&FC=A&SERVICE=SpecialRec&WORK-TITLE=" +vTitle
	s += "&VARIABLE-NAMEr0=ITEM"
	s += "&VARIABLE-VALUEr0=" +vItem
	s += "&VARIABLE-NAMEr1=DESCRIPTION"
	s += "&VARIABLE-VALUEr1=" +vDesc
	s += "&VARIABLE-NAMEr2=REQUESTER"
	s += "&VARIABLE-VALUEr2=" +vRequester
	s += "&VARIABLE-NAMEr3=QUANTITY"
	s += "&VARIABLE-VALUEr3=" +vQty
	s += "&VARIABLE-NAMEr4=UOM"
	s += "&VARIABLE-VALUEr4=" +vUom
	s += "&_EOT=TRUE"

	portalWnd.httpRequest(s);
}