Calling JavaScript function from Flex 4 web application - apache-flex

I need to call javascript function from Flash 4 based web application. When I run it in Debug mode it runs perfectly but when I make release build or run same application on other machine it does not call JavaScript function.
For testing I am just calling sample Alert function of JavaScript. Can someone help me what I am missing ?
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" initialize="application1_initializeHandler(event)"
verticalAlign="middle"
backgroundColor="white">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.FlexEvent;
public function btnLogin_click():void
{
var s:String;
if (ExternalInterface.available)
{
ExternalInterface.call("alert", "Hello World!");
}
else
{
Alert.show("External interface not available");
}
trace(s);
}
protected function application1_initializeHandler(event:FlexEvent):void
{
flash.system.Security.allowDomain("always");
}
]]>
</mx:Script>
<mx:Form>
<mx:FormItem>
<mx:Button id="btnLogin" label="Login" click="btnLogin_click()" />
</mx:FormItem>
</mx:Form>
</mx:Application>

Well, firstly, make sure JavaScript on your testing machine is turned on and then also make sure you are adding your JavaScript file/code after adding swfobject.js file.
I had similar problem but it worked out when I moved swfobject.js at the top of all js includes.

Have you tried a test like (Flex):
ExternalInterface.call("alertFn");
And JS:
function alertFn() {
alert("hello world");
}
?
I've never tried an ExternalInterface call to a native JS function like "alert"...

After digging out the error code 2060 through
Alert.show(e.message)
I figured out that for some reason ExternalInterface.call doesn't work on a file:// and needs http(s)://
So, anybody who is facing this problem, get your yourself a webserver(Apache) or a GAE for testing these kinds of things and save yourself from the "Extreme time wastage":
I was having endless hours of problems using file:// with the Flex
AJAX Bridge.
The AJAX code would fail silently during the SWF initialization
callbacks to the AJAX code. I would then have null values for all of
the SWF root elements.
As soon as I installed a web server and started using http:// localhost
everything worked perfectly.
Extreme time wastage :(

test.mxml
..........
protected function bt1_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
ExternalInterface.call("callUnity");
}
.js
....
function callflex(){
alert("got it");
}

Related

Flex' VideoDisplay control does not open stream

I'm trying to make VideoDisplay playing media with FlashDevelop. Here's the source of my application:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.events.VideoEvent;
private function pause():void
{
if (moo_player.state == VideoEvent.PLAYING)
moo_player.pause(); else
if (moo_player.state == VideoEvent.PAUSED)
moo_player.play();
}
]]>
</mx:Script>
<mx:Panel>
<mx:VideoDisplay
source="bar.flv"
width="640"
height="480"
maintainAspectRatio="true"
id="moo_player"
autoPlay="true"
doubleClick="pause();"
doubleClickEnabled="true"
/>
</mx:Panel>
</mx:Application>
The problem is when i build application and run it (unfortunately, got no idea how to run it without KMPlayer or Mozilla - Flash Player is a plugin afaik) i got no video. The movie file is in the same directory as application's "Application.flv" one. But if i reload application (within player or browser) a few times, video starts.
So, here are my questions:
what's wrong with VideoDisplay
component and how to fix this
'non-playing'?
what's the better way
to execute application than running
it within movie player or browser?
P.S.: please, do not get mad of my knowledge lacks - i began to use Flex nearly 30 minutes ago.
You should be using Spark components, not MX components. Try this:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:VideoPlayer source="bar.flv" width="640" height="480" />
</s:Application>
There's some issues with video display internally in the component. One of the only flex components that's kind of poorly done in some ways. Please don't let it discourage you from exploring Flex.
Create a custom component that extends it, create a file named CustomVideoDisplay.as with this code:
package
{
import mx.controls.VideoDisplay;
public class CustomVideoDisplay extends VideoDisplay
{
[Bindable]
override public function get source():String
{
return super.source;
}
override public function set source(value:String):void
{
super.source = value;
play();
}
public function CustomVideoDisplay()
{
super();
}
}
}
Then add this into your root <application> tag :
xmlns:local="*"
And for your video component, refer to it as:
<local:CustomVideoDisplay
source="bar.flv"
width="640"
height="480"
maintainAspectRatio="true"
id="moo_player"
autoPlay="true"
doubleClick="pause();"
doubleClickEnabled="true"
/>
Let me know if this doesn't do the trick for you!
Well, i thought: my player will be ran at client-side of web project, and in FireFox that code runs successfully each of seven runs. I think this would be enough for testing and implementation.
Thanks everyone for the trouble-taking!

What undocumented alchemy is necessary to get parentApplication to work

I load an SWF with SWFLoader. Within the loaded .SWF, this.parentApplication is returning NULL. Been searching the internet for eight hours.
code listing as requested:
<?xml version="1.0"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
initialize= "Init();"
visible="false"
>
<mx:Script>
<![CDATA[
import flextrace.Dumper;
private var txt_event:TextEvent = new TextEvent(TextEvent.LINK,false,false,"next.xml");
private var timer:Timer = new Timer(10000);
private function Init():void {
timer.addEventListener(TimerEvent.TIMER,timer_handlr);
timer.start();
}
private function timer_handlr(event:Event) {
Dumper.info("timer_handlr");
if (this.parentApplication == null)
Dumper.info("null");
parentApplication.dispatchEvent(new TextEvent(TextEvent.LINK,false,false,"next.xml"));
}
]]>
</mx:Script>
</mx:Application>
I just was looking through Flex docs and saw an answer on your question, if I understood you correctly:
The parentApplication property of an Application object is never itself; it is either the Application object into which it was loaded, or it is null (for the Application object).
Since, your calling it from the application, it should be null.
Just a quick link for you about accessing nested applications (I haven't tested the solution yet tho, but still, may give you some ideas): Nesting Flex applications - weird issues..
Hope, this would help :)
RYAN GUILL: I tried your suggestion - didn't work. I replaced the dispatchEvent call in the code from the OP with the following: this.dispatchEvent(new TextEvent(TextEvent.LINK,true,false,"next.xml")); Were you saying that this should have triggered the Parent application's event handler for TextEvent.LINK? It didn't work.
Try FlexGlobals.topLevelApplication?
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/core/FlexGlobals.html?filter_flex=4.1&filter_flashplayer=10.1&filter_air=2

