In my previous blog post we created a restful service that returns with ALV metada and data. Now we will develop a jquerymobile web client that calls this service and represents data in jquery datatables plugin.
Part 1 - Create RESTful service
Part 3 - Visualize ALV Data with Highcharts for iPad
Creating JqueryMobile Web Application
Pre-requisites:
Steps:
index.html
<!DOCTYPE html>
<html>
<!--<html manifest="app.appcache">-->
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="shortcut icon" href="images/mysapreport.jpg" />
<link rel="stylesheet" href="css/jqm/jquery.mobile-1.1.1.min.css" />
<!-- DataTables CSS -->
<link rel="stylesheet" type="text/css" href="css/datatables/jquery.dataTables.css"/>
<link rel="stylesheet" type="text/css" href="css/datatables/ColVisAlt.css"/>
<script src="js/jqm/jquery-1.7.2.min.js"></script>
<script src="js/jqm/jquery.mobile-1.1.1.min.js"></script>
<!-- DataTables -->
<script type="text/javascript" src="js/datatables/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="js/datatables/ColVis.min.js"></script>
<script type="text/javascript" src="js/datatables/TableTools.min.js"></script>
<script type="text/javascript" src="js/settings.js"></script>
<script type="text/javascript" src="js/table.js"></script>
<script>
$.support.cors = true;
jQuery.support.cors = true;
</script>
</head>
<body>
<div data-role="page" id="alv" data-theme="e">
<div data-role="header" data-position="fixed">
<h1>ALV</h1>
<a href="#settings" data-role="button" data-icon="gear" data-theme="b">Settings</a>
</div>
<div data-role="content" >
<div data-role="fieldcontain">
<label for="transaction">Transaction:</label>
<input type="text" name="transaction" id="transaction" value="" />
</div>
<div data-role="fieldcontain">
<label for="variant">Variant:</label>
<input type="text" name="variant" id="variant" value="" />
</div>
<a href="javascript:getALV()" data-role="button" data-icon="grid" data-theme="b">Call Report</a>
<br>
</div>
</div>
<div data-role="dialog" id="settings">
<div data-role="content" >
<label for="connectUrl">Connect to:</label>
<input type="url" name="connectUrl" id="connectUrl" value="" data-mini="true" />
<label for="username">Username:</label>
<input type="text" name="username" id="username" value="" data-mini="true" />
<label for="password">Password:</label>
<input type="password" name="password" id="password" value="" data-mini="true" />
<br>
<a href="javascript:exitSettings()" data-role="button" data-icon="delete">Exit</a>
<a href="javascript:saveSettings()" data-role="button" data-icon="check" data-theme="b">Save</a>
</div>
</div>
<div data-role="page" id="showDatatable" data-theme="e" data-add-back-btn="true" data-dom-cache="true">
<div data-role="header" data-position="fixed">
<h1 id="datatableHeader">ALV</h1>
<div class="ui-btn-right">
<a href="#chartRules" data-role="button" data-icon="star" data-theme="e" data-back="true">Chart</a>
</div>
</div>
<div data-role="content">
<div id="dynamicDatatableDIV" >
<!--<table id="dynamicDatatable" class="tbl_basket_style"></table>-->
</div>
</div>
</div>
</body>
</html>
Call Restful Service:
function getALV(){
alvData = [];
alvMetadata = [];
$.ajax({
type: "GET",
url: 'http://' + $("#username").val() + ':' + $("#password").val() + '@' + $("#connectUrl").val() + '?tcode=' + $("#transaction").val() + '&variant=' + $("#variant").val(),
data: "",
dataType: "jsonp",
contentType: "application/javascript",
username:$("#username").val(),
password:$("#password").val(),
jsonpCallback:"jsonp_success",
crossDomain: true,
cache: false,
timeout: 10000,
xhrFields: {
withCredentials: true
},
beforeSend: function(xhr, settings){
$.mobile.showPageLoadingMsg();
},
complete: function(xhr, textStatus) {
$.mobile.hidePageLoadingMsg();
if (alvMetadata){
createDynamicTable(getColumnData(alvMetadata),alvData);
$.mobile.changePage('#showDatatable');
$('#datatableHeader').text(reportDescription);
}
},
success: function(sys){
},
error: function( result ){
if (result.statusText !== "success"){
alert('Error!! Unable to call ALV Report. Please check your settings & SAP connection');
$.mobile.changePage('#settings');
}
}
}); // Ajax posting
}
function JSONP_SUCCESS(result){
reportDescription = result.description;
alvMetadata = result.alvMetadata;
alvData = result.alvData;
//sort ALV metadata according to col_pos
alvMetadata.sort(function(a,b) {
return (parseInt(a.col_pos) > parseInt(b.col_pos)) ? 1 : ((parseInt(b.col_pos) > parseInt(a.col_pos)) ? -1 : 0);
} );
}
Datatables Columns Creation
function getColumnData(alvMetadata){
var column = new Array();
var type;
var just;
var sclass;
var visible;
var visCount = 0;
for(i=0;i<alvMetadata.length;i++){
type = alvMetadata[i].inttype;
just = alvMetadata[i].just;
visible = alvMetadata[i].no_out;
switch (type){
case 'D':
type = "date";
break;
case 'N':
type = "string";
break;
case 'P':
type = "numeric";
break;
case 'I':
type = "numeric";
break;
case 'F':
type = "numeric";
break;
default:
type = "string";
break;
}
switch (just){
case 'L':
sclass = "left-align";
break;
case 'R':
sclass = "right-align";
break;
case 'C':
sclass = "center-align";
break;
default:
sclass = "left-align";
break;
}
if (visible == 'X' || visCount > 5)
visible = false;
else{
visible = true;
visCount++;
}
column.push({
"mDataProp":alvMetadata[i].fieldname.toLowerCase(),
"sName": alvMetadata[i].fieldname,
"sTitle": alvMetadata[i].seltext,
"sType": type,
"sClass": sclass,
"bVisible": visible
});
}
return column;
}
Initialize Datatables
function createDynamicTable(aColumnData,aDataSet){
$('#dynamicDatatableDIV').html( '<table id="dynamicDatatable" class="tbl_basket_style"></table>' );
var alvTable = $('#dynamicDatatable').dataTable( {
"sDom": 'rfCtip',
"bStateSave": true,//length, filtering, pagination and sorting not change when refresh(cooki)
"sPaginationType": "full_numbers",
"iDisplayLength": 65536,
"oColVis": {
"bRestore": true
},
"bUseRendered": false,
"aaData": aDataSet,
"aoColumns": aColumnData
} );
}
Test
After publishing service on your own system, you can call it only by editing settings in MySapReport . Web client saves your settings on localstorage except password. Password is saved on sessionstorage. So don't need to edit connection url and username in each visit of client application but password is asked for each session.
You can run demo with empty settings.
If you want, you can publish client as BSP pages on sap ITS. For step by step instructions read John Moy's blog .
You can find all sources codes on https://github.com/basarozgur/MySapReport
Screen Shots:
Transaction code entry
Settings
Report Data
Datatables Show / Hide Columns
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
11 | |
9 | |
7 | |
6 | |
4 | |
4 | |
3 | |
3 | |
3 | |
3 |