Apache – Change the character in the TextInput in password mode

apache-flex

I was just curious about the password mode display of the TextInput control in flex. The control displays asterisks instead of the characters themselves when the 'displayAsPassword' is set to true. Quoting the documentation,

displayAsPassword
If true, the field does not display entered text, instead, each text character entered into the control appears as the character "*".

So, is there any way to change this displayed character, unless of course creating a custom component or extending the existing TextInput control?

Thank you very much.

Best Answer

Just a way to resolve


For Flex 4.6

Create a new skin based on TextInput component, "skin_password" or something like that:

New MXML Skin

Now, inside the skin, search for this (with some editors you can press CTRL+O, write textDisplay and press ENTER):

<s:RichEditableText id="textDisplay" left="1" right="1" top="1" bottom="1"
                    verticalAlign="middle" widthInChars="12"
                    left.normal="1" right.normal="1" top.normal="1" bottom.normal="1"/>

Add the property displayAsPassword=true:

<s:RichEditableText id="textDisplay" left="1" right="1" top="1" bottom="1"
                    displayAsPassword="true" verticalAlign="middle" widthInChars="12"
                    left.normal="1" right.normal="1" top.normal="1" bottom.normal="1"/>

Search for this method:

override protected function initializationComplete():void
    {
        useChromeColor = true;
        super.initializationComplete();
    }

Append this line (in my case, a black dot ● instead of the default asterisk *):

textDisplay.mx_internal::passwordChar = "●";

Now, just set the skinClass attribute to your TextInput component (my skin example is in the package skins):

<s:TextInput id="tiPassword" height="30" maxChars="12" skinClass="skins.skin_password" />

And now you have something like this: see working

-

-

A little more of explanation


When you set displayAsPassword to true, Flex add the textFlow to the RichEditableText contained in the TextInput, with the same number of "password characters".

You can see this in the code of RichEditableText.as:

public function get text():String 
    {
        // Note: if displayAsPassword, _text will contain the actual text and the text flow will
        // contain the same number of passwordChars.

        // Go to the source if there isn't a pending change.  getText has its own buffering and 
        // only extracts the text from the TextFlow when it is damaged. 
        if (_textContainerManager && !textChanged && !textFlowChanged && !contentChanged && !displayAsPassword)
            return _textContainerManager.getText("\n");

        // Extracting the plaintext from a TextFlow is somewhat expensive,
        // as it involves iterating over the leaf FlowElements in the TextFlow.
        // Therefore we do this extraction only when necessary, namely when
        // you first set the 'content' or the 'textFlow'
        // (or mutate the TextFlow), and then get the 'text'.
        if (_text == null)
        {
            // If 'content' was last set,
            // we have to first turn that into a TextFlow.
            if (_content != null)
                _textFlow = createTextFlowFromContent(_content);

            // Once we have a TextFlow, we can export its plain text.
            _text = staticPlainTextExporter.export(
                _textFlow, ConversionType.STRING_TYPE) as String;
        }

        return _text;
    }

In the function textContainerManager_flowOperationBeginHandler(event:FlowOperationEvent):void

if (_displayAsPassword)
            {
                // Remove deleted text.
                if (delLen > 0)
                {
                    _text = splice(_text, delSelOp.absoluteStart, 
                                   delSelOp.absoluteEnd, "");                                    
                }

                // Add in the inserted text.
                if (textToInsert.length > 0)
                {
                    _text = splice(_text, insertTextOperation.absoluteStart,
                        insertTextOperation.absoluteStart, textToInsert);

                    // Display the passwordChar rather than the actual text.
                    textToInsert = StringUtil.repeat(passwordChar,
                        textToInsert.length);
                }
            }

You can see the passwordChar variable, it can be accessed with mx_internal

 /**
     *  @private
     */
    mx_internal var passwordChar:String = "*";
Related Topic