SAP BusinessObjects Dashboards Component SDK Tutorial 4 - Creating a custom property sheet ■ SAP BusinessObjects 4.

1

2013-03-16

No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP AG. The information contained herein may be changed without prior notice. These materials are provided by SAP AG and its affiliated companies ("SAP Group") for informational purposes only.com/corporate-en/legal/copyright/index.Copyright © 2013 SAP AG or an SAP affiliate company. The only warranties for SAP Group products and services are those that are set forth in the express warranty statements accompanying such products and services. Nothing herein should be construed as constituting an additional warranty. Some software products marketed by SAP AG and its distributors contain proprietary software components of other software vendors. SAP and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and other countries. and SAP Group shall not be liable for errors or omissions with respect to the materials. Please see http://www. if any. without representation or warranty of any kind. 2013-03-16 .sap. National product specifications may vary.epx#trademark for additional trademark information and notices. All rights reserved.

............................................................Contents Chapter 1 Introduction..................................................................11 Chapter 5 Task 4: Handling communication between property sheet and the component..................................3 5...............................................2 5......................................5 3 2013-03-16 ..........................4 5........................................................................16 5............1 5.16 Subtask 4e: Implementing continueBind function.............................9 Chapter 4 Task 3: Creating a CSS File.................................5 Chapter 2 Task 1: Creating a basic Flex project....14 Subtask 4d: Implementing getPropertyBindDisplayName and initiateBind functions..................................................................................14 Subtask 4c: Implementing initValues() function.................13 Subtask 4b: Implementing init() function............................................................13 Subtask 4a: Importing classes and creating local variables...7 Chapter 3 Task 2: Designing the layout for the property sheet.....................................................................................................

Contents 4 2013-03-16 .

We will also use a sample CSS definition to style the property sheet to look more like the Dashboards color scheme. Download the source code for the custom component so that you could see what properties and styles it has. Please see the CustomPropSheetHorizontalSlider sample source code for a more advanced layout.Introduction Introduction This tutorial assumes that you have at least some knowledge of Cascading Style Sheet (CSS). You will need to reference the names of the properties/styles inside the property sheet source code. ActionScript 3. 5 2013-03-16 . the XML-based markup language introduced by Adobe Flex.0. only the basic controls for the layout of custom property sheet are mentioned. The concentration of the tutorial is creating a custom property sheet for those who do not want to use the default property sheet. We will include Flex controls in the property sheet so that all of the properties and styles of the custom component can be exposed. and MXML. For demonstration purposes.

Introduction 6 2013-03-16 .

Inside of the <mx:Application> tag. Open the Flex project application MXML file. add applicationComplete="init(). 7 2013-03-16 . For details on creating a project and adding the framework.". 2. Create a basic Flex project for the custom property sheet.Task 1: Creating a basic Flex project Task 1: Creating a basic Flex project 1. refer to the Dashboards Component SDK User Guide section Create a visual component. 3. .

Task 1: Creating a basic Flex project 8 2013-03-16 .

text). x=23. left=59 • TextInput: id=titleEditor. x=137.adobe. label=Show Title. right=28. y=169. height=100% • Label: text=Text.setStyle('titleFontColor'. label=General. height=100% • Label: text=Title.setProperty('showTitle'. y=54 • ComboBox: id=titleFontFamilyEditor.value). y=116. x=43. x=231 y=79 width=55 • Label: text=Color.com/2006/mxml" layout="absolute" applicationComplete="init(). right=28. height=10. Design the layout of the custom property sheet. uint(titleColorEditor. width=100%. you should have the following code: <?xml version="1. width=129 • ComboBox: id=titleFontSizeEditor. width=119 • HRule: y=28. right=69."> <mx:ViewStack id="viewstack1" creationPolicy="all" left="0" right="0" y="45" height="100%" width="100%" minWidth="268" minHeight="350"> <mx:Canvas id="general" label="General" minWidth="268" minHeight="350" width="100%" height="100%"> 9 2013-03-16 . y=136. x=23. y=45.seProperty('value'. showTitleEditor. x=23. y=144. change=proxy.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www. dataProvider={_fontSizes}.selected). width=100%. width=119 • HRule: y=118. titleFontSizeEditor. icon=@Embed('resources/bind to cell. change=proxy. height=10. right=37. y=169 • TabBar: dataProvider=viewstack1 3. y=52. left=37 • Button: click=initiateBind('value').text)). switch to Source mode. x=43. left=56 • CheckBox: id=showTitleEditor. width=100%. dataProvider={_fontNames}. After laying out the controls. right=28.setStyle('titleFontFamily'. y=143. right=0. right=69. x=23. y=24. titleFontFamilyEditor. left=0. minWidth=268. change=proxy.setProperty('title'. minWidth=268. Switch to Design mode by pressing the Design button located next to the Source button. Number(valueEditor. left=66 • TextInput: id=valueEditor. text=Title Color:. height=10.png'). width=24 • Canvas: id=appearance. label=Appearance. change=proxy. text=Text. minHeight=350. right=28. height=100%. minWidth=268. minHeight=350. creationPolicy=all. y=23. width=119 • HRule: y=28.selectedColor)).Task 2: Designing the layout for the property sheet Task 2: Designing the layout for the property sheet 1. left=62 • Label: text=Title Color. width=119 • HRule: y=141. minHeight=350 • Canvas: id=general. height=10. Add the following controls to the layout: • Viewstack: id=viewstack1.setStyle('titleFontSize'. 2. left=37 • Label: text=Value.value). change=proxy. titleEditor. selected=true. change=proxy. y=79. x=94. width=116 • ColorPicker: id=titleColorEditor.

