I am working on a product options form whose contents should be cleared by a clearOptions() method each time the user adds an option. The option name TextInput is bound to a value object that is reinstantiated each time the the user adds a product option. The problem I am having is that the StringValidator fires each time the bound value object is reinstantiated.
<mx:StringValidator id="valOptionName" minLength="1" source="{txtOptionName}" property="text" trigger="{btnAddChangeOption}" triggerEvent="click"/>
<mx:TextInput id="txtOptionName" width="120" text="{currentProductOption.name}"/>
<mx:LinkButton id="btnAddChangeOption" label="Add/Change Option" click="saveUpdateOption(event)" horizontalCenter="0"/>
The following code is what causes the StringValidator to fire when it shouldn't. It results in a red outline around a text box.
private function clearOptions():void
{
currentProductOption = new ProductOptionVO();
}
Thank you for any help,
Orville
I solved the problem by setting the source of the validator manually in the validation code and then switching it off before currentProductOption is reinstantiated.
Related
I am trying to make flex autocomplete change its dataprovider at runtime based on user input.
<components:AutoComplete change="change()" id="ac" dataProvider="{_a1}" width="100" />
<s:Button label="change" click="change()" />
private function change():void
{
Alert.show("sdsd");
//Alert.show(event.text);
//ac.dataProvider = _a2;
}
when I click the button, the function get fired, but when i input the text, it doesnt fire.
I was trying to use both change and textEvent, however, none of them are fired.
I wonder if there is any way that i can do this?
Thanks in advance.
When I click a row in the datagrid, the "PeopleDetails" state is loaded. On the details state, I have a checkbox. This checkbox was automatically generated when I created the form. This is because the field in the People table is Boolean.
I actually do not want to have a checkbox, but I want the value Yes/No printed next to the label.
So I write some AS code embedded in the MXML code:
<s:Form includeIn="PeopleDetails">
<s:FormItem label="Is Present?">
<fx:Script>
<![CDATA[
if(person!= null ){
if(person.present==true){
Alert.show("Test - Yes");
}
}
else{
Alert.show("No");
}
]]>
</fx:Script>
<s:CheckBox id="personCheckBox2" enabled="false" selected="{person.present}"/>
</s:FormItem>
</s:Form>
Just for testing purposes, I have Alert popups. Eventually, I would change to printing to screen the values Yes/No.
The problem:
-I do not know how to test whether the attribute present in the object person is true or false.
In the above, I get a FB complaint 1120: Access of Undefined property person.
If I remove the AS code, the checkbox works fine. The checkbox uses person.present to know whether it should be checked or not. Why cannot I use person.present to do the if-else test?
I would appreciate any help on this.
If I'm reading you right, you want a Yes/No value rather than a checkbox, this should do it for you:
Change :
<s:CheckBox id="personCheckBox2" enabled="false" selected="{person.present}"/>
To :
<s:Label text="{(person.present)?'Yes':'No'}"/>
So the new form looks like this :
<s:Form includeIn="PeopleDetails">
<s:FormItem label="Is Present?">
<s:Label text="{(person.present)?'Yes':'No'}"/>
</s:FormItem>
</s:Form>
You can't place ActionScript code on a script manner within Script tag. You can only place properties and methods there following OOP way. So put your code inside a method and call this method as a reaction on some event (creationComplete for example).
I hope the above code is part of an ItemRenderer.
Just move the above Script block code to set data() function as below:
override public function set data( value: Object ): void
{
super.data = value;
if(person != null ){
if(person.present==true){
Alert.show("Test - Yes");
}
}
else{
Alert.show("No");
}
}
Also, I don't think Alert will work in Itemrenderer, so replace it with trace("") statement. Hope it helped.
How to remove validation programmatically from flex component
This is my method
public static function validateRequired(txt:TextInput, errorMessage:String="This field is required"):Boolean
{
var v:Validator = new Validator();
v.listener = txt;
var result:ValidationResultEvent = v.validate(txt.text);
var returnResult:Boolean = (result.type == ValidationResultEvent.VALID);
//Alert.show("validation result is " + returnResult);
if (!returnResult) {
v.requiredFieldError = errorMessage;
}
return returnResult;
}
But, as each time i am creating new validator, so pop-up contains multiple messages like
This field is required.
This field is required.
How to remove error messages attached with component?
I had the same problem, I understood that i had to clear the last validation before the next one.
private function resetValidationWarnings():void {
for each (var validator:Validator in arrValidators) {
validator.dispatchEvent(new ValidationResultEvent(ValidationResultEvent.VALID));
}
}
this is a kinda POG but it got the job done!
hope it helps !
The Validator.enabled property lets you enable and disable a validator. When the value of the enabled property is true, the validator is enabled; when the value is false, the validator is disabled. When a validator is disabled, it dispatches no events, and the validate() method returns null.
For example, you can set the enabled property by using data binding, as the following code shows:
<?xml version="1.0"?>
<!-- validators\EnableVal.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:ZipCodeValidator id="zcVal"
source="{inputA}"
property="text"
required="true"
enabled="{enableV.selected}"/>
<mx:TextInput id="inputA"/>
<mx:TextInput/>
<mx:CheckBox id="enableV"
label="Validate input?"/>
</mx:Application>
I also encountered similar problem. In my case, the root cause is I created the validator object every time the validation is called (just as you did). As a result, the UIComponent see it as different validator object (see UIComponent.errorObjectArray) and stored the error message again. The solution is to have a global or static validator and it solves the duplicate error message for me.
I have various (read lots of..) flex forms in my app, and I now want to create a system by which the user is notified that he hasn't saved if he modifies anything in the form...
now.. I don't want to rewrite every form I have.. is there some nice way to implement this?
Extending the TextInput (and others..) classes somehow?
thanks
This is not really thought through but should work.
You could create a custom component, let's call it FormWatcher which you would than put next to your Form. What the form watcher would do is wait for the CreationComplete event from the form.
So now, as we have the Form ready you can use the getChildren() method of the form to get all the FormItems in it. Than look inside each of them, and you will get TextInputs, Comboboxes, etc. to which you can add event listeners (as individual components), eg.
// THIS IS WHERE THE COMPONENT SHOULD START
protected function changeHandler(event:Event):void
{
trace ("something is dirty");
}
protected function startWatching(passTheFormHere:Form):void
{
for each (var O:Object in passTheFormHere.getChildren())
{
if (O is FormItem)
{
// Let's assume you only have a single child in one FormItem
// and always one child for simplicity
addChangeHandlerFor((O as FormItem).getChildAt(0));
}
}
}
protected function addChangeHandlerFor(someComponent:Object):void
{
// Most regular flex components send a Event.CHANGE event
// when their value is changing
// keep in mind you should check stuff, this is a simple example
(someComponent).addEventListener(Event.CHANGE,changeHandler);
}
// THIS IS WHERE THE COMPONENT SHOULD END
Just paste this code next to some form, and call the startWatching(nameOfYourForm), you should see the changeHandler is being called.
A few more notes:
1) You should clean up the event listeners once you're done.
2) I would create a component out of it so that you would use it like this:
<mx:Form id="form1" >
[...]
</mx:Form>
<FormWatcher form="{form1}" />
Where FormWatcher would have a Boolean var called "clean" or something.
3) The example is very simple, so it will only work for forms similiar to this one:
<mx:Form id="myForm" >
<mx:FormItem>
<mx:TextInput id="someComponent1" />
</mx:FormItem>
<mx:FormItem>
<mx:CheckBox id="someComponent2" />
</mx:FormItem>
<mx:FormItem>
<mx:TextArea id="someComponent3" />
</mx:FormItem>
</mx:Form>
You could go into the TextInput class (and others) and add that event listener and function, but then you would be changing the SDK itself, which is kind of a bad idea. I would create custom classes extending the ones your using and do a find/replace to make it faster.
Say I have a phone-number validator in flex and I have two TextInput controls for phone numbers. I don't want to have two separate validator controls defined that have essentially the same attributes... but each validator has only one "source" attribute. How can I use the same validator on multiple control? (or any equivalent solution)
Not inline, but you can perform the validation programmatically, say, on submission of a form, or when a user tabs out of a control, etc. Here's an example using a single PhoneNumberValidator to validate two form fields; the validation happens when the Submit button gets clicked:
<mx:Script>
<![CDATA[
private function validatePhoneNumber(txt:TextInput):void
{
v.listener = txt;
v.validate(txt.text);
}
private function btn_click():void
{
validatePhoneNumber(p1);
validatePhoneNumber(p2);
}
]]>
</mx:Script>
<mx:PhoneNumberValidator id="v" allowedFormatChars="()- .+" property="text" requiredFieldError="Required." wrongLengthError="Invalid length." invalidCharError="Invalid character." />
<mx:Form>
<mx:FormItem label="Phone Number 1">
<mx:TextInput id="p1" />
</mx:FormItem>
<mx:FormItem label="Phone Number 2">
<mx:TextInput id="p2" />
</mx:FormItem>
<mx:FormItem>
<mx:Button id="btn" label="Submit" click="btn_click()" />
</mx:FormItem>
</mx:Form>
Hope it helps!
Steps to reproduce:
TextInput creates dynamically
textInputBox = new MyTextInput;
textInputBox.restrict = “0-9.”;
textInputBox.maxChars = 24;
amountValidator = new NumberValidator();
amountValidator.source = textInputBox;
amountValidator.property = “text”;
amountValidator.allowNegative = false;
amountValidator.domain = “real”;
amountValidator.precision = 4;
amountValidator.required = false;
amountValidator.maxValue = 999999999999.9999;
amountValidator.trigger = textInputBox;
amountValidator.triggerEvent = Event.CHANGE;
amountValidator.addEventListener(ValidationResultEvent.VALID, amountValid);
amountValidator.addEventListener(ValidationResultEvent.INVALID, amountInvalid);
private function amountValid(event:ValidationResultEvent):void
{
valid = true;
fieldsValidated = true;
}
private function amountInvalid(event:ValidationResultEvent):void
{
valid = false;
fieldsValidated = true;
}
As mention in the creation, when we exceed the limit, it shows error my red color border, and the same time if you delete them by DEL key when it come to the given acceptable limit, automatically become to green soon.
Leave from the field and change values of another textinput(this is just a textinput, this is a form there are some more form elemets), then come back to value exceeded textfield by SHIFT+TABS and remove the additional entered numbers, when you come to green soon your value is accepted.
Now again enter more values and now you are in the warn zone, then leave from the field and do the few changes in other form elements.
Then come back to the value exceeded text filed by MOUSE CLICK, and start delete from DEL, even though you removed additional values, still fields shows that you are in warn zone.
Actual Results:
Even when remove additional numbers,still field is Red
Expected Results:
if remove additional numbers, field should come its normal status.
Picture of this issue can be viewed at View Screen Shot