FOCUS AREAS

SAS Output Delivery System (ODS) documentation

Base SAS

Generating Dynamic HTML

If you generate SAS output in HTML to be read by an audience of end users, then you might want to add dynamic HTML buttons to the page. The buttons can enable your end users to change the appearance of your output. For example, you can generate dynamic properties that enable the user to change colors, add a background image, modify the fonts, and redefine the overall styles. You can also enable the user to dynamically add, replace, or remove text, or to dynamically delete or add an observation.

This document's examples demonstrate how to use JavaScript along with PROC TEMPLATE to generate dynamic HTML files with ODS. Whatever you want to do, you can do it with JavaScript and PROC TEMPLATE. When JavaScript processes a specific element, it supplies an ID for the tag or element. Under PROC TEMPLATE, you can supply that ID with the HTMLID= attribute. This method allows the insertion of an ID for any element within the HTML file.

Modifying Colors

This example places buttons on the HTML page that enable the end user to select colors for the background of the page, the table, the title, and the footnote. After you use the HTMLID= attribute to create an ID, you pass the ID and the desired color to the SetFontColor function. Notice that any value passed to the function needs an extra set of single quotation marks (apostrophes).

The example uses the Document Object Model (DOM) to access each element by its ID and apply the color passed. Below is the function passed in the JavaScript, which is unseen because it is passed externally. The function SetFontcolor takes two parameters: the ID and the color. One of the properties of the DOM is the GetElementById property. This allows you to get the first element with the ID value for that property and apply the instruction. This example passes the style property with the background CSS property. CSS properties are specified in the same way using the DOM as in CSS, except with dashes. View output.

function setfontcolor(id,color){
         document.getElementById(id).style.background =  color  ;
}

The below PROC TEMPLATE code passes the ID and color to several objects.

proc template;
  define style styles.test;
  parent=styles.default;
  style body from body /
        prehtml='
        <FORM>
        <INPUT TYPE="button"
        VALUE="Back Magenta"
        onClick="if(document.getElementById)
                   setfontcolor(''body'',''magenta'')">
        <INPUT TYPE="button"
        VALUE="Back Black"
        onClick="if(document.getElementById)
                   setfontcolor(''body'',''black'')">
        <INPUT TYPE="button"
        VALUE="Table Magenta"
        onClick="if(document.getElementById)
                   setfontcolor(''table'',''magenta'')">
        <INPUT TYPE="button"
        VALUE="Table Black"
        onClick="if(document.getElementById)
                   setfontcolor(''table'',''black'')">
        <INPUT TYPE="button"
        VALUE="Title Magenta"
        onClick="if(document.getElementById)
                   setfontcolor(''title'',''magenta'')">
        <INPUT TYPE="button"
        VALUE="Title Black"
        onClick="if(document.getElementById)
                   setfontcolor(''title'',''black'')">
        <INPUT TYPE="button"
        VALUE="Title fore green"
        onClick="if(document.getElementById)
                   setfontcolor(''title'',''green'')">
        <INPUT TYPE="button"
        VALUE="footnote magenta"
        onClick="if(document.getElementById)
                   setfontcolor(''foot'',''magenta'')">
        </form>'
        htmlid='body';

  style table from table /
        htmlid='table';
  style systemtitle from systemtitle /
        htmlid='title';
  style systemfooter from systemfooter /
          htmlid='foot';
  end;
run;

ods html body='temp.html' contents='temp1.html' style=styles.test
    headtext='<script language="javascript" src="c:\test.js">
    </script>
    ';

proc print data=sashelp.class;
  footnote 'test';
run;

proc print data=sashelp.class;
run;
ods html close;

Applying a Background Image

The next example uses the DOM to supply a background image to the HTML page. The GetItemById property specifies the ID, and the backgroundImage CSS property supplies an image to the HTML page. The ID and the GIF file are passed as an argument to the SetBackgroundImage function. The function is listed below. View output.

function setBackgroundImage(id,image){
         document.getElementById(id).style.backgroundImage = 'url('+image+')';
}

Below is the PROC TEMPLATE code.

proc template;
  define style styles.test;
  parent=styles.default;
    style body from body /
          prehtml='
          <FORM>
          <INPUT TYPE="button"
          VALUE="Back image"
          onClick="if(document.getElementById)
                      setBackgroundImage(''body'',''gchart21.gif'')">
          </form>'
    htmlid='body';
  end;
run;

ods html body='temp.html' contents='temp1.html' style=styles.test
    headtext='<script language="javascript" src="c:\test.js">
    </script>
    ';

proc print data=sashelp.class;
  footnote 'test';
run;

proc print data=sashelp.class;
run;
ods html close;

Applying a Style

This example applies a style for all of the cell values. For this example, the GetElementById property will not work because it applies the instruction to the first element with the ID value. In this case, the style should be supplied to all of the child values as well, which is done by the GetElementsByTagName property. This attribute takes the tag name as an argument, creates a variable, and calculates the number of child nodes. View output.