Can a custom component call PopUpManager.addPopUp on itself? How does one put the pop-up logic inside the component?

I'm trying to organise my code better and figured it would be good to place the pop-up logic within the component that's being popped-up. However, I can't seem to do this without causing one error or another. I also need to make the pop-up modal.
I'm doing something along these lines (psuedo code):
<mx:TitleWindow >
<mx:Label id="messageLabel" />
<mx:Script>
<![CDATA[
public function show():void{
PopUpManager.addPopUp(this, Application.application as DisplayObject, true);
PopUpManager.centerPopUp(this);
}
public function hide():void{
PopUpManager.removePopUp(this);
}
]]>
</mx:Script>
</mx:TitleWindow>
Can anyone help?
It appears that this works, after all.
I'm not sure what I was doing wrong, but after Ryan's response I rewrote the code, using the above pseudo code as a starting point. Now it seems to work.

Flex: weird question, can't access application property in init event of SWFLoader

Very weird problem, I am new to AS, but I have to say it's hard to comprehend AS is a modern language:
private function completed():void
{
trace("completed.");
var player:Object = (loader.content as SystemManager).application as Object;
player.playVideo();
player.setSize(200,300);
}
SWFLoader id="loader" horizontalCenter="0" width="100%" height="362" source="http://localhost:8000/testflv1.swf" init="completed()"
What I want to do is embed a swf in another parent swf, and call a function from parent to the embedded swf. Then, I use the init event for the SWFLoader to invoke the method. Before doing this I have verified that using the same code in a button click handler, it is fine with:
var player:Object = (loader.content as SystemManager).application as Object;
But if in a init event handler, the (loader.content as SystemManager).application is a null.
Whereas, in the document of SWFLoader:
init
Dispatched when the properties and methods of a loaded SWF file are accessible.
I think the problem is here because the application property of your included file is not yet initialized.
You can listen to the APPLICATION_COMPLETE event, which will tell you when the application property of your SWF content is completed.
public var loadedSM:SystemManager;
private function init():void
{
trace("init.");
loadedSM = SystemManager(loader.content);
loadedSM.addEventListener(FlexEvent.APPLICATION_COMPLETE, callFunc);
}
private function callFunc(event:FlexEvent):void
{
LoadFileInclude(loadedSM.application).playVideo();
}
]]>
</mx:Script>
<mx:SWFLoader id="loader" horizontalCenter="0" width="100%" height="362" source="LoadFileInclude.swf" creationComplete="init()" />
I had this same problem. Googling around forever and finally found an answer that led me to the solution buried in this Old Nabble thread.
Basically, when the SWF is injected, the MovieClip itself is in a different place, and it's kind of a pain to get it out. What I did:
MXML:
<mx:SWFLoader
id="loader"
source="#Embed(source='/flash/preloader.swf')" />
AS:
var mc:MovieClip = Loader(DisplayObjectContainer(swf.content).getChildAt(0)).content
as MovieClip;
if(mc)
{
mc.callAFunction();
}

Bookmark a page

How can we bookmark a page on clicking a button or a link button in flex using actionscript
A working example based on the information in previous answers:
bookmarks.js (add this to your html-template directory):
function CreateBookmarkLink(title, url)
{
if (window.sidebar) { // Mozilla Firefox Bookmark
window.sidebar.addPanel(title, url,"");
} else if( window.external ) { // IE Favorite
window.external.AddFavorite( url, title); }
else if(window.opera && window.print) { // Opera Hotlist
return true; }
}
Then add this line to index.template.html:
<script src="bookmarks.js" language="javascript"></script>
Now you have javascript code "wrapping" your Flex application which can be called by this code (bookmarks.mxml):
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
public function AddBookmark() : void
{
ExternalInterface.call("CreateBookmarkLink",
"Stack Overflow",
"http://www.stackoverflow.com");
}
]]>
</mx:Script>
<mx:Button x="10" y="10" label="Bookmark!" click="AddBookmark()"/>
</mx:Application>
Tested on IE.
You'll have to use javascript for that. Just create a javascript function to bookmark a page in your html file that is hosting the swf and then call that function from inside the swf using ExternalInterface.
Here's an example of a javascript function for bookmarking: http://labnol.blogspot.com/2006/01/add-to-favorites-ie-bookmark-firefox.html
Here's the Flex docs on how to use ExternalInterface: http://livedocs.adobe.com/flex/2/docs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001009.html
AFAIK, you can't do that from actionscript directly. However, you can invoke javascript from actionscript unsing the ExternalInterface class, and the web is teeming with javascript functions to create bookmarks. Take a look at this, for example (I have not tested it).

Resources