Learning Center
Plans & pricing Sign in
Sign Out
Your Federal Quarterly Tax Payments are due April 15th Get Help Now >>

Building Interactive Web Applications using Stored Processes


									Using SAS Stored Processes with
JavaScript and Flash to Build Web
based Applications

 Introduction to SAS Web Applications
 Stored Processes on the Web
 Using JavaScript with SAS
 Ext JS & SAS
 Flash & SAS
 Conclusion
Does your app have to be on the web?

 Something I
  learnt yesterday
Consider JMP
 Very powerful
Do you want a SAS App on the Web?

 Often when a customer wants a web reporting tool, they
    SAS Enterprise BI Server
    Information Delivery Portal
    Web Report Studio/Viewer
    Web OLAP Viewer
    etc…
Do you want a SAS App on the Web?

         This looks OK,
but is it really what we want?
Do you want a SAS App on the Web?

 It is all customizable – which is great!
 Usually we want something even more customized
 Often we want something much more user friendly
 Sometimes there is no additional budget for the ideal
  SAS packaged solution
    Required skilled staff may not be easily available
Consider other ways to build applications
with SAS
 SAS AppDev Studio
 SAS/Intrnet
 Integration Technologies
    Web Services, Foundation Services (Java APIs), Web
     Infrastructure Kit
    Support for many languages: Windows Clients, Java, C++,
     VB.Net, etc.
 Enabling use of apps via a web interface, remote
  desktop, Citrix, etc.
 SAS Stored Processes
    Requires SAS 9
Why not build something like this?
SAS Stored Processes on the Web
Stored Processes for beginners

 Like a SAS macro
    Can pass parameters and define where it will run
    Can use security to define who can run it
    Can be run from many places
 Create either in:
    Enterprise Guide, auto handle metadata
    Other SAS tools such as Web Report Studio
    Define in management console and write code
 Run on stored process server or workspace server
Anatomy of a stored process

 Made up of 2 parts:
    Metadata
     » Server?
     » Users?
     » Parameters?
    SAS code, optionally containing
     » *ProcessBody;
         » Substitutes parameters
     » %stpbegin ;
         » ODS begin
     » %stpend ;
          » ODS end
    SAS Code vs. Stored Process

proc print data=sashelp.class ;
run ;
          Initiate input parm processing   *ProcessBody;

                           Initiate ODS    %stpbegin;

                                  code     proc print data=sashelp.class ;
                                           run ;

        Terminate ODS & deliver output     %stpend;

 Web Infrastructure Kit
    Provides bits to connect a web browser to SAS 9 architecture
      » e.g. run a stored process from browser
    Scalable
    Secure
    Similar functionality to SAS/IntrNet
 Provides a range of web applications, portlets and tools
    SAS Stored Process web application
    Portal web application
Stored process web application

 Allows running a stored process
    From a web browser
    From an application such as EXCEL, MS Word
    Anywhere you can call a URL – be creative!
 Allows passing parameters via URL
 Allow SAS to deliver output directly to browser
    Or whatever has invoked the URL
 Maintains logs
Macro variables used with %stpbegin
   _action
      Form, execute, properties, background, strip, index, data
   _debug
      Log, time
      My favourite … 2179 … gives most information
   _gopt_device
      Sasemf, java, activex, png
   _gopt_hsize, _gopt_vsize
   _gopt_xpixels, _gopt_ypixels
   _goptions
   _odsdest, _odsoptions, _odsstyle
   _program
   _result
      Status, stream, streamfragment, package_to_email, etc.
Macro variables that are available when
running the web app
 Some of the useful ones, from many
    _srvname
      » Server, machine webapp is running on
    _srvport
    _url
    _program
      » Path to Stored Process being run
    _metauser
      » Userid from metadata
    _metaperson
      » Name from metadata, e.g. Phil Mason
    _username
What output do you want

 HTML, RTF, PDF, EXCEL, etc??
    Any ODS output
 You can use the %stpbegin macro to help choose the
  kind of output you want
 Use _odsdest=html for interactive parts
 User can choose another format and your report will be
  produced accordingly
