The following code works in the following way:
When I enter incorrect values in the txtother.textbox and focuses out, an alert will be displayed as "Please enter a valid Format Mask." .
After pressing the "ok" button in the Alertbox the txtOther.focusout even is triggered again.
i.e. immediately after pressing the OK of alert, the same ALERT is displayed again.
I have added the code for ur reference:
//in mxml File:
<mx:Canvas label="General" >
<mx:VBox>
<mx:Canvas id="cvsGeneral">
<mx:TextInput id="txtOther" focusOut="txtOther_Validate();"/>
</mx:Canvas>
</mx:VBox>
</mx:Canvas>
<mx:Canvas width="100%" height="5%" horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:HBox width="80%" height="100%" horizontalAlign="left">
<mx:Button width="64" label="Save" id="btnSave" click="btnSave_Click();" focusIn="txtOther_Validate();"/>
</mx:HBox>
</mx:Canvas>
//Validating action script is as follows:
public function txtOther_Validate():void{
var formatMask: String = null;
if(txtOther.editable && txtOther.enabled){
if(txtOther.text != ""){
formatMask = txtOther.text;
if(conditions to validate){
//some expression
}
if(formatMask.length < 12){
Alert.show("Please enter format mask with minimum 12 digits.");
txtOther.setFocus();
return;
} VariableEditControl.getInstance().validateFormatMask(txtOther.text,validateFormatMask_Result,validateFormatMask_Fault, validateFormatMask_Error);
}
}
}
public function validateFormatMask_Result(event:PLEvent): void {
var result:String = event.getData().toString(); // here lets assume that the result variable is stored as "FAILURE"
if(result == "FAILURE"){
Alert.show("Please enter a valid Format Mask.");
txtOther.setFocus(); //
}
}
I don't want to the alert to come again and again ..
I need it in such a way that when the ok button of alert is pressed. The txtother.text should be in focus, and the alert should not come again and again as before.
it's because you have the focusIn="txtOther_Validate();" on the ok button a second time. just remove the focusIn handler and you should be fine.
I may be in error but I think the alert box won't wait till you close it. So you trigger your validate and immediately set the focus back to the input. Now you click the alert box's ok button which will make the input lose the focus triggering the validation which will raise the alert which will... and so on.
EDIT:
stage.focus = txtOther;
This will works in as3... I don't know about flex.
Related
I want to open a dialog box with some questions when I click on a column in a Flex Datagrid. After the dialog is closed, I want to fill that cell with information from the dialog.
What I have until now is this:
public function startEdit(event:DataGridEvent):void {
// event.dataField is null, so we figure it out ourselves
var column:DataGridColumn = dgQObjects.columns[event.columnIndex];
if (column.dataField == "parameters") {
// depending on the type, we can fill in parameters
var type:String = ListCollectionView(dgQObjects.dataProvider).getItemAt(event.rowIndex).type;
switch(type) {
case "Gauge":
event.preventDefault();
quartzObjects[event.rowIndex].parameters = "foo";
updateLocalStorage();
dgQObjects.validateNow();
break;
case "Indicator":
break;
case "New Row":
event.preventDefault();
break;
}
}
}
It sets the 'parameters' to 'foo', so that's good, but it doesn't show that in the datagrid (validateNow() does nothing). Also, if I put in an Alert(), the startEdit keep triggering, and I can never close the Alertbox. The grid is defined as follows:
<QuartzUI:DoubleClickDataGrid width="800" x="10" y="10" height="337"
id="dgQObjects"
editable="true"
itemEditBegin="{startEdit(event)}"
itemEditEnd="{checkQuartzObjects()}"
creationComplete="{initDataGrid()}"
>
(A DoublieClickDataGrid is a subclass of DataGrid)
You should do this through data binding on the model object. It'll make your life a lot easier. Assume the following DataGrid:
<s:DataGrid id="dg" dataProvider="{dp}"
doubleClickEnabled="true"
doubleClick="editSelectedItem()">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="name" />
</s:ArrayList>
</s:columns>
</s:DataGrid>
doubleClickEnabled is false by default, so we have to set it explicitly to be able to catch the doubleClick events. Now let's have a look at the editSelectedItem() method:
private function editSelectedItem():void {
var popup:MyEditor = new MyEditor();
popup.data = dg.selectedItem as MyClass;
PopUpManager.addPopUp(popup, this, true);
PopUpManager.centerPopUp(popup);
}
We just create a new view and pass it the currently selected datagrid item. Then we open it as a modal popup. (note that I haven't added any code to close the popup again to keep my example as simple as possible). Now the MyEditor view looks like this:
<s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:m="net.riastar.model.*"
title="Edit label"
width="400" height="300" >
<fx:Declarations>
<m:MyClass id="data" />
</fx:Declarations>
<s:TextInput text="#{data.name}" />
</s:Panel>
We use two-way data binding to edit the name property of the MyClass instance (note that this property must be marked Bindable for this to work). This is enough for a working example: if you now edit the value in the TextInput, you'll see the according value change in the DataGrid in the background.
Suppose I have an application and a global event listener in it. Should the key events, who are fired in the PopUp, be caught by that listener? Or maybe popups are not placed in that hierarchy?
Here's simplified test-code for you to understand what I'm talking about:
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
<mx:Script><![CDATA[
private function init():void {
FlexGlobals.topLevelApplication.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDownHandler);
}
private function myKeyDownHandler(event:KeyboardEvent):void {
Alert.show("It works!");
}
private function makeNewPopup():void {
var win:PopupWindow = new PopupWindow(this, new TestingForm(), true, "Popup", false);
win.showPopup();
}
]]></mx:Script>
<mx:VBox>
<mx:TextInput/>
<mx:Button label="MakePopup" click="makeNewPopup()"/>
</mx:VBox>
</mx:Canvas>
Ok, what we have .. after running the application, put the input focus into the TextInput and press any letter. The Alert will be fired. Now, press the MakePopup and do the same in it TextInput .. no any feedback from it.
Any thoughts about that?
The parent of all popups is SystemManager. So, use FlexGlobals.topLevelApplication.systemManageror stage.
I have a combobox in a view that receives information about application state changes, and then is supposed to show or hide it's children based on the whole application state.
It receives state change messages, it traces the correct values, it does what it's supposed to do, however, it just doesn't seem to work. Essentially, all it needs to do is hide a combobox during one state, and show it again during another state.
Here is the code:
public function updateState(event:* = null):void {
trace("Project Panel Updating State");
switch(ApplicationData.getSelf().currentState) {
case 'login':
this.visible = false;
break;
case 'grid':
this.visible = true;
listProjects.includeInLayout = false;
listProjects.visible = false;
trace("ListProjects: " + listProjects.visible);
listLang.visible = true;
break;
default:
break;
}
}
Here is the MXML:
<mx:HBox>
<mx:Button id="btnLoad" x="422" y="84" label="Load" enabled="true" click="loadProject();"/>
<mx:ComboBox id="listProjects"
x="652"
y="85"
editable="true"
change="listChange()"
color="#050CA8"
fontFamily="Arial" />
<mx:Label x="480" y="86" text="Language:" id="label3" fontFamily="Arial" />
<mx:ComboBox id="listLang"
x="537"
y="84"
editable="true"
dataProvider="{langList}"
color="#050CA8"
fontFamily="Arial"
width="107"
change="listLangChange(event)"/>
<mx:CheckBox x="830" y="84" label="Languages in English" id="langCheckbox" click='toggleLang()'/>
</mx:HBox>
It's not that clear form your code where and how the updateState function gets called, and to get any further into a solution I think I would need to see that. However, I think you may like to consider a different approach.
Have you tried using views instead of manually showing and hiding things and setting properties? I think you would have simpler code if you had a different view state for each of the cases in your switch, e.g. 'login' etc. Then all the showing hiding stuff becomes a design-time activity rather than run-time and all you have to do is set the current state.
If you matched your state names with your ApplicationData currentState values you may even be able to do away with the updateState function completely.
Have you tried changing
updateState(event:* = null):void
to this
updateState(event:Event = null):void
Im still looking into the event:* and everything I have found so far has Event instead of *. Will repost still looking
I have a function that restores all of the default settings of my application. This process can take a bit of time, so I would like to implement a "Please wait..." modal popup to let the user know that everything is alright and the program hasn't frozen. Once the function completes its task, I'd like for it to remove the message, and resume normal behavior.
alt text http://www.freeimagehosting.net/uploads/c5906da30c.jpg
On start:
var waitingpopup:TitleWindow = new TitleWindow()
waitingpopup.title = "Please Wait ..."
PopupManager.addPopup(waitingpopup, this, true)
On complete:
PopupManager.removePopup(waitingpopup)
As long as you don't need to convey anything to the user other than "the app is still running", I think a more elegant method would be to just change the cursor:
mx.managers.CursorManager.setBusyCursor()
//do stuff
mx.managers.CursorManager.removeBusyCursor()
The cursor will change to a clock with spinning hands. I'm not sure if there's a way to override this with your own animation, but it's simple and doesn't require you to design your own window.
You can use the PopUpManager to create a Modal PopUp with an animated spinner. The Alert component does this. You can always reference the Alert source code to see how it works.
For those arriving late to this question, Adobe released a Throbber in 4.5:
http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&loc=en_us&extid=1283019
http://fusiongrokker.com/post/using-the-flex-4-5-busyindicator
http://flexdevtips.blogspot.com/2011/05/simple-animating-preloader-and.html
For example, run the following from the fusiongrokker link above:
private function busyOn():void
{
throbberId.visible = true;
}
private function busyOff():void
{
throbberId.visible = false;
}
]]>
</fx:Script>
<s:VGroup width="100%"
paddingLeft="10"
paddingRight="10"
paddingTop="10"
paddingBottom="10">
<s:BusyIndicator
id="throbberId"
visible="false"
rotationInterval="{rotationInterval}" />
<s:Button
id="start"
click="busyOn()"
width="100%"
height="50"
label="start" />
<s:Button
id="stop"
click="busyOff()"
width="100%"
height="50"
label="stop" />
</s:VGroup>
I have text input boxes. There is validation for each of the boxes using numberValidator.
Now, the thing is that am using alert box to show if any error occurs.
Flowchart ::
1> Insert value in textBox.
2> NumberValidator validates the input on "trigger=change".
3> If error, alert message is displayed. The user clicks OK to go back to form.
4> Focus set back to the TextBox.
5> But, alert box makes the text input value blank / null. i.e. Both the previous error value entered by user and the default correct value will not be displayed now.
Goal : Display the most recent correct value that was entered in the text box. Not the default of any other, but the most recent correct value entered by the user.
can anyone help ??
Here is a complete answer. I used the "enter" event of the text box to do validation since the "change" event fires after only a single character is entered
<?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
// set last correct value to a default
private var lastCorrectValue:String="411"
function handleInvalid(event:Event)
{
Alert.show("invalid");
textInput.text=lastCorrectValue
}
function handleValid()
{
Alert.show('Validation Succeeded!')
lastCorrectValue=textInput.text
}
]]>
</mx:Script>
<mx:TextInput id="textInput"
text="{lastCorrectValue}"/>
<!-- Use the enter event of the text box to do validation. The change event fires after a single character-->
<mx:NumberValidator source="{textInput}"
property="text"
integerError="Enter Integer value"
domain="int"
trigger="{textInput}"
triggerEvent="enter"
invalid="handleInvalid(event)"
valid="handleValid();"/>
</mx:Application>
You will need to store the most recent correct answer in a variable and have the click/close handler of the alert replace the value with the stored var.
here is an example of listening for alert event:
<?xml version="1.0"?>
<!-- controls\alert\AlertEvent.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.CloseEvent;
private var lastKnownCorrectAnswer:String = "Some Answer";
private function alertListener(eventObj:CloseEvent):void {
// Check to see if the OK button was pressed.
if (eventObj.detail==Alert.OK) {
myText.text = lastKnownCorrectAnswer;
}
}
]]>
</mx:Script>
<mx:TextInput id="myAnswer"
width="150"
text="" />
<mx:Button id="myButton"
label="Copy Text"
click='Alert.show("Copy Text?", "Alert",
Alert.OK | Alert.CANCEL, this,
alertListener, null, Alert.OK);'/>
</mx:Application>
You will need to add your validation logic in there, but you get the idea. The above is from the Alert docs.
Fire a event on the Text Input FocusIn() and store whatever text value in a variable. (That would be your last correct answer). Reset the inputbox text to this value after validation... Hope I made sense :)