function changeElementsStyle(el,clr,fsz,fw,fs){
         if(document.getElementsByTagName)//check for obj
         {
         var nodes = document.getElementsByTagName(el)
         var max = nodes.length
         for(var i = 0;i < max;i++)
         {
         var nodeObj = nodes.item(i);
         nodeObj.style.color = clr;
         nodeObj.style.fontSize= fsz;
         nodeObj.style.fontWeight = fw;
         nodeObj.style.fontStyle = fs;
         }
         }
         }

With PROC TEMPLATE, you pass the tag name to the function changeElementsStyle. The affected styles are the fontweight and the fontstyle. Again, the values are enclosed in a set of two single quotation marks (apostrophes).

proc template;
  define style styles.test;
  parent=styles.default;
    style body from body /
          prehtml='
          <FORM>
          <button
          onclick="changeElementsStyle(''thead'',''red'',
                                       ''100'',''bolder'',''italic'')"
          >header</button>
          <button
          onclick="changeElementsStyle(''tbody'',''red'',
                                       ''100'',''bolder'',''italic'')"
          >body</button>
          </form>';
    style data from data /
          htmlid='data';
  end;
run;

ods html body='temp.html' contents='temp1.html' style=styles.test
    headtext='<script language="javascript" src="c:\test.js">
    </script>
    ';

proc print data=sashelp.class;
  footnote 'test';
run;

proc print data=sashelp.class;
run;
ods html close;

Adding and Removing Text

The example below uses the DOM properties APPENDCHILD and the REMOVECHILD methods. The APPENDCHILD appends an element and the REMOVEELEMENT removes a element. View output.

function append(clr,value) {
         newelement=document.createElement("<div align=center
                                           style=font-size:40pt>");
         newelement.style.color=clr;
         newelement.innerHTML=value;
         document.all.body.appendChild(newelement);
         }

function remove( ) {
         var newelement;
         document.all.body.removeelement(newelement);
         }

Below is the PROC TEMPLATE code, which adds "this is some other text" to the bottom of the output page.

proc template;
  define style styles.test;
  parent=styles.default;
    style body from body /
          prehtml='
          <FORM>
          <INPUT TYPE="button"
          VALUE="insert text"
          onClick="append(''green'',''this is some other text'')">
          <INPUT TYPE="button"
          VALUE="remove text"
          onClick="remove(this)">
          </form>'
          htmlid='body';
  end;
run;

ods html body='temp.html' contents='temp1.html' style=styles.test
    headtext='<script language="javascript" src="c:\append.js">
    </script>
    ';

proc print data=sashelp.class;
  footnote 'test';
run;

ods html close;

Replacing Text

The example given below replaces content dynamically by using the InnerHTML DOM property. This property changes the text inside an HTML tag that is rendered by the ID. In the example, the title is changed to a new string that is passed to the function CHANGE from PROC TEMPLATE. The style attributes for color and font size are also passed. View output.

function change(value,size,clr) {
         title.innerHTML=value;
         title.style.fontSize=size;
         title.style.color=clr;
         }

The PROC TEMPLATE code is below.

proc template;
  define style styles.test;
  parent=styles.default;
    style body from body /
          prehtml='
          <FORM>
          <INPUT TYPE="button"
          VALUE="Change title"
          onClick="change(''this is some other text'',''40'',''red'')">
          </form>';
    style systemtitle from systemtitle /
          htmlid='title';
  end;
run;

ods html body='temp.html' contents='temp1.html' style=styles.test
    headtext='<script language="javascript" src="c:\change.js">
    </script>
    ';

proc print data=sashelp.class;
  footnote 'test';
run;

ods html close;

Modifying the Justification

You can dynamically justify an element by using CSS properties. View output.

function moveleft()
         {
         title.style.position="absolute"
         title.style.left="0"
         }
function moveback()
         {
         title.style.position="relative"
         }

The PROC TEMPLATE code is below.

proc template;
  define style styles.test;
  parent=styles.default;
    style body from body /
          prehtml='
          <FORM>
          <INPUT TYPE="button"
          VALUE="Change title"
          onClick="moveleft()">
          <INPUT TYPE="button"
          VALUE="Change title"
          onClick="moveback()">
          </form>';
    style systemtitle from systemtitle /
          htmlid='title';
  end;
run;

ods html body='temp.html' contents='temp1.html' style=styles.test
    headtext='<script language="javascript" src="c:\move.js">
    </script>
    ';

proc print data=sashelp.class;
  footnote 'test';
run;

ods html close;

Deleting Cell Values

The following example deletes cell values, one at a time. View output.

function delCell()
         {
         var x=myTable.rows(1)
         var y=x.deleteCell(1)
         }

The PROC TEMPLATE code is below.

proc template;
  define style styles.test;
  parent=styles.default;
    style body from body /
          prehtml='
          <FORM>
          <INPUT TYPE="button"
          VALUE="Change title"
          onClick="delCell()">
          </form>';
    style table from table /
          htmlid='myTable';
  end;
run;

ods html body='temp.html' contents='temp1.html' style=styles.test
    headtext='<script language="javascript" src="c:\delcell.js">
    </script>
    ';

proc print data=sashelp.class;
  footnote 'test';
run;

ods html close;