Adobe Flex : Popup dialog not sizing correctly - apache-flex

I have a popup dialog that is an mx:TitleWindow. The rendered height of the dialog is too large however, see the whitespace at the bottom. Decreasing the height by x pixels seems to have no effect. How do I get it to size correctly?
<mx:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="356" height="322"
layout="vertical" showCloseButton="true" close="cancel(event)"
title="Add User" creationComplete="usernameTF.setFocus();"
hasFocusableChildren="true">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.adobe.crypto.SHA1;
import com.hurlant.crypto.hash.SHA1;
import mx.controls.Alert;
import mx.events.CloseEvent;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
[Bindable]
public var mainApp:Object = null;
protected function apply_clickHandler(event:MouseEvent):void {
if (usernameTF.text == null || usernameTF.text.length < 1) {
usernameTF.errorString = "The username is mandatory";
width = 520;
return;
}
else if (mainApp.userExists(usernameTF.text)) {
usernameTF.errorString = "Username already exists";
width = 520;
return;
}
else {
usernameTF.errorString = "";
}
if (passwordTF.text == null || passwordTF.text.length < 1) {
passwordTF.errorString = "The password is mandatory";
width = 520;
return;
}
else {
passwordTF.errorString = "";
}
if (confirmTF.text == null || confirmTF.text.length < 1) {
confirmTF.errorString = "The confirmation password is mandatory";
width = 520;
return;
}
else {
confirmTF.errorString = "";
}
if (passwordTF.text != confirmTF.text) {
passwordTF.errorString = "The passwords must match";
width = 520;
return;
}
else {
passwordTF.errorString = "";
}
var u:Object = new Object();
u.username = usernameTF.text;
u.password = com.adobe.crypto.SHA1.hash(passwordTF.text);
u.accesslevel = accessLevelCB.selectedItem;
mainApp.addUserToModel(u);
mainApp.applyHandler(null);
}
protected function cancel(event:Event):void {
PopUpManager.removePopUp(this);
}
]]>
</fx:Script>
<s:Form height="280" defaultButton="{apply}">
<s:layout>
<s:FormLayout gap="{Globals.FORM_GAP}"/>
</s:layout>
<s:FormHeading label="Add User"/>
<s:FormItem label="Username:">
<s:TextInput id="usernameTF" restrict="0-9A-Za-z_." maxChars="127"/>
</s:FormItem>
<s:FormItem label="Password:">
<s:TextInput maxChars="127" id="passwordTF" displayAsPassword="true"/>
</s:FormItem>
<s:FormItem label="Confirm Password:">
<s:TextInput maxChars="127" id="confirmTF" displayAsPassword="true"/>
</s:FormItem>
<s:FormItem label="Access Level:">
<s:ComboBox id="accessLevelCB" selectedIndex="0">
<s:dataProvider>
<mx:ArrayList>
<fx:String>user</fx:String>
<fx:String>admin</fx:String>
</mx:ArrayList>
</s:dataProvider>
</s:ComboBox>
</s:FormItem>
<s:FormItem>
<s:HGroup>
<s:Button id="apply" label="Apply" click="apply_clickHandler(event)" />
<s:Spacer width="3"/>
<s:Button label="Cancel" click="cancel(event)"/>
</s:HGroup>
</s:FormItem>
</s:Form>

Decreasing the height by x pixels
Which height are you decreasing?
<mx:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="356" height="322"
layout="vertical" showCloseButton="true" close="cancel(event)"
title="Add User" creationComplete="usernameTF.setFocus();"
hasFocusableChildren="true">
<s:Form height="280" defaultButton="{apply}">
In the code you show I would expect the height of the box to be 322. The form would be 280; which leaves ~42 pixels of whitespace at the bottom.

Related

SkinnablePopUpContainer Is Visually Blocked by StageWebView in Flex

