Wrench value from your Creo Investments Home Measure the benefits Simple Automation can bring Why
Automate?
A personal way to do PDM Peer to Peer
PDM
3D Drawings Model Based
Design
Smooth out unwanted sharp edges Other
Articles
www.proetoolbox.co.uk - Simple Automation made Simple

Combining Pro/Web.Link and YUI

This article builds on the previous one and develops a full example application with the YUI (Yahoo User Interface) Library so you can leverage the technique in your applications. For owners of the "A Pro/ENGINEERS Guide to Pro/Web.Link" you can download the working app to try it out in your environment.

The App

We're going to list all Models in Session (and show some properties for each of them) and then provide the user with a way of opening windows for some of them. The example will have sufficient detail to get you going.

Step 1: Build and test your Pro/Web.Link code

//PROGRAM CODE TO EXECUTE ON PAGE LOAD IN HERE
//Setups
var PrtType = pfcCreate("pfcModelType").MDL_PART;
var AssyType = pfcCreate("pfcModelType").MDL_ASSEMBLY;
var DrwType = pfcCreate("pfcModelType").MDL_DRAWING;

//Get List of In-Session Models
var Models = new Array();
var Parts = oSession.ListModelsByType(PrtType);
var Assys = oSession.ListModelsByType(AssyType);
var Drws = oSession.ListModelsByType(DrwType);
for (var i=0,z=Parts.Count;i<z;i++)
  Models[Models.length] = Parts.Item(i);
for (var i=0,z=Assys.Count;i<z;i++)
  Models[Models.length] = Assys.Item(i);
for (var i=0,z=Drws.Count;i<z;i++)
  Models[Models.length] = Drws.Item(i);

//Write Model Info To UI
var Out= new Array();
for (var i=0,z=Models.length;i<z;i++)
{
  try{
    Out[Out.length] = "<LI>"+
      Models[i].FileName+
      "</LI>";
  }
  catch(er)
  {}
}
UI.innerHTML = Out.join("");

