If you have a DateChooser control next to a text control and you left click your mouse to select the text then continue holding down the mouse button and letting the mouse button up while over the datechooser control, the selectedDate value changes to the date you are hovering over. I have users that are having issues with this and it happens unintentionally because of the proximity of the two controls. I cannot find a way to stop this effect. Basically I would want the selectedDate to only change if the user actually clicks the calendar control ie. mouseDown or click. Calling functions in those events do not change this behavior. I need a way to disable the control from changing the date on the mouseUpEvent (I think).
That's an irritating bug because you cannot cancel events on the DateChooser. Here is a possible solution:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600">
<mx:Script>
<![CDATA[
private function preventDateChooserBug(e:MouseEvent):void {
//set the mouseChildren property to false, not enabled because
//that could cause an irritating flickering when clicking the
//text input box for focus
dtc.mouseChildren = false;
//add the event listener to stage so we get the mouse up event even
//outside of the text input control
stage.addEventListener(MouseEvent.MOUSE_UP, function(e2:MouseEvent):void {
dtc.mouseChildren = true;
});
}
]]>
</mx:Script>
<mx:TextInput x="10" y="10" id="txt" mouseDown="preventDateChooserBug(event)" />
<mx:DateChooser x="178" y="10" id="dtc" />
</mx:Application>
Related
I have an AdvancedDataGrid with two columns that have item renderers. Those item renderers are rendering link buttons in their respective columns. I want to be able to click on those link buttons without triggering the itemClick event of the AdvancedDataGrid. Any suggestions for how I could accomplish this?
I've never worked with an AdvancedDataGrid but I assume a few principles hold. The first being the behavior of event propagation. The event gets processed by the button before it gets processed by the grid. This means that we can catch and stop the event from ever reaching the DataGrid. Below is a code sample demonstrating how a DataGrid renderer can have a Button without triggering other behavior.
CustomerRenderer...
<fx:Script>
<![CDATA[
protected function watchButtonClickHandler(event:MouseEvent):void
{
//the line below stops the event from
//propagating through the rest of the display
//list
event.stopImmediatePropagation();
//handle button click logic here
}
]]>
</fx:Script>
<s:Group width="100%" id="buttonGroup">
<s:layout>
<s:HorizontalLayout horizontalAlign="center" verticalAlign="middle"
paddingBottom="1" paddingLeft="1"
paddingRight="1" paddingTop="1" />
</s:layout>
<s:Button id="watchButton" width="98" label="{buttonLabel}"
click="watchButtonClickHandler(event)"/>
</s:Group>
....
I want to add a button with a cross to the header of the accordion which can be clickable. that means i want to display a message when the some one click on that button. i go through many of the samples in the web but couldn't get it done. if any one who knows do this in flex4 it will very helpful.
I tried with also a CanvasButtonAccordionHeader, it shows the button but when i click it, it didn't give the message although i created the click event handler.
if somebody know how to resolve this please describe it with a simple source code.
thanx.
You can easily do that by customizing the header in CSS.
Add the header Style to you accordion.
<mx:Accordion id="accordion"
headerStyleName="accHeader"
width="100%" />
In your CSS
.accHeader {
fillColors: haloSilver, haloBlue;
fillAlphas: 1.0, 0.5;
selectedFillColors: black, black;
}
Or embed your image in here.
You can place that message in your ViewStack.
I use the CanvasButtonAccordionHeader in Flex 3, so not sure if this will work in Flex 4.
But.... in case it's of any use, I create my CanvasButtonAccordianHeader as a custom componant which dispatches an event when the button is clicked:
<CanvasButtonAccordionHeader xmlns="flexlib.containers.accordionClasses.*"
xmlns:mx="http://www.adobe.com/2006/mxml" mouseChildren="true"
<mx:Script>
<![CDATA[
[Bindable]
private var itemName:String;
public function init():void{
itemName=data.name;
}
]]>
</mx:Script>
<mx:Metadata>
[Event(name="homeButtonClicked")]
</mx:Metadata>
<mx:HBox width="100%" horizontalAlign="right" height="100%"
paddingRight="5"
verticalAlign="middle">
<mx:LinkButton label="<>"
click="dispatchEvent(new Event('homeButtonClicked'));"
/>
</mx:HBox>
</CanvasButtonAccordionHeader>
Then I instantiate the custom componant at the bottom of the Accordian as a Header Renderer:
............................................
<mx:headerRenderer>
<mx:Component>
<applicationLayout:AccordionNavHeaderRenderer
homeButtonClicked="outerDocument.dispatchEvent(new Event('homeClick'))"/>
</mx:Component>
</mx:headerRenderer>
</mx:Accordion>
Hope this is of use.
I am having a problem with a checkbox in my datagrid. It pulls in a dataprovider (xml file) and I am using it to set the checkbox selection with a custom itemrenderer. I then save the datagrid, when updated, back to the xml file.
The checkbox, when clicked, saves to the xml fine.. I know this because when I reload the application it shows the correct result. However, when I just refresh the dataprovider without closing out the flex application then the checkboxes revert back to what they were before the change.
So here is the custom checkbox:
<?xml version="1.0" encoding="utf-8"?>
<mx:CheckBox xmlns:mx="http://www.adobe.com/2006/mxml" >
<mx:Script>
<![CDATA[
override public function set data( value:Object ):void{
super.data = value;
trace("data = " + data.#hidden);
if(data.#hidden == "true")
{
this.selected = true;
}else
{
this.selected = false;
}
}
]]>
</mx:Script>
</mx:CheckBox>
And here is where I am calling it:
<mx:DataGridColumn width="75" headerText="hide?" dataField="#hidden">
<mx:itemRenderer>
<mx:Component>
<local:itemRendCheckBox />
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
I imagine what is happening is that everything is updating except the custome itemrenderer. Is there something I can do to tell the checkbox to refresh with the dataprovider?
I think I figured it out, I was calling the datagrid to refresh, which is different then refreshing the actual dataprovider. So instead of myDataGrid.send() I called dataProv.dataprovider.refresh();
I have a textArea and a Button - I want the Button to disappear when the user clicks anywhere in the app window EXCEPT the "Send" button
<mx:Button x="306" y="168" label="Button" id="btn" click="Alert.show('Button clicked')"/>
<mx:TextArea x="138" y="146" focusOut="btn.visible=false" focusIn="btn.visible=true"/>
I tried calling btn.visible=false when TextArea loses focus (using focusOut event) - if I click anywhere in the app it works, but it also works when I click the Button - the TextArea focusOut event is processed first and the click for the button later - can someone please help out with this?
Thanks!
were u trying to override the default focusOut handler? That doesn't work...
private function setBtnNotVisible():void
{
btn.visible=false;
}
override protected function focusOutHandler(event:FocusEvent):void
{
callLater(setBtnNotVisible);
}
Neither does writing my own event handler...
private function setBtnNotVisible():void
{
btn.visible=false;
}
private function focusOutHandler2(event:FocusEvent):void
{
callLater(setBtnNotVisible);
}
--------------------- Full Code ------------------
##### Try clicking INSIDE the textArea and then on the button, I cannot catch the Alert
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
private function onFocusOut(event:FocusEvent):void{
callLater(
function ():void{
btn.visible=false;
}
)
}
]]>
</mx:Script>
<mx:Button x="306" y="168" label="Button" id="btn" click="Alert.show('Button clicked')"/>
<mx:TextArea x="138" y="146" focusOut="onFocusOut(event)" focusIn="btn.visible=true"/>
</mx:Application>
I previously said use call later, but on testing it doesn't work, sorry for wasting anyone's time. Instead you need to use the focus manager something like this: I tested this and it seems solid.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.managers.FocusManager; //pull in the manager
private function onFocusOut(event:FocusEvent):void{
if(getFocus() != null){ //in case focus goes outside the flash player
if(getFocus().name == "btn"){ //the focus went to the item with the ID "btn"
return; //do nothing, let the click handler work
}else{ //any other item gets focus
btn.visible=false; //disappear
}
}
}
private function clickHandler():void{ // made it it's own function so do more than just alert
Alert.show('Button clicked');
btn.visible=false;
}
]]>
</mx:Script>
<mx:Button x="306" y="168" label="Button" id="btn" click="clickHandler();"/>
<mx:TextArea x="138" y="146" focusOut="onFocusOut(event)" focusIn="btn.visible=true"/>
</mx:Application>
I have a Flex application where I'm using a Canvas to contain several other components. On that Canvas there is a Button which is used to invoke a particular flow through the system. Clicking anywhere else on the Canvas should cause cause a details pane to appear showing more information about the record represented by this control.
The problem I'm having is that because the button sits inside the Canvas any time the user clicks the Button the click event is fired on both the Button and the Canvas. Is there any way to avoid having the click event fired on the Canvas object if the user clicks on an area covered up by another component?
I've created a simple little test application to demonstrate the problem:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
private function onCanvasClick(event:Event):void {
text.text = text.text + "\n" + "Canvas Clicked";
}
private function onButtonClick(event:Event):void {
text.text = text.text + "\n" + "Button Clicked";
}
]]>
</mx:Script>
<mx:Canvas x="97" y="91" width="200" height="200" backgroundColor="red" click="onCanvasClick(event)">
<mx:Button x="67" y="88" label="Button" click="onButtonClick(event)"/>
</mx:Canvas>
<mx:Text id="text" x="97" y="330" text="Text" width="200" height="129"/>
</mx:Application>
As it stands when you click the button you will see two entries made in the text box, "Button Clicked" followed by "Canvas Clicked" even though the mouse was clicked only once.
I'd like to find a way that I could avoid having the second entry made such that when I click the Button only the "Button Clicked" entry is made, but if I were to click anywhere else in the Canvas the "Canvas Clicked" entry would still appear.
The event continues on because event.bubbles is set to true. This means everything in the display heirarchy gets the event. To stop the event from continuing, you call
event.stopImmediatePropagation()
Laplie's answer worked like a charm. For those interested the updated code looks like this:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
private function onCanvasClick(event:Event):void {
text.text = text.text + "\n" + "Canvas Clicked";
}
private function onButtonClick(event:Event):void {
text.text = text.text + "\n" + "Button Clicked";
event.stopImmediatePropagation();
}
]]>
</mx:Script>
<mx:Canvas x="97" y="91" width="200" height="200" backgroundColor="red" click="onCanvasClick(event)">
<mx:Button x="67" y="88" label="Button" click="onButtonClick(event)"/>
</mx:Canvas>
<mx:Text id="text" x="97" y="330" text="Text" width="200" height="129"/>
</mx:Application>
The only difference is the one additional line in the onButtonClick method.
I have 2 ideas, first try this:
btn.addEventListener(MouseEvent.Click,function(event:MouseEvent):void{
event.stopImmediatePropagation();
...
});
if that doesn't work, see if you can add the click listener to the canvas and not the button and check the target property on the event object. something like:
btn.addEventListener(MouseEvent.Click,function(event:MouseEvent):void{
if(event.target == btn){
...
}
else{
...
}
});
Again, these are some ideas of the top of my head...I'll create a small test app and see if these work...