For some unknown reason, my popup AlertMsg is visually blocked by the StageWebView:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160" xmlns:local="*"
creationComplete="application1_creationCompleteHandler(event)"
backgroundColor="#112233">
<fx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
public var webView:StageWebView = new StageWebView();
public function StageWebViewExample():void
{
webView.stage = webContainer.stage;
// webView.viewPort = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight );
webView.viewPort = new Rectangle( 100, 100, 500, 500 );
}
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
webContainer.addEventListener(Event.ADDED_TO_STAGE, function(ee:Event):void {
StageWebViewExample();
});
}
protected function btnTest_clickHandler(event:MouseEvent):void
{
webView.loadURL("http://www.example.com");
new AlertMsg().open(FlexGlobals.topLevelApplication as DisplayObjectContainer, true);
}
]]>
</fx:Script>
<fx:Declarations>
<fx:Component className="AlertMsg">
<s:SkinnablePopUpContainer x="70" y="300">
<s:TitleWindow title="My Message" close="close()">
<s:VGroup horizontalAlign="center" paddingTop="8" paddingBottom="8" paddingLeft="8" paddingRight="8" gap="5" width="100%">
<s:Label text="My alert message text here..."/>
<s:Button label="OK" click="close()"/>
</s:VGroup>
</s:TitleWindow>
</s:SkinnablePopUpContainer>
</fx:Component>
</fx:Declarations>
<s:Panel id="thePanel" title="Panel" backgroundColor="blue">
<s:Button id="btnTest" label="Test"
click="btnTest_clickHandler(event)" />
<s:BorderContainer id="webContainer" y="50" width="400" height="300" />
</s:Panel>
</s:Application>
Any idea?
I absolutly agree with #www.Flextras.com, there is no another workaround than substitute WebView by its snapshot. There is a ready solution http://www.judahfrangipane.com/blog/2011/01/16/stagewebview-uicomponent/

Can not move my custom component based on HGroup

I have created a custom component based on spark.components.HGroup and it works mostly as needed, but I have this minor problem: I can not move it.
Maybe someone will look at my simplified test case below and spot my error?
Here is the screenshot of my 3 custom components, representing chat bubbles:
Here my custom component Bubble.mxml drawing black text on green background:
<?xml version="1.0" encoding="utf-8"?>
<s:HGroup
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
gap="0"
creationComplete="init(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
private static const PAD:uint = 10;
private static const BGCOLOR:uint = 0xCCFFCC;
private static const BGALPHA:Number = 0.8;
private var _timer:Timer = new Timer(600, 20);
public function init(event:FlexEvent):void {
_timer.addEventListener(TimerEvent.TIMER, fadeBubble);
_timer.addEventListener(TimerEvent.TIMER_COMPLETE, hideBubble);
addEventListener(MouseEvent.CLICK, hideBubble);
}
public function set text(str:String):void {
_text.text = str;
if (x > 100 && x < 200) {
_left.visible = true;
_right.visible = false;
} else {
_left.visible = false;
_right.visible = true;
}
visible = true;
alpha = 1.0;
_timer.reset();
_timer.start();
}
public function get text():String {
return _text.text;
}
private function fadeBubble(event:TimerEvent):void {
if (_timer.currentCount * 2 > _timer.repeatCount)
alpha /= 2;
}
// the argument could be TimerEvent or MouseEvent
public function hideBubble(event:Event):void {
visible = false;
_timer.stop();
}
]]>
</fx:Script>
<s:Graphic id="_left" visible="false">
<s:Path data="M 20 10 L 0 20 L 20 30">
<s:fill>
<s:SolidColor color="{BGCOLOR}" alpha="{BGALPHA}" />
</s:fill>
</s:Path>
</s:Graphic>
<s:Label id="_text" width="100%"
paddingTop="{PAD}" paddingBottom="{PAD}"
paddingLeft="{PAD}" paddingRight="{PAD}"
fontSize="24" textAlign="center"
backgroundColor="{BGCOLOR}" backgroundAlpha="{BGALPHA}" />
<s:Graphic id="_right" visible="false">
<s:Path data="M 0 10 L 20 20 L 0 30">
<s:fill>
<s:SolidColor color="{BGCOLOR}" alpha="{BGALPHA}" />
</s:fill>
</s:Path>
</s:Graphic>
</s:HGroup>
Here is my text application Test.mxml which uses absolute positioning:
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:comps="*"
width="700" height="525">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
private static const AVATAR:String =
'http://preferans.de/images/70x90/male_happy_70x90.png';
public static function randRange(from:int, to:int):int {
return from + Math.round((to - from) * Math.random());
}
public function chat(event:FlexEvent):void {
_bubble0.y = 340 + randRange(-20, 20);
_bubble1.y = 4 + randRange(0, 40);
_bubble2.y = 4 + randRange(0, 40);
trace('_bubble0.y = ' + _bubble0.y);
trace('_bubble1.y = ' + _bubble1.y);
trace('_bubble2.y = ' + _bubble2.y);
_bubble0.text = _chat.text;
_bubble1.text = _chat.text;
_bubble2.text = _chat.text;
_chat.text = '';
}
]]>
</fx:Script>
<s:Image id="_user0" source="{AVATAR}" horizontalCenter="20" y="340" width="160" height="140" />
<s:Image id="_user1" source="{AVATAR}" left="4" top="4" width="160" height="140" />
<s:Image id="_user2" source="{AVATAR}" right="4" top="4" width="160" height="140" />
<comps:Bubble id="_bubble0" maxWidth="200" x="20" y="340" />
<comps:Bubble id="_bubble1" maxWidth="200" left="170" top="4" />
<comps:Bubble id="_bubble2" maxWidth="200" right="170" top="4" />
<s:TextInput id="_chat" bottom="4" right="4" enter="chat(event)" text="Hello!" />
</s:Application>
In the debug console I do see the varying y coordinates:
_bubble0.y = 350
_bubble1.y = 31
_bubble2.y = 36
_bubble0.y = 340
_bubble1.y = 43
_bubble2.y = 15
but at the screen they never change!
The problem is that _bubble1 and _bubble2 are positioned with constraints (left="170" top="4"). Flex ignores the x and y properties because the constraints have a higher priority than absolute positioning with x and y.
Try removing the left="170" top="4" from both components and you'll see they change positions as expected.
Hope this helps,
Blaze

