TextInput wmode opaque/tranpsarent workaround

Many of you have come accross the horrendous bug that happens with text input in flash when the swf is embedded with wmode=transparent/opaque. It has been much discussed (Firefox Bugzilla entry for this bug, Adobe Forum discussion, etc.), but it seems that in all the years that this bug has existed nothing much has been done. A lot of workarounds have been published, many of them based on custom key mapping etc… My workaround uses html element <input type=”text”> that is placed right over flex <mx:TextInput>. Html element is styled transparent (no design) so user will not notice.

Following application uses wmode “opaque”, try inserting characters (čšň) into first text input (mx:TextInput) and than into second (uses html <input type=”text”> over flash)

Main application

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    applicationComplete="init()" viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
    import mx.managers.PopUpManager;
    private function init():void
    {
        var window:FakeInputsWindow = new FakeInputsWindow();
        PopUpManager.addPopUp(window, this);
        PopUpManager.centerPopUp(window);
    }
]]>
</mx:Script>
</mx:Application>

FakeInputsWindow

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow 
    xmlns:mx="http://www.adobe.com/2006/mxml" 
    xmlns:html="sk.yoz.html.*"
    layout="vertical" width="400" height="250"
    creationComplete="init()"
    move="moveHandler()">
<mx:Script>
<![CDATA[
    [Bindable]
    private var text2:String = "";
    
    private function init():void
    {
        ExternalInterface.addCallback("fakeTextInputChange", fakeTextChange);
    }
    
    private function moveHandler():void
    {
        fakeTextInput.positionChanged = true;
        fakeTextInput.invalidateProperties();
    }
    
    private function fakeTextChange(value:String):void
    {
        text2 = value;
    }
]]>
</mx:Script>
<mx:Text text='&lt;mx:TextInput ....'/>
<mx:TextInput id="text1" width="300" height="20"/>
<mx:Label text="{text1.text}" />
<mx:Spacer height="10" />
<mx:Text text='&lt;input type="text" ....'/>
<mx:Canvas width="300" height="20">
    <mx:TextInput width="300" height="20"/>
    <html:IFrame width="100%" height="100%" id="fakeTextInput" 
        autoResize="true"/>
</mx:Canvas>
<mx:Label text="{text2}" />
</mx:TitleWindow>

lines:

  • 15: javascript-to-flash callback definition fakeTextInputChange (from javascript) sends value into actionscript fakeTextChange()
  • 18: fakeTextInput is IFrame class, that controls position and size of html input, lets correct position on TitleWindow move…
  • 35-39: I placed IFrame over TextInput. IFrame is in fact transparent html input, so what user see is just flex TextInput graphics

Html template file

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> 
<head> 
    <title>FakeTextInput</title> 
    ...    
    <script type="text/javascript" src="js/swfobject.js"></script> 
    <script type="text/javascript" src="js/flexiframe.js"></script> 
    <script type="text/javascript"> 
    <!--
        var flashvars = {}
        
        var params = {
            allowscriptaccess: "always",
            wmode: "opaque"
        };
        var attributes = {
            id: "flash"
        };
        swfobject.embedSWF("Tests.swf", "alternative", "100%", "100%", "10.0.0",
            "flash/expressInstall.swf", flashvars, params, attributes);
            
        function fakeTextInputChange()
        {
            var input = document.getElementById('fakeTextInput');
            var flash = document.getElementById('flash');
            flash.fakeTextInputChange(input.value);
        }
    //-->
    </script> 
    
    <style type='text/css'> 
    <!--
        body {margin:0px;overflow:hidden;}
        html, body, object, embed {width:100%;height:100%;outline:none;}
        #fakeTextInput {
            position:absolute;
            border:none;
            outline:none;
            padding:0;
            margin:0;
            background:transparent url("images/spacer.gif");
            vertical-align:middle;
        }
    -->
    </style> 
</head> 
<body> 
    <div id="alternative"> 
        <a href="http://www.adobe.com/go/getflashplayer"> 
            <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /> 
        </a> 
    </div> 
    <input type="text" id="fakeTextInput" onkeyup="fakeTextInputChange()"/> 
</body> 
</html>

Notice lines:

  • 07: import flexiframe.js used for positioning html input on correct place
  • 13: allowscriptaccess must be enabled
  • 14: wmode opaque/transparent is what the source of all evil
  • 22: javascript-to-flash communication
  • 35-42: remove all html input text design and makes it transparent
  • 53: input text definition, you may want to define your own handlers (submit, paste, focus…)

7 comments so far

  1. […] Beaucoup d'entre vous ont rencontré le bogue horribles qui se passe avec la saisie de texte dans flash lorsque le swf est intégré avec wmode = transparent / opaque. On a beaucoup discuté (Firefox entrée Bugzilla pour ce bogue, Adobe Forum de discussion, etc), mais il semble que dans toutes les années que ce bug existe depuis rien n'a vraiment été [. . . ] URL article original: http://blog.yoz.sk/2010/02/textinput-wmode-opaque-transparent-workaround/ […]

  2. hejaaa December 13, 2011 17:45

    ok Flex, or Flash CSx?

  3. Jozef Chúťka December 13, 2011 18:35

    hejaaa, this thing is a little older, example only works with mxml component, however you can rewrite it to use with pure actionscript

  4. hejaaa December 20, 2011 17:52

    how?:))

  5. hejaaa December 22, 2011 15:31

    Flash TextInput not work in Safari:(

  6. Jozef Chúťka December 23, 2011 12:16

    hejaaa, even this os offtopic regarding this article, you can find more about it here: https://discussions.apple.com/thread/3191466?start=0&tstart=0
    solutions:
    1. use non debug version of flash player
    2. use fp debug version 11.1++
    3. use wmode window
    4. use different browser

  7. hejaaa December 23, 2011 15:29

    thx, but items 1-4 is not solution

Leave a comment

Please be polite and on topic. Your e-mail will never be published.