Creating Embedded List like function on a Catalog Item

markg_TIN
Kilo Explorer

Hi,

We are trying to create a catalog item with a function which looks similar to the embedded list. http://wiki.service-now.com/index.php?title=Embedded_Lists

The idea is to provide the end user with a set of variables and the ability to create multiple rows using that same variable set. The itil would then be able to export the list to excel for uploading to another system.

The variables do not provide an obvious way to do this, so we're thinking we may need to use something other than a catalog item or create a client script to accomplish this.

Any experts out there have thoughts on how to do this?

Thanks

4 REPLIES 4

Jay_Ford
Kilo Guru

I'm no expert, but I have a similar requirement that I've been working on. I will share what I have but it is not even close to finished.

I created a UI Page and then show that UI page on the catalog item form. I'm then going to use an onSubmit client script to grab the data entered and do something with it.

For the UI page:
1. Create a new UI page with any name you wish.
2. The xml for mine is....




<j:jelly trim='false' xmlns:j='jelly:core' xmlns:g='glide' xmlns:j2='null' xmlns:g2='null'>
<div id='add_shop_users' class='list_div'>
<a id='clickAdd' title='Add new row' onclick='addRow("user_add_dt")'><img src='images/add_filter.png' /></a>
<a id='clickDelete' title='Delete selected rows' onclick='deleteRow("user_add_dt")'><img src='images/closex_hover.gif' /></a>
<TABLE id='user_add_dt' class='wide' cellspacing='0' border='0' style='margin-bottom: 8px;'>
<thead>
<TR class='list_header'>
<TH align='left'></TH>
<TH align='left' col='fn'>First Name</TH>
<TH align='left' col='ln'>Last Name</TH>
<TH align='left' col='cl'>Client</TH>
<TH align='left' col='em'>Email</TH>
<TH align='left' col='ci'>City</TH>
<TH align='left' col='st'>State</TH>
<TH align='left' col='ph'>Phone</TH>
</TR>
</thead>
<tbody id='tablebody'>
<g2:evaluate var='jvar_line_num' expression='$[jvar_line_num + 1]' />
<j2:set var='jvar_line_color' value='odd' />
<j2:if test='$[jvar_line_num % 2 == 0]'>
<j2:set var='jvar_line_color' value='even' />
</j2:if>

<TR class='$[jvar_line_color]'>
<TD><INPUT type='checkbox' NAME='chk'/></TD>
<TD> <INPUT id='fn_user' type='text' /> </TD>
<TD> <INPUT id='ln_user' type='text' /> </TD>
<g:evaluate>
var companies = new GlideRecord('core_company');
companies.addQuery('customer', true);
companies.query();
</g:evaluate>
<TD><select id='comp_user'>
<j:while test='${companies.next()}'>
<option value='${companies.sys_id}'>${companies.name}</option>
</j:while>
</select></TD>
<TD> <INPUT id='ln_email' type='text' /> </TD>
<TD> <INPUT id='ln_city' type='text' /> </TD>
<TD> <INPUT id='ln_state' type='text' /> </TD>
<TD> <INPUT id='ln_phone' type='text' onkeydown='if (event.keyCode == 13) document.getElementById("clickAdd").click()'/> </TD>
</TR>
</tbody>
</TABLE>
</div>
</j:jelly>

3. The client script (this goes in the client script of the UI page) to add of delete rows...


function addRow(r){
//this function is used by the + button to add more rows to your table
var root = document.getElementById(r);
var allRows = root.getElementsByTagName('tr');
var cRow = allRows[1].cloneNode(true);
var j = 0;
for (j = 0; j < cRow.cells.length; j++) {
if(j>0 &amp;&amp; j!=3){
cRow.cells[j].firstElementChild.value = '';
}
}
root.appendChild(cRow);

}

function deleteRow(r) {
//this function is used by the x button to delete selected rows from your table
try {
var table = document.getElementById(r);
var rowCount = table.rows.length;

for(var i=0; i<rowCount; i++) {
var row = table.rows<i>;
var chkbox = row.cells[0].childNodes[0];
if(null != chkbox &amp;&amp; true == chkbox.checked) {
table.deleteRow(i);
rowCount--;
i--;
}
}
}
catch(e) {
alert(e);
}
}


Once you have the UI page created you can add it to your catalog item form at the desired location. I then use the below onSubmit catalog client script to capture the results and complete portions of my request. I haven't played with getting this into excel.

onSubmit script:


function tableToObj(table){
var trs = table.rows;
var trl = trs.length;
var i = 0;
var j = 0;
var keys = [];
var obj;
var ret = [];
for (; i < trl; i++) {
if (i == 0) {
for (; j < trs<i>.children.length; j++) {
keys.push(trs<i>.children[j].getAttribute('col'));
}
} else {
obj = {};
for (j = 0; j < trs<i>.cells.length; j++) {
if(j>0){
obj[keys[j]] = trs<i>.cells[j].firstElementChild.value;
}
}
ret.push(obj);
}
}
return ret;
}


You could also accomplish data entry through creating a custom table to enter your information into and use the export excel from a list view of the table as described here. For my purpose I needed it in a catalog item.

I attached a screenshot to show what it looks like.


hartr
Giga Contributor

I'd be interested to know if you developed this idea any further ? for example filtering the choicelist based on an entry in a previous cell in the same row ? or any other novel variable types that anyone else has developed .. thanks


markg_TIN
Kilo Explorer

That looks really cool. We'll definitely take a look at this. Thanks Jay.


Dan117
Kilo Expert

I know it's been a while, but I would also be very interested to know if you had worked on this more. I am looking at a similar requirement and what you have there so far looks great.