Add array to URL string

I know this questions is going to have an easy obvious answer but i have spent over two days now trying to do it with no luck (I am a Flex newbie)
Basically i am trying to open a webView that will open google maps to the location in an array
The location comes from data in an array taken from facebook events (that works fine and will display the data) but i am struggling with passing this information to the webView.loadURL string
The data i want in the array is 'data.location' (the code i am having issues with is in the itemrenderer towards the bottom of the code snippet)
I have tried so many different options i am now stuck
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="Home" creationComplete="onLoad()">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var facebookEvents:ArrayCollection;
import com.facebook.graph.FacebookMobile;
private function onLoad():void
{
if(FacebookMobile.getSession() != null) {
getEvents()
} else {
eventsDataGrid.visible=false
NotLogin.visible=true
}
}
private function getEvents():void {
var fql:String = "select name, location, pic, start_time from event where creator = 148839887036 and eid in (select eid from event_member where uid=148839887036)";
FacebookMobile.fqlQuery(fql, handleGetEventsResponse);
}
private function handleGetEventsResponse(events:Object, fail:Object):void {
if (events != null)
facebookEvents = new ArrayCollection(events as Array);
//else
//status = "Error";
}
]]>
</fx:Script>
<s:List id="eventsDataGrid" width="100%" height="100%" dataProvider="{facebookEvents}">
<s:itemRenderer>
<fx:Component>
<s:ItemRenderer>
<fx:Script>
<![CDATA[
import com.facebook.graph.utils.FacebookDataUtils;
var webView:StageWebView = new StageWebView
var mapURL:String = ('http://maps.google.com/maps?f=d&hl=en&saddr='+ "{data.location}")
private function time2DateStr(time:String):String {
return FacebookDataUtils.stringToDate(time).toLocaleString();
}
protected function getDirections_clickHandler(event:MouseEvent):void
{
webView.stage = this.stage;
webView.viewPort = new Rectangle(0, 100, stage.stageWidth, stage.stageHeight);
webView.loadURL(mapURL);
}
]]>
</fx:Script>
<s:HGroup paddingBottom="10" paddingTop="10">
<s:Image source="{data.pic}"/>
<s:VGroup width="100%">
<s:Label text="{data.name}" fontWeight="bold" width="100%"/>
<s:Label text="Where: {data.location}"/>
<s:Label text="When: {time2DateStr(data.start_time)}"/>
<s:Label text="Get Directions" click="getDirections_clickHandler(event)" id="getDirections"/>
</s:VGroup>
</s:HGroup>
</s:ItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:List>
<s:Label visible="false" x="6" id="NotLogin" width="463" height="78" styleName="text"
text="Sorry You Need To Be Logged In Via Facebook, Please Go Back and Log In, THANK YOU"/>
all i needed to do was to add the data into the brackets (dont know the offical name) here it is
protected function directions_click (location:String):void
{
navigateToURL(new URLRequest('http://maps.google.co.uk/maps?q=' + location));
}
and for the button/ label
<s:Label text="Get Directions" fontFamily="lucida grande" fontSize="14" color="#3b5998" click="directions_click(data.location)"/>