First let's concentrate our mind on the code to list up all the objects.

  • Code Assumes you already have a template Pro/Web.Link App page. (get one here)
  • Save Template as e.g. "Table_Example.html"
  • Rename Title and Heading to suit.
  • Create Code to lists all Models in session.
  • Create Code to writes a list of Model Names into UI to check proper functioning.


  • What we are going to do next is to link the Array of Objects to a YUI Table.

    Step 2: Setup the Page to Accept YUI

    <BODY class=" yui-skin-sam">
    <!-- Individual YUI CSS files -->
    <link rel="stylesheet" type="text/css" 
      href="yui_files/button.css">
    <link rel="stylesheet" type="text/css" 
      href="yui_files/datatable.css">
    <!-- Individual YUI JS files -->
    <script type="text/javascript" 
      src="yui_files/yahoo-min.js"></script>
    <script type="text/javascript" 
      src="yui_files/dom-min.js"></script>
    <script type="text/javascript" 
      src="yui_files/event-min.js"></script>
    <script type="text/javascript" 
      src="yui_files/element-min.js"></script>
    <script type="text/javascript" 
      src="yui_files/button-min.js"></script>
    <script type="text/javascript" 
      src="yui_files/datasource-min.js"></script>
    <script type="text/javascript" 
      src="yui_files/datatable-min.js"></script>
    

    Setting up YUI is a matter of correctly including all the various related files such that you can call the appropriate functions which make your UI. I went to the trouble of copying all resource files into a single folder and adjusting the *.css files to point to the correct images.

  • Add class to setup the BODY element.
  • Add Links to YUI components (I manually copied to 'yui_files/').
  • Step 3: Add Code to generate the YUI Table

    //Write Model Info To UI
    myTable = function() {
    var myColumnDefs = [
      {key:"FileName", label: "Name", 
      formatter:YAHOO.widget.DataTable.formatText,
      sortable:true, resizeable:true}		
    ];
    
    var myDataSource = new YAHOO.util.DataSource(Models);
    myDataSource.responseType = 
      YAHOO.util.DataSource.TYPE_JSARRAY;
    myDataSource.responseSchema = {
      fields: ["FileName"]
    };
    var myDataTable = new YAHOO.widget.DataTable("UI",
      myColumnDefs, myDataSource);
    
    return {
      oDS: myDataSource,
      oDT: myDataTable
    };
    }();
    

    Defining the Table is as discussed in the previous article about accomplishing the following basic steps.

  • You must have an Array of Objects.
  • Define how you want the Columns to be.
  • Specify the datasource.


  • Wow wasn't that simple? Now to do some tweaking to make the app a bit more interesting...

     

    Step 4: Add More Columns

    var myColumnDefs = [
      {key:"Type", label: "Type", 
        formatter:CustomTypeFormater,sortable:true, 
    	resizeable:false},
      {key:"InstanceName", label: "Name", 
        formatter:YAHOO.widget.DataTable.formatText,
        sortable:true, 
    	resizeable:true},
      {key:"IsModified", label: "Status", 
        formatter:CustomStatusFormater,sortable:true, 
    	resizeable:false}		  
    ];
    

    Notice how I've added additional entries into the Column Definitions. More entries means more Columns. Notice how I'm calling out keys (Type, InstanceName and IsModified) which happen to be properties of the pfcModel objects in our array. The YUI has a great deal of flexibility over how you can choose to configure the display of each cell. In particular see how I've defined the cell formater for Type and IsModified to be Custom functions. We'll need to write them next.

  • 'key' is the property of the objects you're listing.
  • 'label' is how you want the title of the column to appear.
  • 'formatter' is the cell formatter function you want to use.
  • 'resizeable' is a flag to set whether the column can be re-sized.
  • 'sortable' is a flag to set whether the column can be sorted.
  • ...there are many other properties you can use!
  •  

    Step 5: Tweak the DataSource Object

    myDataSource.responseSchema = {
      fields: ["InstanceName","Type","IsModified"]
    };
    

    Be sure to tweak the DataSource lines such that the fields are correctly specified.

    Step 6: Define the Custom Formatting Options

    var CustomTypeFormater = 
      function(elCell, oRecord, oColumn, oData) {
        switch (oData)
        {
          case PrtType:
          elCell.innerHTML = 
    	    "<IMG SRC=\"ProE_Image/prt.gif\">";
    	  break;
    	  case AssyType:
          elCell.innerHTML = 
    	    "<IMG SRC=\"ProE_Image/asm.gif\">";
    	  break;
    	  case DrwType:
          elCell.innerHTML = 
    	    "<IMG SRC=\"ProE_Image/drw.gif\">";
    	  break;
        }
    };
    
    var CustomStatusFormater = 
      function(elCell, oRecord, oColumn, oData) {
      if (oData)
    	elCell.innerHTML = "+";
      else
    	elCell.innerHTML = "-";
    };  
    

    You will likely wish to define a custom formatter for most Pro/Web.Link applications. The format is straightforward as you can see in the code right. Be sure to place the definitions prior to the Column Definitions code.

    I wanted the content of the cells in Type and Status centered so I defined a '.center' style class and wrapped the formatter outputs with SPAN tags referencing the '.center' class. The result of the changes so far can be seen in the picture below.



    Step 7: Add A Column to Select Records

    var myColumnDefs = [
      {key:"Type", label: "Type", 
        formatter:CustomTypeFormater,sortable:true, 
    	resizeable:false},
      {key:"InstanceName", label: "Name", 
        formatter:YAHOO.widget.DataTable.formatText,
        sortable:true, 
    	resizeable:true},
      {key:"IsModified", label: "Status", 
        formatter:CustomStatusFormater,sortable:true, 
    	resizeable:false},
      {key:"Select",  
        formatter:"checkbox"}	
    ];
    

    We've added the 'Select' Column to allow user to pick records.

    We could also setup columns containing BUTTONS, Radio buttons and Columns with whatever you need in it. In fact the list of built in cell formatters is quite extensive, here's a list of some others I think are useful.

  • formatButton
  • formatDropdown
  • formatTextbox
  • formatDate
  • formatEmail
  • formatLink
  • formatText
  • formatNumber
  • formatTextarea
  • //Add Event handlers to the DataTable object.
    myDataTable.subscribe("checkboxClickEvent", 
      function(oArgs){
        var elCheckbox = oArgs.target;
        var oRecord = this.getRecord(elCheckbox);
        oRecord.setData("Select",elCheckbox.checked);
    });
    

    In order to make your checkbox record it's value against each record, a little extra code is needed. I've shown it right where you can see we 'setData' for the 'Select' field to whatever the current value of the checkbox is. I hope you agree, this is really very straight forward.

    Step 8: Add A Button to Open Selected Models

    <DIV id="UI_Pushbuttons"></DIV>
    

    Add a DIV into the HTML body to take the generated button.

    Setup the button and the template function to check the button is working.

    var oOpenPushButton = new YAHOO.widget.Button(
      {label:"Open", id:"openPushButton",
      container:"UI_Pushbuttons" });
    oOpenPushButton.on("click", OpenModels);
    		
    function OpenModels()
    {
    	alert ("Open Button Pressed");
    }
    

     

    Step 9: Add Code to Open Selected Models

    function OpenModels()
    {
      var CurWin = oSession.CurrentWindow;
      var RecordSet = myTable.oDT.getRecordSet();
      var Records = RecordSet.getRecords();
      for (var i=0,z=Records.length;i<z;i++)
      {
        if (Records[i].getData("Select"))
        {
          var CurModel = oSession.GetModel(
            Records[i].getData("InstanceName"),
    		Records[i].getData("Type")) ;
          var Win = oSession.CreateModelWindow(CurModel);
          CurModel.Display();
        }
      }
      CurWin.Activate();
    }
    

    The interesting thing about the code is that one can simply call the getRecordSet() method on the DataTable object and subsequently call getRecords() on the RecordSet to get an Array of Records which one can then getData("property") from. A little bit of Pro/Web.Link magic to finish and we have our finished application.

    Conclusion

    This Article led you through the practical use of YUI in making Simple Automation applications where the format is a)Produce Table b)Let user Select some Pro/E objects c)Process those Selected objects. This design pattern is the basis of many Simple Automation tools. If you own "A Pro/ENGINEERS Guide to Pro/Web.Link" you are quite welcome to download the full code.