selectedColor))" /> </mx:Canvas> </mx:ViewStack> <mx:TabBar x="0" y="0" dataProvider="viewstack1"> </mx:TabBar> </mx:Application> 10 2013-03-16 ." icon="@Embed('re sources/bind to cell.setStyle('titleFontSize'.titleEditor. showTitleEditor. titleFontFamilyEditor.setStyle('titleFontFamily'. titleFontSizeEditor.Task 2: Designing the layout for the property sheet <mx:Label x="23" y="24" text="Title" width="119"/> <mx:HRule y="28" height="10" right="28" left="59"/> <mx:TextInput id="titleEditor" y="52" right="69" left="37" change="proxy.value)" /> <mx:Label x="23" y="136" text="Color" width="119"/> <mx:HRule y="141" height="10" right="28" left="62"/> <mx:Label x="43" y="169" text="Title Color:" width="116"/> <mx:ColorPicker id="titleColorEditor" x="137" y="169" change="proxy.setProper ty('showTitle'.value)" /> <mx:ComboBox id="titleFontSizeEditor" dataProvider="{_fontSizes}" x="231" y="79" width="55" change="proxy. Number(valueEditor.text))"/> <mx:Button y="143" right="37" width="24" click="initiateBind('value').setStyle('titleFontColor'. uint(titleColorEditor.setProperty('value'.selected)" selected="true"/> <mx:ComboBox id="titleFontFamilyEditor" dataProvider="{_fontNames}" x="94" y="79" width="129" change="proxy.png')"/> </mx:Canvas> <mx:Canvas id="appearance" label="Appearance" minWidth="268" minHeight="350" width="100%" height="100%"> <mx:Label x="23" y="23" text="Text" width="119"/> <mx:HRule y="28" height="10" right="28" left="56"/> <mx:CheckBox id="showTitleEditor" x="43" y="54" label="Show Title" change="proxy.text)"/> <mx:Label x="23" y="116" text="Value" width="119"/> <mx:HRule y="118" height="10" right="28" left="66"/> <mx:TextInput id="valueEditor" y="144" right="69" left="37" change="proxy.setProperty('ti tle'.

located in the SDK install folder: SDK\samples\CustomPropSheetHo rizontalSlider\CustomPropSheetHorizontalSliderPropertySheet\style\.css: <mx:Style source="style\PSStyle. then import PSStyle. add the following tags: <mx:Style /> <mx:Script> <![CDATA[ ]]> </mx:Script> 2.Task 3: Creating a CSS File Task 3: Creating a CSS File 1. These styles definitions were chosen because they closely match Dashboards property sheet styles: background color is #F4F3EE. Immediately after <mx:Application> and before <mx:ViewStack>.css"/> 11 2013-03-16 . etc. Right click on the project folder in the Navigation window and create a new folder named style. text color is black. fontFamily is Tahoma. Modify the source of <mx:Style> tag to include PSStyle. 3. This CSS definition file contains several tags that define the styles for each of them.css.

Task 3: Creating a CSS File 12 2013-03-16 .

13 2013-03-16 . [Bindable] protected var _fontSizes:Array = new Array("8". mx. 4a through 4e. In the first subtask. protected var propertyToBind:String. xcelsius.propertySheets.1 Subtask 4a: Importing classes and creating local variables Inside CData section.*. mx. "14". "11". 5. "12".binding.OutputBindings.Task 4: Handling communication between property sheet and the component Task 4: Handling communication between property sheet and the component Task 4 is divided into five subtasks. "9".controls.impl. include the following segments of code: import import import import import import import import import mx.interfaces.FlexEvent.BindingDirection. mx. "16". xcelsius. "20".binding. "10". [Bindable] private var _fontNames:Array = [].core.*.Container. xcelsius. xcelsius.tableMaps.PropertySheetFunctionNamesSDK. protected var proxy:PropertySheetExternalProxy = new PropertySheetExternalProxy(). • initiateBind(propertyName:String):void allows the user of the component to bind the Excel spreadsheet cell to an Dashboards custom component property/style. protected var currentBindingID:String.tableMaps. you will implement the following functions: • init():void initializes the property sheet on load • getPropertyBindDisplayName(propertyName:String):String returns the bind display name or null if not Bound. xcelsius.output. In the remaining subtasks.InputBindings. • continueBind(bindingID:String):void completes the binding when the user has finished selecting the cell to bind to or cleared the binding. "22"). "18".events.input. you will import classes from the Dashboards SDK framework.PropertySheetExternalProxy.binding.containers.propertySheets.

i++) { var font:Font = allFonts[i].enumerateFonts(true). and then notifies Dashboards that it has finished loading the property sheet. proxy.2 Subtask 4b: Implementing init() function The function init() sets the callback to continueBind method when the user is picking Excel cell(s) to bind to.getProperties method. then the array of values for the styles using proxy.inter faces.Task 4: Handling communication between property sheet and the component • • _fontNames will contain system fonts that the user can choose from. _fontNames. Variable proxy is the Dashboards proxy that enables communication between the property sheet and the custom component. we first get the array of values for the Dashboards custom component properties using proxy. var allFonts:Array = Font. protected function init():void { proxy. it makes a call to initValues method that initializes the property sheet on load with default property/style values.propertySheets. for (var i:int=0. 5. and either displaying that value to the corresponding control's default value or the cell address(es) if bound 14 2013-03-16 .PropertySheetExter nalProxy for the proxy is the implementation of the interface xcelsius. i<numFonts. Both of these variables need to be bindable since we bind them to the data providers of the combo boxes on the "Appearance" tab. we process through the arrays retrieving the name and value of each property and style. } 5. var numFonts:int = allFonts.addCallback(PropertySheetFunctionNamesSDK.propertySheets. this. Next. The retrieval of the list of system fonts is implemented here. } initValues().INIT_COMPLETE_FUNCTION).push(font. Refer to the API Documentation for the list of function name constants.length.IPropertySheetProxy. Lastly. allFonts. and current BindingID stores the current binding id (null if there's no binding) for the property. get Styles method.CASEINSENSITIVE).continueBind).impl. _fontSizes is the list of selectable font sizes. The package xcelsius. Variable propertyToBind stores the name of the property that the user is binding.callContainer(PropertySheetFunctionNamesSDK.fontName). which are both included in the xcelsiusframework. Both methods need a list of property or style names passed in as an array of strings. Array.swc.RESPONSE_BINDING_ID.3 Subtask 4c: Implementing initValues() function In initValues().sortOn("fontName".

var propertyValuesLength:int = (propertyValues != null ? propertyValues.selectedColor = uint(styleValue). for (var j:int=0. } break. } else if (!isNaN(styleValue)) { titleFontSizeEditor.selectedIndex = _fontSizes. } } // Process the array of values for the custom component styles. for (var i:int=0. var propertyValue:* = propertyObject.getStyles(["titleFontFamily". j < styleValuesLength. If a property has binding capability.indexOf(styleValue). switch (styleName) { case "titleFontColor": titleColorEditor.value. } else { valueEditor. break. switch (propertyName) { case "title": titleEditor. case "value": bindingText = getPropertyBindDisplayName(propertyName).name. var propertyName:String = propertyObject. var styleValuesLength:int = (styleValues != null ? styleValues.length : 0). } break.enabled = false. make use of getPropertyBindDis playName method and add an if-else statement to handle that correctly.selectedIndex = -1.indexOf(styleValue). "titleFontColor".text = styleValue.Task 4: Handling communication between property sheet and the component to the Excel spreadsheet.text = propertyValue."showTitle"]). valueEditor. case "showTitle": showTitleEditor. var styleName:String = styleObject. var styleValues:Array = proxy. } } } 15 2013-03-16 . default: break. i < propertyValuesLength.toString()). protected function initValues():void { // Process the array of values for the Xcelsius custom component properties. case "titleFontSize": titleFontSizeEditor. var bindingTextStyle:String = "". var bindingText:String = "". if (index != -1) { titleFontSizeEditor. break. i++) { var propertyObject:Object = propertyValues[i]. if (bindingText != null) { valueEditor. "value".name.text = bindingText. var index:int. index = _fontSizes.selected = Boolean(propertyValue). break. var propertyValues:Array = proxy.text = String(propertyValue).toString().selectedIndex = index. var styleValue:* = styleObject.indexOf(styleValue. "titleFont Size"]).value. break. default: break. j++) { var styleObject:Object = styleValues[j].length : 0).getProperties(["title". case "titleFontFamily": titleFontFamilyEditor. } else { titleFontSizeEditor.selectedIndex = _fontNames.

BindingDirection.getBindings([propertyName]). disabling the option to manually enter a value once the component if the property is bound. Again. if ((propertyBindings != null) && (propertyBindings. var propertyBindings:Array = proxy. return proxy. initiateBind allows the user to select the Excel spreadsheet cell(s) to bind to an Dashboards custom component property. If we have at least one binding for that property then pick the first one. } propertyToBind = propertyName. Use the function proxy. } 5. } Given a property name. InputBindings.5 Subtask 4e: Implementing continueBind function continueBind method completes the binding when the user has finished selecting the cell(s) to bind to or cleared the binding. } return null. proxy. OutputBindings. and the actual binding using proxy. 16 2013-03-16 .requestUserSelection(currentBindingID). if ((propertyBindings != null) && (propertyBindings.getBindings method.4 Subtask 4d: Implementing getPropertyBindDisplayName and initiateBind functions Given a property name. protected function getPropertyBindDisplayName(propertyName:String):String { var propertyBindings:Array = proxy.length > 0)) { var bindingID:String = propertyBindings[0][0].BOTH updates the custom component property when the spreadsheet changes and also updates the spreadsheet when the custom component changes.bind method. protected function initiateBind(propertyName:String):void { currentBindingID = null. getPropertyBindDisplayName gets the array of bindings for that property by calling proxy.getBindingDisplayName(bindingID).length > 0)) { currentBindingID = propertyBindings[0].length > 0) && (propertyBindings[0].Task 4: Handling communication between property sheet and the component 5. If there is an existing binding for that property.SINGLETON writes to a single cell in the spreadsheet. displaying the range address.SINGLETON reads a single cell in the spreadsheet. show that in the Excel binding selection window and store the currentBindingID (null if there is no current binding) in case we "continueBinding".requestUserSelection method to let the user choose where to bind to in the Excel spreadsheet.getBindings([propertyName]). we process through each property that has binding capability to do the following: filling the control with current value and set property when the user explicitly clears binding.

setProperty(propertyName.enabled = false. } valueEditor. var bindingAddresses:Array. OutputBindings.value. var propertyObject:Object. null.text = propertyObject. protected function continueBind(bindingID:String):void { var propertyName:String = propertyToBind. proxy.bind("value". refer to Appendix B in the Dashboards Component SDK SP1 User Guide. InputBindings.SINGLETON). var propertyValues:Array. BindingDirection.BOTH.unbind(currentBindingID).getBindingDisplayName(bindingID). propertyValues = proxy. propertyObject.text = proxy. return.SINGLETON. if (currentBindingID != null) { proxy. break. bindingID. propertyObject = propertyValues[0]. currentBindingID = null. valueEditor. default: break. } switch (propertyName) { case "value": if ((bindingID == null) || (bindingID == "")) { valueEditor.getProperties([propertyName]).value). 17 2013-03-16 . valueEditor. proxy.enabled = true. } } Save and build.Task 4: Handling communication between property sheet and the component For more information on bindings and the custom property sheet API.

Task 4: Handling communication between property sheet and the component 18 2013-03-16 .

Sign up to vote on this title
UsefulNot useful