advanceddatagrid component with group and header renderer in flex

How to create advanceddatagrid component with grouprenderer and checkboxheader renderer in flex 3?
Please find my solution below:
<mx:AdvancedDataGridColumn headerText="indexed"
width="100"
dataField="indexed"
showDataTips="true"
editable="false"
headerWordWrap="true"
headerRenderer="index.DatagridCheckBoxHeaderRenderer"
sortable="false">
<mx:itemRenderer>
<fx:Component>
<mx:HBox horizontalAlign="center">
<mx:CheckBox id="indexed"
click="this.data.indexed=!this.data.indexed"
selected="{data.indexed}">
</mx:CheckBox>
</mx:HBox>
</fx:Component>
</mx:itemRenderer>
</mx:AdvancedDataGridColumn>
DatagridCheckboxHeaderRenderer.mxml:
<mx:VBox xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="100%"
height="100%"
horizontalAlign="center">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.HierarchicalData;
import mx.controls.AdvancedDataGrid;
public function checkAllDatainDatagrid(isObjectSelected:Boolean,propertyName:String):void
{
//if the header is checked,iterate thru the datagrid data
//and set all the checkbox to true
if (isObjectSelected)
{
selectAll(parentDocument.attributeList,isObjectSelected, propertyName);
}
else if(!isObjectSelected)
{
selectAll(parentDocument.attributeList,false, propertyName);
}
parentDocument.gridHierarchialData.source = parentDocument.attributeList;
}
protected function selectAll(dataCollection:ArrayCollection,isObjectSelected:Boolean, propertyName:String):ArrayCollection{
for each (var obj:Object in dataCollection)
{
if(obj.hasOwnProperty('children')){
var childCollection:ArrayCollection = obj.children;
selectAll(childCollection,isObjectSelected, propertyName)
}else if(obj.hasOwnProperty(propertyName)){
obj[propertyName]=isObjectSelected;
}
}
return dataCollection;
}
]]>
</fx:Script>
<s:Label text="Index ?"
verticalAlign="middle"/>
<mx:CheckBox id="headerComboBox"
click="checkAllDatainDatagrid(headerComboBox.selected,data.dataField);"
verticalCenter="0">
</mx:CheckBox>

Flex item renderer- don't include element if null?

I have item renderer code like this:
<s:HGroup>
<s:Label text="{data.DateTime}"/>
<s:VGroup>
<s:Label text="{data.Description}"/>
<s:Label text="{data.Amount}"/>
</s:VGroup>
</s:HGroup>
Description is an optional field.. I would like if the Description field is null for the Amount field to move up, but right now there is just an empty space. Is there any way to achieve this in mxml? I want them in separate fields because I plan to make the Description editable, but the Amount fixed.
I wrote simple application that simulates a behaviour of Item renderer.
The trick is to use visible and includeInLayout properties:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
creationComplete="application1_creationCompleteHandler(event)"
>
<fx:Script>
<![CDATA[
import mx.charts.DateTimeAxis;
import mx.events.FlexEvent;
[Bindable]
private var data:Object;
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
var newData:Object = new Object();
newData.DateTime = new Date();
newData.Description = "Description";
newData.Amount = 12345;
data = newData;
}
protected function setNull_clickHandler(event:MouseEvent):void
{
var newData:Object = new Object();
newData.DateTime = new Date();
newData.Description = null;
newData.Amount = 12345;
data = newData;
}
protected function setValue_clickHandler(event:MouseEvent):void
{
var newData:Object = new Object();
newData.DateTime = new Date();
newData.Description = "Description";
newData.Amount = 12345;
data = newData;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:VGroup>
<s:HGroup>
<s:Button id="setNull" label="Set Null" click="setNull_clickHandler(event)"/>
<s:Button id="setValue" label="Set Description" click="setValue_clickHandler(event)"/>
</s:HGroup>
<s:Label text="Renderer"/>
<s:HGroup>
<s:Label text="{data.DateTime}"/>
<s:VGroup>
<s:Label text="{data.Description}"
visible="{data.Description != null}"
includeInLayout="{data.Description != null}"
/>
<s:Label text="{data.Amount}" />
</s:VGroup>
</s:HGroup>
</s:VGroup>
</s:Application>

Resources