I have to create a custom report on a ServiceNow UI Page using Javascript and HTML/Jelly. Everything is working except for this line:
<td>${jelly.jvar_bucket.timebuckets[idx].totalSystem;} </td>
If I replace idx with a number, say 20 or 25, then the report shows as expected. With idx it is all blanks.
Here is the full script.
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<g:ui_form>
<g:evaluate var="jvar_surveys" object="true" jelly="true">
var bucket = [];
<!-- // Helper function to determine AM or PM from hour -->
function timeflip(hour)
{
if(hour > 12)
{
return "PM";
}
if(hour == 12)
{
return "PM";
}
if(hour < 12)
{
return "AM";
}
} <!-- end function timeflip -->
var buckets = [];
var ind = 0;
var hour = 0;
while(ind < 48)
{
var itm = {};
var h = hour;
var daynight = "AM";
if(hour > 12)
{
h = hour-12;
daynight = "PM";
}
if(hour == 12)
{
h = hour;
daynight = "PM";
}
var notWhole = (h - Math.floor(h)) !== 0;
if(notWhole)
{
h = Math.floor(h);
if(h == 0 && daynight=='PM')
{h=12};
itm.interval = (h) +":30 "+timeflip(hour)+" - "+(h+1)+":00 "+timeflip(hour+1) ;
if(h == 12 && daynight=='PM')
itm.interval = (h) +":30 "+timeflip(hour)+" - "+(h-11)+":00 "+timeflip(hour) ;
}
else
{
h = Math.floor(h);
itm.interval = h +":00 "+timeflip(hour)+" - "+h+":30 "+timeflip(hour);
}
itm.totalInterviewer = itm.totalSystem = itm.totalRow = 0;
hour += 0.5;
ind++;
buckets.push(itm);
}
<!-- TOP HALF SCRIPT -->
var ga = new GlideRecord('x_igngr_fema_cati_study_table');
ga.query();
while(ga.next())
{
var obj = {};
var stdy = ga.study_type.getDisplayValue();
obj.timebuckets = buckets;
obj.study_type = stdy;
obj.totComp = ga.surveys_completed.getDisplayValue();
obj.totQuota = ga.quota_study.getDisplayValue();
obj.intNames = ga.study_interviewer.getDisplayValue();
if(obj.intNames.trim() === ""){
obj.intCount = 0;
} else {
var splitNames = obj.intNames.split(',');
obj.intCount = splitNames.length;
}
var totAtt = 0
var attempts = new GlideRecord('x_igngr_fema_cati_piror_attempts');
attempts.addEncodedQuery('survey_record.collection_cycle.status=open');
attempts.query();
while(attempts.next()) {
totAtt += 1;
}
obj.totAtt = totAtt;
<!-- Time buckets -->
<!-- var timeBuckets = buckets; -->
var interviewerGrandTotal = 0;
var systemGrandTotal = 0;
var surveyRecord = new GlideRecord('x_igngr_fema_cati_survey_record');
surveyRecord.addEncodedQuery('study_type.study_type='+stdy);
surveyRecord.addQuery('in_queue=true^callback_date_timeISNOTEMPTY');
surveyRecord.addQuery('schedule_status=by_interviewer^ORschedule_status=unmet^ORschedule_status=no_answer');
<!-- surveyRecord.addQuery('schedule_status=no_answer'); -->
surveyRecord.query();
while(surveyRecord.next())
{
var t = surveyRecord.callback_date_time;
var startTime = new GlideDateTime(t);
var testtime = startTime.getDisplayValueInternal();
var finalTime = new GlideDateTime(testtime);
var mSecs = finalTime.getTime().getNumericValue();
var min = mSecs / (1000 * 60);
var b = Math.floor(min / 30);
if (b >= 18 && 39 >= b){
if(surveyRecord.schedule_status == 'no_answer')
{
var tot = obj.timebuckets[b].totalSystem;
obj.timebuckets[b].totalSystem = tot + 1;
obj.timebuckets[b].totalRow = obj.timebuckets[b].totalRow + tot + 1;
systemGrandTotal = systemGrandTotal + 1;
}
else{
var tot = obj.timebuckets[b].totalInterviewer;
obj.timebuckets[b].totalInterviewer = tot + 1;
obj.timebuckets[b].totalRow = obj.timebuckets[b].totalRow + tot + 1;
interviewerGrandTotal = interviewerGrandTotal + 1;
}
}
}
bucket.push(obj);
}
</g:evaluate>
</g:ui_form>
<center>
</center>
<div class="col-sm-12 col-md-12">
<h1>All Studies Scheduling Report</h1>
</div>
<table id="exportTable" name="exportTable" class="table table-bordered">
<thead>
<tr>
<th rowspan="2">Study</th>
<j:forEach var="jvar_key" items="${bucket}">
<th style="text-align: center" colspan="2">${jvar_key.study_type}</th>
</j:forEach>
</tr>
</thead>
<tbody>
<g:evaluate jelly="true">
</g:evaluate>
<tr>
<th scope="row">Total Quota</th>
<j:forEach var="jvar_key" items="${bucket}">
<th style="text-align: center" colspan="2">${jvar_key.totQuota}</th>
</j:forEach>
</tr>
<tr>
<th scope="row">Total Completes</th>
<j:forEach var="jvar_key" items="${bucket}">
<th style="text-align: center" colspan="2">${jvar_key.totComp}</th>
</j:forEach>
</tr>
<tr>
<th scope="row">Total Attempts</th>
<j:forEach var="jvar_key" items="${bucket}">
<th style="text-align: center" colspan="2">${jvar_key.totAtt}</th>
</j:forEach>
</tr>
<tr>
<th scope="row">Number of Interviewers Assigned</th>
<j:forEach var="jvar_key" items="${bucket}">
<th style="text-align: center" colspan="2">${jvar_key.intCount}</th>
</j:forEach>
</tr>
<tr>
<th scope="row">Names of Assigned Interviewers</th>
<j:forEach var="jvar_key" items="${bucket}">
<th style="text-align: center" colspan="2">${jvar_key.intNames}</th>
</j:forEach>
</tr>
<tr>
<th>Queue Time Interval</th>
<j:forEach var="jvar_key" items="${bucket}">
<th bgcolor="EBF3FC">System Scheduled Record Count</th>
<th bgcolor="EBF3FC">Interviewer Scheduled Callback Record Count</th>
</j:forEach>
</tr>
<g:evaluate jelly="true">
var idx = 0;
</g:evaluate>
<j:forEach items="${buckets}" var="jvar_field_name">
<j:if test="${idx >= 18 && 39 >= idx }">
<tr>
<td scope="row">${jvar_field_name.interval;}</td>
<j:forEach items="${bucket}" var="jvar_bucket">
<!-- <g:evaluate jelly="true">
var interval = jvar_bucket.timebuckets[idx].interval;
var interviewer = jvar_bucket.timebuckets[idx].totalInterviewer;
var system = jvar_bucket.timebuckets[idx].totalSystem;
if (interviewer == 0)
{
interviewer = "";
}
if (system == 0)
{
system = "";
}
</g:evaluate> -->
<td>${jvar_bucket.timebuckets[idx].totalSystem;} </td>
<td>${jvar_bucket.timebuckets[idx].totalInterviewer;} </td>
<!-- <j:forEach begin="0" end="2" items="${bucket}" var="jvar_bucket">
<td>${jvar_bucket.timebuckets.totalSystem;}</td>
<td>${idx} </td>
</j:forEach> -->
</j:forEach>
</tr>
</j:if>
<g:evaluate jelly="true">
idx++;
</g:evaluate>
</j:forEach>
<tr class="success">
<th>Total</th>
<!-- <td>${systemGrandTotal}</td>
<td>${interviewerGrandTotal}</td> -->
</tr>
</tbody>
</table>
<button type="button" class="btn btn-primary col-sm-2 col-md-2" style="position: relative; bottom: 0; right: 0;" onClick="tableToCSV()">Export Report </button>
</j:jelly>