JavaScript DHTML/SmartClient/Portal — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Версия 13:00, 26 мая 2010
Portal animation
<source lang="html4strict">
<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>
<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>
</source>
Smartclient portal
<source lang="html4strict">
<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">
<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>
htmlAfter:"</nobr>" }, { id:"under10", title:"Red Light",htmlBefore:"<nobr>
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>
</BODY> </HTML>
</source>
SmartClient RSS portlet example
<source lang="html4strict">
<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>
</source>