Streaming HTML to browser

 Set _result to stream
    e.g. On URL add &_result=stream
 Set _odsdest=html
   » e.g. On URL add &_odsdest=html
 I prefer to set _result to streamfragment
    Just writes HTML for reports/graphs without extra bits
      » No <html> tag or <body> section
      » Allows more customisation and control
      » You can use your own CSS
Some simple techniques for building
Applications with Stored Processes
 Enterprise guide can generate a web page
    Use wizard to do this simply
    It prompts for parameters and calls stored process
 Stored processes which create their own interactive
 Generate HTML with hyperlinks to other HTML
    Implement drill down
    Make menus
    Writing your own custom HTML

     Write to the fileref _webout
     Doesn’t work in between %stpbegin & %stpend, since
      _webout is being used
     Usually use with _result=stream, when streaming to

Data _null_ ;
  File _webout ;
  Put “<h1>Make your choices and press submit to continue</h1>” ;
Run ;
One way to put HTML into a web page
data html_code;              /* generate html code */
   infile datalines4 length=l;
   input #1 htmlline $varying400. l;
Put    your       HTML   here
data _null_;                 /* stream html code to browser */
   file _webout;
   set html_code;
   put htmlline;
A useful addition to this technique

 Use Resolve function to resolve any macro variables or
  macro calls in the datalines.

data _null_;        /* stream html code to browser */
   file _webout;
   set html_code;
   htmlline=resolve(htmlline) ;
   put htmlline;
Stored process with menu

 If specific parameters are passed in then produce report
 If they are not, then produce a menu
    Menu allows selection of various options
    When user clicks on “submit” then stored process is called again
       » Users selections are passed in
e.g.        %if &menu=yes %then %do ;
              * Some code to make a menu ;
              %end ;
            %else %do ;
              * some code to produce a report ;
              %end ;
Persistence – how to pass data between
Stored Processes
 Passing parameters on URL
    Easiest way
 Sessions
 Cookies
    I have had some problems trying this with IE6
 Files / datasets
    Sharing dataset
    Using Lock statement, checking return code and looping till free
Passing lots of parameters of the same
 Often used in html selection lists
 If list is called pick then you will get a collection of macro
    url&pick=a&pick=b
    Pick0=2, pick1=a, pick2=b

 Its easy to make a macro to construct a macro variable
  for use with an IN operator
    %let picks=“a”,”b” ;
Get vs. Post method
<form method=‘post’ action=‘do?_program=my_stp’>

 Get has a limit of about 2,083 characters
 If you pass more they are truncated without warning
    Can have unpredictable results
 Get
    Nice for short URLs
    Shows URL to user in browser address line or properties
 Post
    More secure, user cant see URL
    Needed for long URLs
Check the stored process server logs

 Great source of
 Write code to
  analyse logs
 Make sure your
  server options
  are set so you
  get the log info
  written that you
Use WinMerge to find differences in your
 Free
 Open
 Directory/fil
 Windows
 Beyond
  is better
Using JavaScript with SAS
What does a SAS programmer need to know
about JavaScript?
 Some basic HTML syntax
 Some basic JavaScript syntax
 How to define JavaScript libraries to HTML
 Some object oriented programming concepts
 How data is stored and used
 How SAS Stored Processes can feed data to objects
 How to find and use JavaScript debuggers
