I use validators in my flex mobile application.
I want to remove the red border when validator has triggered an error.
<mx:EmailValidator id="emailV" source="{login_txt}" property="text" triggerEvent="click" trigger="{connexion_btn}" />
<mx:StringValidator id="passwordV" source="{password_txt}" property="text" trigger="{connexion_btn}" triggerEvent="click" />
I tried:
target.errorString = null; // not good
Any clue ?
Usually I would set the errorString to an empty string; and I do that on the instance of the component with the red string on it. I believe in that case, it would be your trigger component:
login_txt.errorString = '';
password_txt.errorString = '';
I'm unclear based on the limited code provided if the target you are setting the errorString on will be the same as the actual component specified as the validator source. It could be, we just aren't provided enough information to know for sure.
The red glow is defined in spark.skins.spark.ErrorSkin, which is the default value of a UIComponent's errorSkin property. You can't set this property to null, but you can extend the ErrorSkin class and override the methods that generate the glow (namely, updateDisplayList and processBitmap).
I created a NullFocusSkin that I use to remove the red error glow and the blue focus glow. I set the component's errorSkin and focusSkin properties to that and hey presto - no more nasty glow, and no need to manually clear the errorString!
import spark.skins.spark.HighlightBitmapCaptureSkin;
public class NullFocusSkin extends HighlightBitmapCaptureSkin
{
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
// Do nothing.
}
override protected function processBitmap():void
{
// Do nothing.
}
}
Besides setting the error string to empty, I had to call showFocus(), or the red border wouldn't go away.
login.errorString = '';
login.focusManager.showFocus();
Related
I am using a SuggestBox in GWT.I also inherit the Standard theme from SuggestionBox.gwt.xml as
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
so this are using default standard css for widget Suggestbox and it is making border through image as hborder.png,vborder.png etc..I want to remove this but my css is not working.
.gwt-SuggestBoxPopup{
border : 1px solid #000000;
}
so how can i solve this issue.Please help me.
Thanks Rahul
The class used for the popup is a DefaultSuggestionDisplay for default SuggestBox. It uses a DecoratedPopupPanel as you can see in SuggestBox.java around line 392.
To avoid "heavy" border, you have to create/override a SuggestionDisplay that uses a non-decorated popupPanel and pass it to your SuggestBox trough constructor
public SuggestBox(SuggestOracle oracle, TextBoxBase box,SuggestionDisplay suggestDisplay);
Say, "border" is not sufficient, because DecoratedPopupPanel uses multiple cells to set borders, as you seen in the CSS. So you probably can update CSS directly but it will apply to all project, as SuggestBox does not seems to handle resource bundle directly.
Create a customSuggestionDisplay class
public static class CustomSuggestionDisplay extends SuggestBox.DefaultSuggestionDisplay {
private PopupPanel suggestionPopupRef;
public CustomSuggestionDisplay() {
suggestionPopupRef = getPopupPanel();
}
public void removeBorder() {
((Element)suggestionPopupRef.getElement().getChild(0)).getStyle().setBackgroundColor("white");
NodeList<com.google.gwt.dom.client.Element> tdList = suggestionPopupRef.getElement().getElementsByTagName("td");
for (int tdIndex = 0; tdIndex < tdList.getLength(); ++tdIndex) {
Element tdElement = (Element) tdList.getItem(tdIndex);
if (tdElement.getClassName().startsWith("suggestPopup"))
tdElement.removeClassName(tdElement.getClassName());
}
}
}
Create a suggestBox object
SuggestOracle oracle = new RestSuggestOracle();
CustomSuggestionDisplay suggestionDisplay = new CustomSuggestionDisplay();
TextBox textfield = new TextBox();
SuggestBox m_field = new SuggestBox(oracle, textfield, suggestionDisplay);
Call removeBorder when the suggestion is displaying
if (m_field.isSuggestionListShowing())
suggestionDisplay.removeBorder();
according the documentation borderThickness is an applicable style, but when I try to set it to anything (would prefer '0') it says "The style 'borderThickness' is excluded by type 'mx.controls.DateField'."
I could style the background color to be the same as the background, but I have an image behind so this will not work.
There must be some way to remove this border!?
There is a protected property in the DateField named textInput. You can override the DateField class and set style 'borderStyle' of the textInput, which is of type TextInput, to 'none'. Example:
.
public class ExtendedDateField extends DateField {
override protected function createChildren():void{
super();
textInput.setStyle('borderStyle','none');
}
}
I've managed to style my QLineEdit to something like this:
alt text http://www.kimag.es/share/54278758.png
void Utilities::setFormErrorStyle(QLineEdit *lineEdit)
{
lineEdit->setStyleSheet(
"background-color: #FF8A8A;"
"background-image: url(:/resources/warning.png);"
"background-position: right center;"
"background-repeat: no-repeat;"
"");
}
I called the function using
Utilities *util = new Utilities;
util->setFormErrorStyle(lineNoStaf);
The flow should be something like this:
User open form
User fill data
User submit data
Got error
Use setFormErrorStyle()
User edit the text in the QLineEdit and the style disappear
This function should be reusable over and over again, but how can I connect QLineEdit signal such as textChanged() to a function in other class that will reset the Style Sheet and then disconnect the signal so that it won't be running continuously every time the text changed ?
Qt also allows dynamic properties in its stylesheet, that means you don't need to code your own class for every widget type in your form.
From http://qt-project.org/doc/qt-4.8/stylesheet-examples.html
Customizing Using Dynamic Properties
There are many situations where we need to present a form that has mandatory fields. To indicate to the user that the field is mandatory, one effective (albeit esthetically dubious) solution is to use yellow as the background color for those fields. It turns out this is very easy to implement using Qt Style Sheets. First, we would use the following application-wide style sheet:
*[mandatoryField="true"] { background-color: yellow }
This means that every widget whose mandatoryField Qt property is set to true would have a yellow background.
Then, for each mandatory field widget, we would simply create a mandatoryField property on the fly and set it to true. For example:
QLineEdit *nameEdit = new QLineEdit(this);
nameEdit->setProperty("mandatoryField", true);
QLineEdit *emailEdit = new QLineEdit(this);
emailEdit->setProperty("mandatoryField", true);
QSpinBox *ageSpinBox = new QSpinBox(this);
ageSpinBox->setProperty("mandatoryField", true);
Works also in Qt 4.3!
Allright, this is not compile but should work in principle, you should be able to change the look by calling editWidget->setProperty('isError',true) or editWidget->setError(false)
class ErrorTextEdit : QLineEdit
{
Q_OBJECT
QPROPERTY(bool isError, READ isError, WRITE setError);
public:
ErrorTextEdit(QWidget* parent) : QLineEdit(parent), m_isError(false)
{
m_styleSheet = "" // see below
setStyleSheet(m_styleSheet);
}
void setError(bool val)
{
if (val != m_isError)
{
m_isError = val;
setStyleSheet(m_styleSheet);
}
}
bool isError() {return m_isError;}
private:
QString m_styleSheet;
bool m_isError;
}
for the stylesheet
ErrorTextEdit[isError="false"]
{
optional ...
Style for textedit that is NOT an error
}
ErrorTextEdit[isError="true"]
{
background-color: #FF8A8A;
background-image: url(:/resources/warning.png);
background-position: right center;
background-repeat: no-repeat;
}
the term
[<property>="<value>"]
restricts the application of the stylesheet to instances of the class whose <property> has the appropriate <value> the only caveat is that the style is not changed when the property changes its' value, so the stylesheet has to be reapplied for the look of the widget to actually change, see Stylesheet Documentation -> Property Selector
This construction moves the stylesheet into the widget that uses it and makes switch internal to the widget, the widget changes in accordance to its state.
In general you have a couple of ways to handle invalid inputs in your form
a) observe every change and update the style appropriately, you should be able to use QValidator for that too, but that is a separate topic, using QValidator you will probably be able to completely internalize the state of a single QTextEdit and not have to deal with its validity from the outside
b) Do it in the submit loop that you have described above, whenever the user clicks on submit change the state of the correct and incorrect fields
it all depends the structure of your app and the view
See, the other idea is you need to override the paint evet of line edit and then set the background image and color.
here the implimentation is presetn here button, follow up the same to your line edit
The examples I've seen seem to show how to change the color that shows when the user actually hovers over the textinput field.
However when the validation fails, a generic textInput border qill have a red line over it. My CSS file uses a border skin for the textInput, so I can't see this line.
I was hoping there was a way to highlight the text box when it failed validation, or re-enable the red line feature. I don't want to get rid of my CSS cos it'll totally blow my color-scheme, but any tweak allowing the error line to show would be much appreciated.
This is the CSS:
TextInput, TextArea
{
border-skin: Embed(source='/../assets/images/input_bg.png', scaleGridLeft=8, scaleGridRight=20, scaleGridTop=8,scaleGridBottom=9);
padding-top:2;
padding-left:2;
font-size:11;
}
anything that extends UIComponent (both TextInput and TextArea do) has a style called errorColor. It defaults to red. You can change this to whatever you want.
Additionally, if you've got an image that you are using as a border, you should probably remove the pixels from the middle so that it is an actual border instead of an overlay.
The only way I've managed to find, is that Validator will change the component's borderColor style. I don't think it can be achieved using an image- you'll have to embed the image in a basic GraphicRectangularBorder subclass or similar. You can then add this to your skin class:
override public function styleChanged(styleProp:String):void
{
super.styleChanged(styleProp);
if (styleProp == "borderColor")
{
if (getStyle("borderColor") == getStyle("errorColor"))
{
// show error outline
}
else
{
// hide error outline
}
}
}
I want to make a label that has a tiny title above it, for example so the label say $1,000 with a small retail price or our price above it. I am trying to add the title label to the display list of the main label. I get no error but the title does not show up. I also considered rawChildren but apparently Label has no rawChildren property.
Here is my code:
package
{
import mx.controls.Label;
public class PriceLabel extends StrikeThroughLabel //<-- exntension of label to add strike
{
private var _title:Label;
public function PriceLabel()
{
super();
}
[Bindable]
public function set title(s:String):void
{
if(_title == null)
{
_title = new Label();
addChild(_title);
this.alpha = .2;
}
_title.text = s;
}
public function get title():String
{
var s:String
if(_title != null)
{
s = _title.text;
}
return s;
}
}
}
If you add children to a Flex component that is not a container, then you have to manually manage sizing and positioning of those children. Containers do a lot of that work for you.
Here's what you should do:
Move the creation of your child Label into an override of the createChildren() function.
Set the text property of the child label in an override of the commitProperties() function. Your title getter and setter should save the value in a _title variable to be used later for the assignment in commitProperties(). This is actually important for performance.
Override the measure() function and update measuredWidth and measuredHeight to be the maximum width and height values of the main label and it's child.
Override updateDisplayList() and use setActualSize() on the child Label to set it to the required width and height.
That may seem like a lot of work, but in terms of best practices, that's the way you're supposed to build custom components. The Flex Team at Adobe spent a lot of time maximizing performance, and that's why things happen in several steps like that.
That's how to do it based on what you asked. Personally, I would make a subclass of UIComponent with two Labels or UITextFields as children, each with their own separate property.
By the way, the rawChildren property is only available on containers. It exists so that you can add "chrome" to a container that isn't part of the container's child layout algorithm. For example, Panel has a title bar and a border that aren't affected by the vertical/horizontal/absolute layout options.
Why not create a custom component that contains both labels as its children, instead of trying to throw a child on the Label? That feels cleaner to me, as adding children to build-in components like that doesn't seem right.