JavaScript DHTML/SmartClient/Portal

Материал из Web эксперт
Перейти к: навигация, поиск

Portal animation

 
<!--
Isomorphic SmartClient
Copyright(c) 1998 and beyond Isomorphic Software, Inc.
"SmartClient" is a trademark of Isomorphic Software, Inc.
All rights reserved.
Open Source License
SmartClient source code, located under the source/ directory, and the resulting assembled modules 
in isomorphic/system/modules/, as well as JavaScript and CSS files under the isomorphic/skins directory are 
licensed under the terms of the GNU Lesser General Public License, version 3. 
The text of the LGPLv3 license is available online at http://www.gnu.org/licenses/lgpl-3.0.html
If your project precludes the use of this license, or if you"d like to support SmartClient LGPL, 
we encourage you to buy a commercial license.
Icon Experience Collection
Selected 16x16 icons within the isomorphic/skins directory are part of the Icon Experience collection 
(http://www.iconexperience.ru) and may be freely used with any SmartClient components without charge, 
but may not be used as part of screen designs separate from SmartClient components without a purchase 
of a license from Icon Experience. We are working to replace these icons as soon as possible.
All other media found under the isomorphic/skins directory may be used under the LGPLv3.
Commercial Licenses
A number of commercial licenses are available for purchase. Please see http://smartclient.ru/license.
Warranty Disclaimer
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 
Public License for more details.
Copyright 2001 and beyond Isomorphic Software, Inc. Last revised July 20, 2008. 

-->
<!-- The following code is revised from SmartClient demo code(SmartClient_70rc2_LGPL.zip).-->

<HTML><HEAD><TITLE>SmartClient portal animation example</TITLE>
    <SCRIPT>var isomorphicDir = "isomorphic/"</SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Core.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Foundation.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Containers.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Grids.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Forms.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_DataBinding.js></SCRIPT>
  <SCRIPT SRC=isomorphic/skins/BlackOps/load_skin.js></SCRIPT>
</HEAD><BODY CLASS="pageBackground">

<SCRIPT>
// global for convenient single setting of multiple animation times in this example
var gAnimatePortletTime = 750; // milliseconds
// fake portlet list for self-contained example
// The real list could be included inline, or loaded on the fly from the server.
// This data can include whatever attributes you want to use for these portlet,
// e.g. feed URLs, icons, update frequency...
var gPortletData = [
        {portletName:"Portlet 1"},
        {portletName:"Portlet 2"},
        {portletName:"Portlet 3"},
        {portletName:"Portlet 4"},
        {portletName:"Portlet 5"},
        {portletName:"Portlet 6"},
        {portletName:"Portlet 7"},
        {portletName:"Portlet 8"},
        {portletName:"Portlet 9"},
        {portletName:"Portlet 10"}
    ];
var gViewIconHTML = Canvas.imgHTML("[SKIN]actions/view.png");
var gAddToColumn = 0;
</SCRIPT>
<!-- load customized components for this example -->
<SCRIPT>
//  SmartClient portal example -- customized components
//      Portlet, PortalColumn, and PortalLayout
//
//  ISOMORPHIC SOFTWARE CONFIDENTIAL MATERIAL
// Portlet class definition
isc.defineClass("Portlet", "Window").addMethods({
    autoDraw:false,
    showShadow:false,
    // enable predefined component animation
    animateMinimize:true,
    // Window is draggable with "outline" appearance by default.
    // "target" is the solid appearance.
    dragAppearance:"outline",
    canDrop:true,
    
    // customize the appearance and order of the controls in the window header
    // (could do this in load_skin.js instead)
    headerMembers:["minimizeButton", "headerLabel", "closeButton"],
    // show either a shadow, or translucency, when dragging a portlet
    // (could do both at the same time, but these are not visually compatible effects)
    //showDragShadow:true,
    dragOpacity:30,
    
    // these settings enable the portlet to autosize its height only to fit its contents
    // (since width is determined from the containing layout, not the portlet contents)
    vPolicy:"none",
    overflow:"visible",
    bodyProperties:{overflow:"visible"}
});
// PortalColumn class definition
isc.defineClass("PortalColumn", "VStack").addMethods({
    // leave some space between portlets
    membersMargin:6,
    // enable predefined component animation
    animateMembers:true,
    animateMemberTime:gAnimatePortletTime,
    // enable drop handling
    canAcceptDrop:true,
    
    // change appearance of drag placeholder and drop indicator
    dropLineThickness:4,
    dropLineProperties:{backgroundColor:"aqua"},
    showDragPlaceHolder:true,
    placeHolderProperties:{border:"2px solid #8289A6"}
});
// PortalLayout class definition
isc.defineClass("PortalLayout", "HLayout").addMethods({
    numColumns:2,
    membersMargin:6,
    initWidget : function () {
        this.Super("initWidget", arguments);
        // create multiple PortalColumn components
        for (var i = 0; i < this.numColumns; i++) {
            this.addMember(isc.PortalColumn.create({autoDraw:false, width:"*"}));
        }
    },
    addPortlet : function (portlet, addToTop) {
        var fewestPortlets = 999999,
            fewestPortletsColumn;
        // find the column with the fewest portlets
        for (var i=0; i < this.members.length; i++) {
            var numPortlets = this.getMember(i).members.length;
            if (numPortlets < fewestPortlets) {
                fewestPortlets = numPortlets;
                fewestPortletsColumn = this.getMember(i);
            }
        }
        fewestPortletsColumn.addMember(portlet, (addToTop ? 0 : null));
        return fewestPortletsColumn;
    }
});
</SCRIPT>

<SCRIPT>
// PORTLET LIST
isc.ListGrid.create({
    ID: "portletList",
    autoDraw: false,
    height: 20,
    width: 120,
    
    // autosize to fit the list, instead of scrolling
    overflow: "visible",
    bodyOverflow: "visible",
    leaveScrollbarGap: false,
    
    // hide the column headers
    showHeader:false,
    
    // disable normal row selection behaviors
    selectionType: "none",
    
    fields: [ {name:"portletName", formatCellValue:"return gViewIconHTML + " " + value"} ],
    // see above for fake data used by this self-contained example
    data: gPortletData,
    
    //------------------------------------------------------------
    // OPEN PORTLET logic -
    //  Called whenever you click on an enabled row in this list.
    //------------------------------------------------------------
    rowClick: function (record, rowNum) {
        // disable the row -- this will prevent subsequent clicks, and will also change the
        //  row style, to indicate that this portlet is already in the viewing area
        record.enabled = false;
        this.refreshRow(rowNum);
        
        // create a new portlet
        var newPortlet = isc.Portlet.create({
            title: record.portletName,
            items:[
                // simple fake portlet contents - could put anything here
                isc.Label.create({
                    autoDraw:false, align:"center", layoutAlign:"center",
                    contents: record.portletName+" contents"
                })
            ],
            portletRecord: record,
            portletList: this,
            // callback to the portletList when this portlet is closed (see closePortlet below)
            closeClick: function () {this.portletList.closePortlet(this, this.portletRecord)}
        });
        // insert the portlet in the content area, but keep it hidden for now
        newPortlet.hide();
        var column = portalContentArea.addPortlet(newPortlet, true); // add to top
        // also insert a blank spacer element, which will trigger the built-in
        //  animateMembers layout animation
        var placeHolder = isc.LayoutSpacer.create();
        placeHolder.setRect(newPortlet.getRect());
        column.addMember(placeHolder,0); // add to top
        // create an outline around the clicked row
        var outline = isc.Canvas.create({
            left:this.getPageLeft(), top:this.getRowPageTop(rowNum),
            width:this.getVisibleWidth(), height:this.getRowSize(rowNum),
            border:"2px solid #8289A6"
        });
        // animate the outline from the clicked row, to the desired position of the new portlet
        // (this will execute in parallel with the placeHolder animation)
        outline.animateRect(
            newPortlet.getPageLeft(), newPortlet.getPageTop(),
            newPortlet.getVisibleWidth(), newPortlet.getVisibleHeight(),
            function () {
            // callback at end of animation - destroy placeholder and outline; show the new portlet 
                placeHolder.destroy();
                outline.destroy();
                newPortlet.body.hPolicy = "fill";
                newPortlet.show();
            },
            gAnimatePortletTime
        );
    },
    
    
    //------------------------------------------------------------
    // CLOSE PORTLET logic -
    //  Called when you click the close control in the top-right
    //  corner of a portlet (see closeClick above).
    //------------------------------------------------------------
    closePortlet: function (portlet, portletRecord) {
        var rowNum = portletList.data.indexOf(portletRecord);
        // create an outline around the portlet
        var outline = isc.Canvas.create({autoDraw:false, border:"2px solid #8289A6"});
        outline.setRect(portlet.getPageRect());

        // swap the portlet with a blank spacer element
        // (disabling relayout temporarily to prevent animation during the swap)
        var portalColumn = portlet.parentElement;
        portlet.hide();
        var spacer = isc.LayoutSpacer.create();
        spacer.setRect(portlet.getRect());
        portalColumn.addMember(spacer, portalColumn.getMemberNumber(portlet), true);
        // animateHide (shrink) the spacer to collapse this space in the content area
        spacer.animateHideTime = gAnimatePortletTime;
        spacer.animateHide();
        // simultaneously animate the portlet outline down to the row in this portletList
        outline.draw();
        outline.animateRect(
            this.getPageLeft(),
            this.getRowPageTop(rowNum),
            this.getVisibleWidth(),
            this.getRowSize(rowNum),
            function () {
            // callback at end of animation - destroy outline, portlet, and spacer;
            // also enable and refresh the row in the portletList so it does not show the special
            // style (and so it can be clicked again)
                outline.destroy();
                spacer.destroy();
                portlet.destroy();
                portletRecord.enabled = true;
                portletList.refreshRow(rowNum);
            },
            gAnimatePortletTime
        );
    }
});
// PAGE LAYOUT
isc.HLayout.create({ 
    ID: "portalExamplePage",
    width: "100%",
    height: "100%",
    layoutMargin: 10,
    membersMargin: 10,
    members: [
        portletList,
        isc.PortalLayout.create({ 
            ID: "portalContentArea", 
            autoDraw: false,
            numColumns: 3
        })
    ]
});
</SCRIPT></BODY></HTML>



Smartclient portal

 
<!--
Isomorphic SmartClient
Copyright(c) 1998 and beyond Isomorphic Software, Inc.
"SmartClient" is a trademark of Isomorphic Software, Inc.
All rights reserved.
Open Source License
SmartClient source code, located under the source/ directory, and the resulting assembled modules 
in isomorphic/system/modules/, as well as JavaScript and CSS files under the isomorphic/skins directory are 
licensed under the terms of the GNU Lesser General Public License, version 3. 
The text of the LGPLv3 license is available online at http://www.gnu.org/licenses/lgpl-3.0.html
If your project precludes the use of this license, or if you"d like to support SmartClient LGPL, 
we encourage you to buy a commercial license.
Icon Experience Collection
Selected 16x16 icons within the isomorphic/skins directory are part of the Icon Experience collection 
(http://www.iconexperience.ru) and may be freely used with any SmartClient components without charge, 
but may not be used as part of screen designs separate from SmartClient components without a purchase 
of a license from Icon Experience. We are working to replace these icons as soon as possible.
All other media found under the isomorphic/skins directory may be used under the LGPLv3.
Commercial Licenses
A number of commercial licenses are available for purchase. Please see http://smartclient.ru/license.
Warranty Disclaimer
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 
Public License for more details.
Copyright 2001 and beyond Isomorphic Software, Inc. Last revised July 20, 2008. 

-->
<!-- The following code is revised from SmartClient demo code(SmartClient_70rc2_LGPL.zip).-->

<HTML><HEAD>
  <SCRIPT>var isomorphicDir="isomorphic/";</SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Core.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Foundation.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Containers.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Grids.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Forms.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_DataBinding.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Calendar.js></SCRIPT>
  <SCRIPT SRC=isomorphic/skins/standard/load_skin.js></SCRIPT>
</HEAD><BODY BGCOLOR="silver">
<div id="gridDiv">
<SCRIPT>
// Sample Portlets
// ---------------------------------------------------------------------------------------
var samplePortlets = [];
// Qyarterly Results chart
// ---------------------------------------------------------------------------------------
samplePortlets.add({
    title:"Quarterly Results", 
    className:"FusionChart",
    makeComponent : function () {
        return makeSalesChart();
    }
});
function makeSalesChart() {
    return isc.FusionChart.create({
        autoDraw:false,
        facets:[{ id:"regions" }, { id:"product" }],
        data : [
           {product:"cars", regions:"west", _value:4},
           {product:"cars", regions:"north", _value:2},
           {product:"cars", regions:"east", _value:5},
           {product:"trucks", regions:"west", _value:1},
           {product:"trucks", regions:"north", _value:9},
           {product:"trucks", regions:"east", _value:3}
        ]
    })
}
// Analytics engine (CubeGrid)
// ---------------------------------------------------------------------------------------
samplePortlets.add({
    title:"Business Analytics",
    className:"CubeGrid",
    makeComponent : function () {
        return makeCubeGrid();
    }
});
function makeCubeGrid() {
var reportData = [
  {quarter:"Q1", month:"jan", region:"west", product:"pens", metric:"rev", _value:10000, percentNational:25},
  {quarter:"Q1", month:"jan", region:"west", product:"chairs", metric:"rev", _value:50000, percentNational:45},
  {quarter:"Q1", month:"jan", region:"west", product:"monitors", metric:"rev", _value:120000, percentNational:49},
  {quarter:"Q1", month:"jan", region:"west", product:"pens", metric:"profit", _value:2000, percentNational:25},
  {quarter:"Q1", month:"jan", region:"west", product:"chairs", metric:"profit", _value:5000, percentNational:45},
  {quarter:"Q1", month:"jan", region:"west", product:"monitors", metric:"profit", _value:44000, percentNational:59, _hilite:"over50"},
  {quarter:"Q1", month:"jan", region:"midwest", product:"pens", metric:"rev", _value:8000, percentNational:20},
  {quarter:"Q1", month:"jan", region:"midwest", product:"chairs", metric:"rev", _value:22000, percentNational:20},
  {quarter:"Q1", month:"jan", region:"midwest", product:"monitors", metric:"rev", _value:20000, percentNational:8, _hilite:"under10"},
  {quarter:"Q1", month:"jan", region:"midwest", product:"pens", metric:"profit", _value:2000, percentNational:25},
  {quarter:"Q1", month:"jan", region:"midwest", product:"chairs", metric:"profit", _value:2000, percentNational:18},
  {quarter:"Q1", month:"jan", region:"midwest", product:"monitors", metric:"profit", _value:5000, percentNational:7, _hilite:"under10"},
  {quarter:"Q1", month:"jan", region:"east", product:"pens", metric:"rev", _value:22000, percentNational:55, _hilite:"over50"},
  {quarter:"Q1", month:"jan", region:"east", product:"chairs", metric:"rev", _value:40000, percentNational:36},
  {quarter:"Q1", month:"jan", region:"east", product:"monitors", metric:"rev", _value:105000, percentNational:43},
  {quarter:"Q1", month:"jan", region:"east", product:"pens", metric:"profit", _value:4000, percentNational:50, _hilite:"over50"},
  {quarter:"Q1", month:"jan", region:"east", product:"chairs", metric:"profit", _value:4000, percentNational:36},
  {quarter:"Q1", month:"jan", region:"east", product:"monitors", metric:"profit", _value:25000, percentNational:34},
  {quarter:"Q1", month:"feb", region:"west", product:"pens", metric:"rev", _value:12000, percentNational:23},
  {quarter:"Q1", month:"feb", region:"west", product:"chairs", metric:"rev", _value:42000, percentNational:47},
  {quarter:"Q1", month:"feb", region:"west", product:"monitors", metric:"rev", _value:160000, percentNational:40},
  {quarter:"Q1", month:"feb", region:"west", product:"pens", metric:"profit", _value:4000, percentNational:23},
  {quarter:"Q1", month:"feb", region:"west", product:"chairs", metric:"profit", _value:4000, percentNational:47},
  {quarter:"Q1", month:"feb", region:"west", product:"monitors", metric:"profit", _value:68000, percentNational:40},
  {quarter:"Q1", month:"feb", region:"midwest", product:"pens", metric:"rev", _value:10000, percentNational:19},
  {quarter:"Q1", month:"feb", region:"midwest", product:"chairs", metric:"rev", _value:12000, percentNational:13},
  {quarter:"Q1", month:"feb", region:"midwest", product:"monitors", metric:"rev", _value:75000, percentNational:19},
  {quarter:"Q1", month:"feb", region:"midwest", product:"pens", metric:"profit", _value:3000, percentNational:20},
  {quarter:"Q1", month:"feb", region:"midwest", product:"chairs", metric:"profit", _value:1000, percentNational:11},
  {quarter:"Q1", month:"feb", region:"midwest", product:"monitors", metric:"profit", _value:32000, percentNational:17},
  {quarter:"Q1", month:"feb", region:"east", product:"pens", metric:"rev", _value:31000, percentNational:58, _hilite:"over50"},
  {quarter:"Q1", month:"feb", region:"east", product:"chairs", metric:"rev", _value:35000, percentNational:39},
  {quarter:"Q1", month:"feb", region:"east", product:"monitors", metric:"rev", _value:164000, percentNational:41},
  {quarter:"Q1", month:"feb", region:"east", product:"pens", metric:"profit", _value:8000, percentNational:53, _hilite:"over50"},
  {quarter:"Q1", month:"feb", region:"east", product:"chairs", metric:"profit", _value:4000, percentNational:44},
  {quarter:"Q1", month:"feb", region:"east", product:"monitors", metric:"profit", _value:88000, percentNational:47},
  {quarter:"Q1", month:"mar", region:"west", product:"pens", metric:"rev", _value:18000, percentNational:26},
  {quarter:"Q1", month:"mar", region:"west", product:"chairs", metric:"rev", _value:25000, percentNational:54, _hilite:"over50"},
  {quarter:"Q1", month:"mar", region:"west", product:"monitors", metric:"rev", _value:220000, percentNational:40},
  {quarter:"Q1", month:"mar", region:"west", product:"pens", metric:"profit", _value:9000, percentNational:29},
  {quarter:"Q1", month:"mar", region:"west", product:"chairs", metric:"profit", _value:2000, percentNational:40},
  {quarter:"Q1", month:"mar", region:"west", product:"monitors", metric:"profit", _value:112000, percentNational:38},
  {quarter:"Q1", month:"mar", region:"midwest", product:"pens", metric:"rev", _value:7000, percentNational:10},
  {quarter:"Q1", month:"mar", region:"midwest", product:"chairs", metric:"rev", _value:6000, percentNational:13},
  {quarter:"Q1", month:"mar", region:"midwest", product:"monitors", metric:"rev", _value:135000, percentNational:25},
  {quarter:"Q1", month:"mar", region:"midwest", product:"pens", metric:"profit", _value:2000, percentNational:6, _hilite:"under10"},
  {quarter:"Q1", month:"mar", region:"midwest", product:"chairs", metric:"profit", _value:1000, percentNational:20},
  {quarter:"Q1", month:"mar", region:"midwest", product:"monitors", metric:"profit", _value:66000, percentNational:23},
  {quarter:"Q1", month:"mar", region:"east", product:"pens", metric:"rev", _value:44000, percentNational:64, _hilite:"over50"},
  {quarter:"Q1", month:"mar", region:"east", product:"chairs", metric:"rev", _value:15000, percentNational:33},
  {quarter:"Q1", month:"mar", region:"east", product:"monitors", metric:"rev", _value:190000,percentNational:35},
  {quarter:"Q1", month:"mar", region:"east", product:"pens", metric:"profit", _value:20000, percentNational:65, _hilite:"over50"},
  {quarter:"Q1", month:"mar", region:"east", product:"chairs", metric:"profit", _value:2000, percentNational:40},
  {quarter:"Q1", month:"mar", region:"east", product:"monitors", metric:"profit", _value:115000, percentNational:39}
  
];

var report = isc.CubeGrid.create({
    autoDraw:false,
  
  data:    reportData,
    valueProperty:"_value",
  columns:  {facets:["quarter","month","metric"]},
  rows:    {facets:["region","product"]},
    canMoveFacets:true,
  canReorderFacets:    false,
  canSortData:      false,
  canSortFacets:      false,
  canCloseColumns:    false,
  autoSizeHeaders:    true,
  wrapFacetValueTitles:    true,
  wrapFacetTitles:    true,
  facets:  [
  {id:"quarter",
   title:"Quarter",
   values:[
    {id:"Q1", title:"Q1, 2002", align:"left"}
   ]},
  
  {id:"month",
   title:"Month",
   border:"1px solid black;",
   values:[
    {id:"jan", title:"January", align:"left"},
    {id:"feb", title:"February", align:"left"},
    {id:"mar", title:"March", align:"left"}
   ]},
  
  {id:"region",
   title:"Region",
   width:85,
   values:[
     {id:"west", title:"Western U.S."},
    {id:"midwest", title:"Midwest U.S."},
    {id:"east", title:"Eastern U.S."}
   ]},
   
  {id:"product",
   title:"Product",
   width:85,
   values:[
    {id:"chairs", title:"Trucks"},
    {id:"pens", title:"Cars"},
    {id:"monitors", title:"SUVs"}
   ]},
   
  {id:"metric",
   title:"Metric",
   values:[
    {id:"rev", title:"Revenue", width:70, align:"right",
            getCellValue : function (viewer, record) {
                return "$" + Math.round(record._value / 10) + "k";
            }
        },
    {id:"profit", title:"Profit", width:70, align:"right",
            getCellValue : function (viewer, record) {
                return "$" + Math.round(record._value / 10) + "k";
            }
        }
   ]}
    ],
   
  hilites:[  
  {
  id:"over50",
  title:"Green Light",
  htmlBefore:"<nobr><div style="float:left">&nbsp;<img src="inlineExamples/portal/images/greenlight.gif" width="7" height="7" border="0">&nbsp;</div>",
  htmlAfter:"</nobr>"
  },
  
  {
  id:"under10",
  title:"Red Light",
  htmlBefore:"<nobr><div style="float:left">&nbsp;<img src="inlineExamples/portal/images/redlight.gif" width="7" height="7" border="0">&nbsp;</div>",
  htmlAfter:"</nobr>"
  },
  
  {
  id:"boldpurple",
  title:"Bold Purple Text",
  style:"font-weight:bold; color:#990099;"    
  },
  
  {
  id:"aqua",
  title:"Aqua Background",
  style:"background-color:aqua; border:1px solid aqua;"
  }
    ],
    blinkCellList : [reportData[8], reportData[11], reportData[45]],
    blink : function (on) {
      this.hiliteCellList(this.blinkCellList, on ? 1 : null);
        var report = this;
      isc.Timer.setTimeout(function () { 
            report.blink(!on)
        }, 600);
    }
  
});
report.delayCall("blink");
return report;

}
// Sales Forecasting
// ---------------------------------------------------------------------------------------
samplePortlets.add({
    title:"Sales Forecasting",
    className:"VLayout",
    makeComponent : function () {
        return makeForecastGrid();
    }
});
function makeForecastGrid() {
isc.defineClass("PortletContents", "VLayout").addProperties({
    
    initWidget : function () {
        this.Super("initWidget", arguments);
        // generate a random data set
        //----------------------------------------
        var months = [
            {name:"jun", title:"Jun", longTitle:"June"},
            {name:"jul", title:"Jul", longTitle:"July"},
            {name:"aug", title:"Aug", longTitle:"August"},
            {name:"sep", title:"Sep", longTitle:"September"},
            {name:"oct", title:"Oct", longTitle:"October"},
            {name:"nov", title:"Nov", longTitle:"November"},
            {name:"dec", title:"Dec", longTitle:"December"}
        ];
        var salesData=[], 
            numProducts = 4, 
            products = ["Cars", "Trucks", "Vans", "SUVs"];
        for (var i=0; i<numProducts; i++) {
            salesData[i] = {product:products[i]};
            var minSales = Math.round(Math.random()*8000) + 2000, // 2k-10k
                maxVariance = minSales/3; // up to 33% of min value for this product
            for (var j=0; j<months.length; j++) {
                salesData[i][months[j].name] = Math.round(Math.random()*maxVariance) + minSales;
            }
        }
        // show a grid view
        //----------------------------------------
        this.salesDataGrid = isc.ListGrid.create({
            masterLayout: this,
    
            leaveScrollbarGap:false, height:108,
            canEdit:true, editEvent:"click", 
            chartProperties : {
                chartProperties : {
                    bgColor:"000000"
                }
            },
            // editing a cell triggers an update of the chart
            cellChanged:"this.updateChart()",
            updateChart : function (props) {
                // store chart configuration
                if (props) this.chartProps = props;
                isc.addProperties(this.chartProps, {
                    height: 300,
                    animateValuesOnShow: false
                });

                // if there"s already a chart, destroy it
                if (this.lastChart) this.lastChart.destroy();
                // generate chart
                this.lastChart = this.chartData("product", null, null, this.chartProps);
    
                // show it
                this.masterLayout.addMember(this.lastChart, 1);
            },
            // fields (columns) are the same as the chart categories (months), plus an extra column
            // up front to display the series names
            fields:[{name:"product", title:"Product", canEdit:false}].concat(months),
            data:salesData
        });
        // allow dynamic chart changing
        //----------------------------------------
        this.chartSelector = isc.DynamicForm.create({
            items : [ 
                { name:"chartType", title:"Chart Type", type:"select", defaultValue:"Line",
                  valueMap: ["Bar","Column","Line","Area", "Doughnut"],
                  defaultValue:"Column", changed:this.getID()+".salesDataGrid.updateChart({chartType: value})" }
            ]
        });
        this.addMembers([this.salesDataGrid, this.chartSelector]);
        this.salesDataGrid.updateChart({ chartType:"Line" });
    }
});
return isc.PortletContents.create();
}
// Training Video
// ---------------------------------------------------------------------------------------
samplePortlets.add({
    title:"Training Videos", 
    className:"Flashlet",
    makeComponent : function () {
        return makeTrainingVideo();
    }
});

function makeTrainingVideo () {
    return isc.Flashlet.create({
        width:"100%", height:"100%",
        src:"http://www.youtube.ru/v/URF2sVQWuxU&hl=en"
    })
}

// portal components
// ----------------------------------
isc.MenuPalette.create({
    ID:"menuPalette",
    dragType: "Portlet", 
    animateFadeTime: 250,
    showAnimationEffect: "slide",
    dragStart : function () {
        var start = this.Super("dragStart", arguments);
        if (start) {
            this.animateHide("fade", "isc.Menu.hideAllMenus()");
        }
        return start;
    },
    items: [{
        title:"Drag items out to create portlets", 
        disabled:true
    },{
        isSeparator:true
    }].concat(samplePortlets)
});
isc.Window.create({
    ID: "portalWindow", 
    autoDraw:false, 
    title: "Sales Portal",
  
    // add a menu button to the header  
    headerControls: [
        "headerIcon", "headerLabel", 
        isc.MenuButton.create({
            title: "Add Content",
            menu: menuPalette
        })
    ],
    
    items : [
        isc.PortalLayout.create({
            numColumns: 2
        })
    ]
});
isc.VLayout.create({
  width: "100%",
  height: "100%",
    layoutMargin:10,
    members: [ portalWindow ]
})
</SCRIPT>
</div>
</BODY>
</HTML>



SmartClient RSS portlet example

 
<!--
Isomorphic SmartClient
Copyright(c) 1998 and beyond Isomorphic Software, Inc.
"SmartClient" is a trademark of Isomorphic Software, Inc.
All rights reserved.
Open Source License
SmartClient source code, located under the source/ directory, and the resulting assembled modules 
in isomorphic/system/modules/, as well as JavaScript and CSS files under the isomorphic/skins directory are 
licensed under the terms of the GNU Lesser General Public License, version 3. 
The text of the LGPLv3 license is available online at http://www.gnu.org/licenses/lgpl-3.0.html
If your project precludes the use of this license, or if you"d like to support SmartClient LGPL, 
we encourage you to buy a commercial license.
Icon Experience Collection
Selected 16x16 icons within the isomorphic/skins directory are part of the Icon Experience collection 
(http://www.iconexperience.ru) and may be freely used with any SmartClient components without charge, 
but may not be used as part of screen designs separate from SmartClient components without a purchase 
of a license from Icon Experience. We are working to replace these icons as soon as possible.
All other media found under the isomorphic/skins directory may be used under the LGPLv3.
Commercial Licenses
A number of commercial licenses are available for purchase. Please see http://smartclient.ru/license.
Warranty Disclaimer
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 
Public License for more details.
Copyright 2001 and beyond Isomorphic Software, Inc. Last revised July 20, 2008. 

-->
<!-- The following code is revised from SmartClient demo code(SmartClient_70rc2_LGPL.zip).-->

<HTML><HEAD>
  <SCRIPT>var isomorphicDir="isomorphic/";</SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Core.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Foundation.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Containers.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Grids.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_Forms.js></SCRIPT>
    <SCRIPT SRC=isomorphic/system/modules/ISC_DataBinding.js></SCRIPT>
  <SCRIPT SRC=isomorphic/skins/SmartClient/load_skin.js></SCRIPT>
</HEAD><BODY BGCOLOR="e0e0e0"><SCRIPT>

// SmartClient RSS "portlet" example
//    This examples extends the simple RSS DataSource binding example
//    with:
//        -- more/less buttons
//        -- windows (drag, minimize, or close the headlines "portlet")
//        -- hover on headlines for descriptions
//        -- click on preview icon to open in new window
//        -- click on headline to open in another client-side portlet
//        -- enable/disable the buttons appropriately
//
//    Possible next steps for this example:
//        -- wrap this implementation as a single declarative component
//        -- create referenceable components under a portal-specified namespace
// default delay for hover actions is 1000ms (1s) - let"s make it shorter for this example
isc.Hover.delay = 400;
Hover.hoverCanvasDefaults.backgroundColor = "#FFFF99";

// bind an RSS feed to a dataSource and specify the fields we want to use
isc.DataSource.create({
    ID:"newsFeed",
    dataURL:"http://rss.slashdot.org/Slashdot/slashdot",
    recordXPath:"//default:item",
    fields:[
        {name:"title"},
        {name:"description"},
        {name:"link"}
    ]
});

// create a listGrid to display headlines from the RSS feed
isc.ListGrid.create({
    ID: "headlineGrid",
    autoDraw: false,
  // connect to the RSS-bound dataSource, but display the "title" field only
    dataSource:"newsFeed",
    fields:[
        {name:"link", type:"link", linkText:isc.Canvas.imgHTML("[SKIN]/common/view.png", 16, 16), width:22},
        {name:"title"}
    ],
  // border on top, no headers, no scrollbars
    styleName:"borderT",
    showHeader:false,
    bodyOverflow:"hidden",
    leaveScrollbarGap:false,
  // when the user hovers over a headline, show the description
    canHover:true,
    hoverWidth:300,
    cellHoverHTML: function (record) {return record.description},
  // when the user clicks on a headline, follow the link in a separate portlet
    recordClick:"storyPortlet.setContentsURL(record.link)"
});

// create a toolbar with Less/More buttons
isc.Toolbar.create({
    ID:"headlineControls",
    buttonConstructor:"IButton",
    height:36,
    layoutMargin:8,
    membersMargin:8,
    autoDraw:false,
    buttons:[
        {ID:"lessBtn", title:"Less...", click:"headlineWindow.showLess()" },
        {ID:"moreBtn", title:"More...", click:"headlineWindow.showMore()" }
    ]
});

isc.Window.create({
    ID:"headlineWindow",
    title:"Headlines",
    left:50, top:50, width:300, height:300,
    showCloseButton:false,
    numHeadlines:5, // to start with
    items:[headlineControls, headlineGrid],
    
    // logic to show more headlines and enable/disable the buttons appropriately
    showMore: function () {
        var rssData = headlineGrid.data;
        this.numHeadlines = this.numHeadlines + 3;
      // stop when we hit the end of the feed (first check that the feed is valid, to avoid errors)
        if (isc.isA.ResultSet(rssData) && rssData.lengthIsKnown() && this.numHeadlines >= rssData.getLength()) {
            this.numHeadlines = rssData.getLength();
            moreBtn.disable();
        }
        this.fitHeadlines();
        lessBtn.enable();
    },
    
    // logic to show fewer headlines and enable/disable the buttons appropriately
    showLess: function () {
        this.numHeadlines = this.numHeadlines - 3;
        if (this.numHeadlines <= 0) {
            this.numHeadlines = 0;
            lessBtn.disable();
        }
        this.fitHeadlines();
        moreBtn.enable();
    },
    // resize to fit the current number of headlines, plus extra space for the
    // window header, toolbar, and edges
    fitHeadlines: function () {
        this.setHeight(headlineGrid.cellHeight * this.numHeadlines + 75);
    }
});

isc.Window.create({
    title:"Full Story",
    left:400, top:50, width:600, height:500,
    canDragResize:true,
    showCloseButton:false,
    showMinimizeButton:false,
    items:[Canvas.create({
        ID:"storyPortlet", contentsType:"page", overflow:"auto"
    })]
});

headlineGrid.fetchData();
headlineWindow.fitHeadlines();
</SCRIPT>
</BODY>
</HTML>