Where to put HTML code, JavaScript
libraries, images, etc.?
 SAS Web App runs
  via Application Server
  (a.k.a. Servlet
    Often this will be
 Use any accessible
    Can use ROOT
    Can use
     Web application
Building interactivity with JavaScript

 Popup windows
    Using alert function
 Updating status message
 Taking actions based on user interactions with objects
    Using onclick, ondblclick, onmouseover, onkeydown, etc.
 Validating form fields
 Linking to one or more other URLs
 Customising HTML programatically
  Linking stored processes

   Best way I have found is by using the body onLoad

data _null_ ;
  file _webout ;
  put '<body class="panel"' ;
src = " ;
IP://Foundation/test” ;
  Put "%nrstr(&parm1)=120%nrstr(&parm2)=BP' ;""" ;
  Put ">" ;
run ;
JavaScript IDE
Interactive Development Environment

 Advantages
    Syntax highlighting & code completion
    Debugger
    FTP, SFTP & Sync
 Possibilities
    Aptana Studio      Aptana Studio 3
    Netbeans
    Notepad ++
    Eclipse
    TextWrangler
    Hyperedit
JavaScript debuggers

 Apart from in IDEs
 Some Web browsers have them built in or available as
    Chrome
    Firefox, Firebug
    Safari, Firebug
    Internet Explorer, there are some …
The Ext JS JavaScript Framework
What is a JavaScript framework

 Provide a set of tools for building interactive web
    Means you can make great things quickly and easily
 Various are available:
    jQuery
    Ext JS
    Dojo Toolkit
    Spry Framework (from Adobe)
    Prototype
    Moo Tools
    ASP.NET Ajax Framework
Ext JS

What is Ext JS?
 JavaScript Framework
 Open Source
 Maintained by
 Rich modern UI widgets
 Supports all major browsers:
  Internet Explorer 6+, Firefox 1.5+, Chrome 3+, Safari 3+, Opera 9+
 Commercial and GPLv3 License
Ext JS & SAS

 Ext JS and SAS make a powerful combination
 SAS generate dynamic data driven webpages
 AJAX requests to SAS Stored Processes
 Use Ext JS Graphs and Grids for web reports
 Requires minimal SAS installation:
     SAS Base
     Stored Process Server
     Metadata Server
     Management Console
     Enterprise Guide (optional)
Example of a SAS & Ext JS Web App
Census Left
Census Right
The Ext JavaScript framework home page
Ext JS Examples

 Samples provided
http://localhost:8888/Ext JS/examples/
http://localhost:8888/Ext JS4/examples/

http://localhost:8888/Ext JS/examples/desktop/desktop.html
http://localhost:8888/Ext JS/examples/forum/forum.html
http://localhost:8888/Ext JS/examples/layout-browser/layout-
Ext JS Designer
Lets talk about how to use Ext JS

 Important terms and concepts:
    JSON (JavaScript Object Notation)
    AJAX (Asynchronous Javascript And XML)
    Components
    vtypes (validation types)
    Data Stores
    Events

 Key-Value pairs
 Man and Machine readable
 Nested if necessary
 Example:
{ key1 : value1
 ,key2 : { subkey1: subvalue1 }
      JSON example (& XML)
{"menu": {
   "id": "file",
   "value": "File",
   "popup": {
     "menuitem": [
       {"value": "New", "onclick": "CreateNewDoc()"},
       {"value": "Open", "onclick": "OpenDoc()"},
       {"value": "Close", "onclick": "CloseDoc()"}

The same text expressed as XML:

<menu id="file" value="File">
    <menuitem value="New" onclick="CreateNewDoc()" />
    <menuitem value="Open" onclick="OpenDoc()" />
    <menuitem value="Close" onclick="CloseDoc()" />
       Communicate with the server asynchronously
       No need for complete page refreshes to send or retrieve data

Ext.Ajax.request( {
       url : 'do?_program=/myStp/report1' ,
       params : { action : 'getDate' },
       method: 'GET',
       success: function ( result, request ) {
               'Data return from the server: '+
       failure: function ( result, request) {
              Ext.MessageBox.alert('Failed', result.responseText);
} ) ;

 Note that AJAX is asynchronous
 This means that the browser will continue to run the rest
  of the code, without waiting for the AJAX request to
 You may need to synchronize again!
 function synchronize_step() {
 if (wait_condition) {

 Components are the main building blocks of the user
 Commonly used components:
      Windows
      Panels (Tabpanel/Treepanel)
      Forms
      Textfields/Numberfields
      Grids
      Comboboxes
      Textareas
      Labels
      Checkboxes
      Radiobuttons
      Buttons

 Define using JSON format
var mywindow = new Ext.Window({
   xtype: window
  ,id: ‘mywindow’
  ,title: ‘mytitle’
  ,items: [
        /* add components of window here*/
} ) ;

 Validation Types
 When a textfield is edited, it is automatically validated.
 vtypes define when a value is valid or not
 A field will be marked as invalid
 A tooltip will explain why it is invalid

{ fieldLabel: ’File to save',
  name: ’save_file',
Vtypes – how to define
    Ext.apply(Ext.form.VTypes, {
     vfilename: function(v) {
       return ( v.indexOf("\\") == -1                 && v.indexOf("/") == -1
                 && v.indexOf("\"") == -1             && v.indexOf("*") == -1
                 && v.indexOf(">") == -1              && v.indexOf("<") == -1
                 && v.indexOf("?") == -1              && v.indexOf("|") == -1
                 && v.indexOf(":") == -1
                 && v.length +
                   Ext.getCmp('client_save_path').getValue().length <= 218
           ) ;    }
          ,vfilenameText: 'The maximum combined length of the path and
     filename is 218 characters. The following characters are invalid:
     " / \ * > < ? | :’
} ) ;
    vfilename is the name of the vtype
    vfilenameText is the tooltip text of the vtype
xt.form.VTypes["hostnameVal1"] = /^[a-zA-Z][-.a-zA-Z0-
Ext.form.VTypes["hostnameVal2"] = /^[a-zA-Z]([-a-zA-Z0-
Ext.form.VTypes["ipVal"] = /^([1-9][0-9]{0,1}|1[013-9][0-9]|12[0-
Ext.form.VTypes["netmaskVal"] =
Ext.form.VTypes["portVal"] = /^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-
Ext.form.VTypes["multicastVal"] = /^((22[5-9]|23[0-9])([.](0|[1-9][0-
Data Stores

 Data Stores are objects where data is stored for
  comboboxes, grids, etc.
 Local vs. Remote
    Local data stores refer to data defined on the client, like a
     JavaScript Array.
    Remote data stores refer to data defined on the server, using
     AJAX to retrieve the data.
 JavaScript objects use data in various formats
    Arrays
    Simple Stores
    XML
    JSON
Using SAS to provide data to JavaScript

 Key idea
    Stored processes can produce any kind of output
    Write a stored process to produce required data
      » e.g. JSON data
    Often a data source can be pointed to from JavaScript
      » e.g. using the URL parm in Ext JS
    A Stored Process can write to _webout to write the data to the
     web browser at the appropriate point
      » e.g. as an Array or SimpleStore
SimpleStores & Arrays
can be created by SAS
 Simplestore
var values = new{
            fields: ['id', 'value'],
            data : [['1','A'],['2','B'],['3','C']]

 Array
var myCars=new Array(); // regular array (add an optional integer
myCars[0]="Saab";       // argument to control array's size)
JSON Data Store – best one for Ext JS

 The store expects JSON data like this:
{ success: true
 ,rows: [
 {id: ‘id1’, val: ‘val1’}
,{id: ‘id2’, val: ‘val2’}
JSON Data Store produced by a
Stored Process
var mydatastore = new{
  url: "do?_PROGRAM=/CBA/dimitri_test2"
  ,reader: new{
        root: 'rows',
        id: ’name'
   }, [’name', ’sex’, ’age’])
} ) ;
More complete example
Ext.onReady(function(){ /* When all Ext JS stuff is loaded we can
start defining our application */
  var sasdatasetStore = new{ /* data store
necessary to load data from the server */
  id : 'sasdatasetStore' /* id is a unique id of the component so
we can later reference it using Ext.getCmp('sasdatasetStore') */
 ,url: 'do?_program=/CBA/dimitri_test2' /* stored process to
retrieve data */
 ,reader: new{ /* reader to process the JSON
data */
  root: 'rows', /* The property in the JSON data which contains
an Array of record objects */
  id: 'name' /* name of the value which is used as id */
  }, ['name', 'sex', 'age']) /* names of the values */
} );
sasdatasetStore.load(); /* load data from server */
Example of stored process producing data
/* stream data to browser in JSON format */
data _null_;
   file _webout;
   set sashelp.class end=last;
   if _n_ =1 then
      put "{ success:true, rows:[";
        /* return data retrieved was a success,
           rows is an array containing all the data */
      put ","; /* separator for each row in the data */
   put "{ name: '" name+(-1) "',
           sex: '" sex+(-1) "',
           age: '" age+(-1) "'}";
   if last then
     put "]}"; /* close array and JSON dataset */

 Events lets the application react to user
     Generated by one part of program – the event source
     Notify another part – the listener
 Usually are DOM or JavaScript (software) events
 You need to ‘listen’ for an event
{        xtype: 'textfield’
           ,id: “mytextfield”
 ,listeners :{
               valid: function() {
               /* code when textfield is valid*/        }
                } }

 Or handle an event
{    xtype: 'button’
        ,id: "mybutton"
     ,text: ‘Click Me’
,handler: function() {
    /* code to handle clicking the button */   }
Using Flash with SAS
What does a SAS programmer need to know
about Flash?
 Basic HTML
 Basic JavaScript
 How to configure browser to use flash
    Sometimes an issue on some company intranets
 How to put directives into form needed for flash object
 How to put data into form needed for flash object
Find a nice Flash Object

 Here is a free one called Charts/SWF, XML version
Sample flash HTML
<script language="JavaScript">AC_FL_RunContent = 0;</script>
<script language="JavaScript"> DetectFlashVer = 0; </script>
<script src="AC_RunActiveContent.js" language="JavaScript”>
<script language="JavaScript" type="text/JavaScript">
var requiredMajorVersion = 10;
var requiredMinorVersion = 0;
var requiredRevision = 45;

<BODY bgcolor="#FFFFFF”>

                                 1 of 4
<BODY bgcolor="#FFFFFF">
<script language="JavaScript" type="text/JavaScript">
if (AC_FL_RunContent == 0 || DetectFlashVer == 0) {
       alert("This page requires AC_RunActiveContent.js.");
} else {
var hasRightVersion = DetectFlashVer(requiredMajorVersion,
requiredMinorVersion, requiredRevision);
if(hasRightVersion) {
 'width', '400',
 'height', '250',
 'scale', 'noscale',
 'salign', 'TL',
 'bgcolor', '#777788',
 'wmode', 'opaque’,

                                  2 of 4
'wmode', 'opaque',
'movie', 'charts',
'src', 'charts',

'id', 'my_chart',
'name', 'my_chart',
'menu', 'true',
'allowFullScreen', 'true',
'quality', 'high',
'align', 'middle',
'pluginspage', '',
'play', 'true',
'devicefont', 'false’
} else {

                                    3 of 4
} else {
       var alternateContent = 'This content requires the Adobe
Flash Player. '
       + '<u><a href=>Get
// -->
          <P>This content requires JavaScript.</P>


                                   4 of 4
Using SAS to provide data to Flash

 Depends on what Flash object you use
 Usually will be XML or JSON
 Easy to use a stored process to produce this
 e.g. in previous example we had

 Should replace with this
XML file contains data and directives for
making graphs
 XML File
 HTML File
 Result
Another Flash Object

 Constellation Roamer
 Configuration
 Data

 Stored Processes give you all the power and flexibility
  of SAS
 JavaScript enables interactivity
 A JavaScript framework provides a quick start
 Flash objects provide a powerful package of
  functionality that SAS driving JavaScript can use
 The techniques in this paper show one way to put it all
Thanks for help with paper & presentation

 Dimitri Woei
    Business & Decision, Netherlands
 Chris Brooks
    Office of National Statistics, Wales
 Rafal Gagor
    Contractor, UK & Poland
These slides will be put onto by the end of
next week

You can email me at

To top