Passing Data Between Pages in jQuery Mobile

Coming from Flex one of the things I’ve struggled a bit with is passing data between views in my jQuery Mobile applications. The template approach with Mustache worked really well, but it also had a lot of overhead. In fiddling around today I found a more hacky way that seems to work pretty well (though I think the Mustache route is still better). It relies on the fact that the pagebeforeshow method provides a prevPage property as part of its data object. That prevPage property is just a representation of everything in DOM of the previous page. That means it’s relatively easy to use selectors and that object to pass data to the new page.

The setup of my pages is as follows. My first page has a list of breweries, and each brewery page has a list of the beers that brewery uses. When you click on any of the beers, it goes to a form that can be used to rate the beers and provide some extra information about them. My goal was to prepopulate some of those forms with the beer data I already had. For instance I know the beer name, brewery, and style of each beer, so I should be able to prepopulate those, but they change for every beer so it has to be dynamic.

Within each page I defined a hidden div with two span elements with ids that represent the brewery name and brewery location (since they’re the same for every beer). Then within the beer list I have a hidden div that contains the beer name and the beer style. Here’s an example:

<div data-role="page" id="aleasylum" data-theme="e" data-add-back-btn="true">
     <div data-role="header">
          <h1>Ale Asylum</h1>
     </div>
     <div style="display:none">
          <span id="brewernameinfo">Ale Asylum</span>
          <span id="brewerlocationinfo">Madison, WI</span>
     </div>    
     <div data-role="content">    
          <ul data-role="listview">
               <li data-role="list-divider">Year Round Beers</li>
               <li>
                    <a href="#beerdetails">
                         <img src="images/hopalicious-thumb.gif" />
                         <h3>Hopalicious</h3>
                         <p>5.8% abv. Eleven separate additions of cascade hops give this American pale ale its lush citrus aroma and bold hop flavor without crazy bitterness. Hopalicious is available year round in six packs and on tap throughout the Madison and Milwaukee regions.</p>
                         <div style="display:none">
                              <span id="beernameinfo">Hopalicious</span>
                              <span id="beerstyleinfo">IPA</span>
                         </div>
                    </a>
               </li>
               <li>
                    <a href="#beerdetails">
                         <img src="images/madtown-nutbrown-thumb.gif" />
                         <h3>Madtown Nutbrown</h3>
                         <p>5.5% abv. Our nutbrown ale is velvety smooth with a rich caramel aroma. We blend seven different malts for just the right touch of sweetness and a creamy finish youÔøΩll really dig. Madtown Nutbrown is available year round in six packs and on tap throughout the Madison and Milwaukee regions.</p>
                         <div id="info" style="display:none">
                              <span id="beernameinfo">Madtown Nutbrown</span>
                              <span id="beerstyle">IPA</span>
                         </div>                        
                    </a>
               </li>

So in order to grab that, I just added an event listener to the pagebeforeshow method that uses selectors to grab the data. One of the critical parts is that jQuery selectors have an optional context property that can be set so that jQuery only selects from that context. In this case, since my pages are all using the same id names for the values, I need to set the context so that the selectors are only pulling from the previous page and not the entire document.

 $('#beerdetails').on('pagebeforeshow',function(e,data){
     var beername = $('.ui-btn-hover-e #beernameinfo',data.prevPage).text();
     var brewername = $('#brewernameinfo',data.prevPage).text();
     var brewerlocation = $('#brewerlocationinfo',data.prevPage).text();
     var beerstyle = $('.ui-btn-hover-e #beerstyleinfo',data.prevPage).text();
     $('#beername').val(beername);
     $('#brewername').val(brewername);
     $('#brewerlocation').val(brewerlocation);
     $('#beerstyle').val(beerstyle);
 });

The code above executes before anything gets displayed on the new page, grabs the values from the first page with the hidden div tags, and then sets some of the form fields to those new values.

It strikes me as a bit odd that there isn’t an easier way to do this, so it could be that I’m just not googling the correct thing and jQuery Mobile has something built-in to help with this issue. It does seem like this can be done by using URL variables, but what I like about this approach is that it’s a bit more semantic and there’s no required parsing of the URL string.

JavaScript Templating – Kind of Like ItemRenderers or Binding from Flex

One of the things I’ve been struggling with on the HTML/JS app I’ve been working on is how to get binding-like functionality. It seems like there are a few ways to do it, but the ones I looked at didn’t seem to fit with the general pattern of JavaScript and I wanted something a bit more elegant. Luckily, I just didn’t know what to look for, and once I came across templates, I realized I had found exactly what I wanted. Templates in JavaScript act like ItemRenderers but in my example I was able to use them to create a page, and then dynamically change the data on that page almost like I would if I were binding an object to a form in Flex.

And that’s almost exactly what templating lets you do. Here’s my example. I’m creating a list of beers, and when I click on one of those beers, I want to load a bunch of information about that beer in a form so I can make changes to it and save those changes to my database. With Flex Mobile I was able to do that pretty robustly because I can pass data between views very easily and bind elements in the second view to my data. With jQuery mobile, there’s nothing quite that fancy, so I had to rely on templates.

It turns out there are a ton of JavaScript templating libraries out there. Underscore.js includes a templating feature and looks interesting but I tried Mustache.js off the bat and found it pretty simple to use.

I started off with the template itself. In my case, it was a basic form that I called beer_detail.mustache

    <form action="#" method="post">
<div id="beername" data-role="fieldcontain">
            <span id="beerlabel">{{ beername }}</span>
            </div>
        <div id="brewername">{{ brewername }}</div>
        <div id="brewerlocation">{{ brewerlocation }}</div>
        <div id="beerstyle">{{ beerstyle }}</div>
<hr>
        <div id="quantity" data-role="fieldcontain">
<label for="quantityslider">Quantity: {{quantity}} </label>
<input type="range" name="quantityslider" id="quantityslider" value="{{ quantity }}" min="0" max="25"  />
</div>
        <div id="purchasedate" data-role="fieldcontain">
        <label for="purchasedatefield">Purchase Date:</label>
                <input type="date" name="purchasedatefield" id="purchasedatefield" value="{{ purchasedate }}"  />
</div>
        <div id="price" data-role="fieldcontain"><input type="text" value="{{ price }}"></div>
        <div id="cellardate" data-role="fieldcontain">
        <input type="date" name="cellarfield" id="cellardatefield" value="{{ cellardate }}"  />
</div>
        <div id="cellartemp">Cellar Temperature: {{ cellarTemperature }}</div>
        <div id="brewdate" data-role="fieldcontain">
        <input type="date" name="brewdatefield" id="brewdatefield" value="{{ brewdate }}"  />
        </div>
<a href="#pintley">This beer on Pintely</a>
        <button type="submit" data-theme="a">Submit</button>
        </form>

The double brackets {{ }} are all of the variable names that the template looks for so those will be replaced with actual data when the template gets rendered. I liked the similarity to Flex’s binding syntax.

One of the things you can do in jQuery Mobile is pass url variables, so for the first part of my application, I use a list of the beer names with a link to a page named beer_details.html that includes an id parameter that I use to look up the beer. In this example I’m using a Lawnchair database called “beers” and just calling the all() method to get all of the beers in the database. Then I iterate through those and build the list.

 
     beers.all(function(arrBeers){
          for(var i = 0; i<arrBeers.length;i++)
          {
               console.log(arrBeers.length);
               var listdiv = document.createElement('li');
                 listdiv.setAttribute('id','listdiv');
                 listdiv.innerHTML = '<a href="beer_details.html?id='+arrBeers[i].key+'">'+arrBeers[i].value.beername+'</a>';              
               $('#beer_list').append(listdiv);    
          }
          $('#beer_list').listview("refresh");
     });

The beer_details.html page itself just contains some skeleton code for jQuery mobile. The code will inject the template into the div id="content" tag. This way, all of the jQuery functionality stays with the application so it can use the back button, has the header/footer, etc and plays the transitions back and forth. So it’s pretty bare bones:

<div data-role="page" id="beerdetail" style="type-inline">
     <div data-role="header">
          <h1>Your Beers</h1>
     </div>
     <div id="content" data-role="content" align="center">
 
     </div>
     <div data-role="footer" data-id="foo1" data-position="fixed">
          <div data-role="navbar">
               <ul>
                    <li><a href="beers.html">Beers</a></li>
                    <li><a href="styles.html">Styles</a></li>
                    <li><a href="scan.html">Scan Barcode</a></li>
                    <li><a href="locations.html">Locations</a></li>                   
               </ul>
          </div>
     </div>
</div>

So now that the structure is set up, we can use Mustache to populate our template with data and inject the resulting HTML into the DOM. The first step is to set up the data object. In this code I parse the URL to figure out the ID of the beer, then use Lawnchair to retrieve that data. I’m listening for the pagebeforeshow method, but I’m not sure if that’s the best one. But it allowed me to get the data and change the DOM before the page showed, which is important for being able to render the template.

     $('#beerdetail').live('pagebeforeshow',function(e) {
          var beerID;
          beerData = {};
 
 
          var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');    
 
          for(var i = 0; i < hashes.length; i++)
          {
            hash = hashes[i].split('=');
            if(hash[0] == "id")
            {
                 beerID = hash[1];
            }
          }                 
 
     });

Once I have the beerID, I can use LawnChair to grab the information. Then I can use that object and pass it to Mustache to build the template. The Mustache library uses a .to_html() method that takes a reference to the template and the object that holds the data, in this case beerData. In the example below, there’s a bit of chaining going on. First I have to get the data, then when that is returned, it calls a function that will go out and load my .mustache template using Ajax, and finally, when that page is retrieved, I call Mustache.to_html() to get the HTML and then inject that HTML into the content so it will render correctly. This code goes inside the pagebeforeshow event handler.

          beers.get(beerID,function(obj){
               beerData = obj.value;
               $.get('templates/beer_detail.mustache',
                    function(data){
                         template = data;    
                         var renderedhtml = Mustache.to_html( template,beerData);
                         $("#content").html(renderedhtml);    
                    });
          });

And voila! Now when we click on a beer from the list, the data gets inserted into the template and when we move back and forth the data will update as we click on new beers.

This is much, much easier than trying to go through the DOM and insert/modify the form variables and also lets us potentially use different templates depending on the beer I choose. So far I’ve found templates to be helpful for getting around concepts like binding in HTML/JS.

I’ve gone ahead and put this project up on GitHub. It’s kind of a disaster at this point, since it’s basically my learning project, but you can see how this was done.

Why I’m Doing PhoneGap

I’ve started to see some general questions and fielded a few emails from people asking about why the big push around PhoneGap on the Adobe side. In general, everyone knows the basic answer: we acquired Nitobi (the company behind PhoneGap), so now as Adobe evangelists, it makes a lot of sense for us to know it and be able to talk about it. And I think we’ve done a pretty good job of that. Christophe has a demo app (with source code) up, Greg has a couple of really good posts on it (especially this one that talks about how PhoneGap affects Flex evangelism). So at a general level, it shouldn’t be a huge surprise, but for me it’s quite a bit deeper than that and I wanted to provide a bit of context.

My desire to learn PhoneGap (and by extension get a lot better at HTML/JS) comes from two places. One, if you aren’t learning new technology, you’re not adapting as a developer. Two, as I’ve been looking around and trying to get my head around PhoneGap/HTML, I’ve found some rougher edges. Since I work at a tools company, I want to know where those edges are so that as Adobe builds out tools for this technology stack, I can provide good feedback to the product teams.

New Technology

I’ll say this a thousand times: I think AIR and Flex are the best way to build cross-platform mobile applications. I think they’re arguably the best way to build mobile apps in general for specific types of apps. And with AIR 3.0, AIR has never been more powerful. Stage3D is coming, we have native extensions and captive runtime so as a developer you can really blur the line between your AIR app and native functionality. But as great as I think native extensions are for our developer community, I’m not personally that excited by spending a lot of time writing them. I love the web. What got me so excited about RIAs back in the day was that you could build desktop-like apps with web technologies. I fully believe that Flash is part of the web, and I always will. Java and Objective C are decidedly not web technologies. And I’m not really that interested in spending a bunch of time learning Java/Objective C code. I don’t think that many AIR developers will have to roll their own native extensions, but it is one of the cool new parts of the platform, so a lot of the Adobe evangelists will be spending time getting up to speed on how to build them. That just doesn’t get me excited. Same goes for Stage3D. The stuff you can do with 3D in Flash Player is mind-blowing. I’m just not a 3D developer or a game developer. Luckily the Flash Platform is evolving beyond that as well. The stuff coming up with concurrency and potential enhancements to ActionScript both fall into what I’d call the “web world” and I’m excited to dive into those and get to know them as they get closer.

But, while I’m waiting, it turns out we now have a pretty cool HTML/JS mobile story with PhoneGap. I’ve been dabbling for a little while in jQuery mobile and HTML/JS and I’d consider myself an average JS developer. But you’ve always got to be learning, and if you love the web, you can’t not be good at JavaScript. I’m kind of ashamed that I’m not better, but this is a great opening for me to dive in, dedicate a ton of time and energy to getting better, and coming out a more holistic web developer. One of the things I love about the HTML/JS community is just how varied it is. There are JS developers of all stripes creating their own frameworks, own solutions to architecture problems, their own server solutions, and hell, even their own languages that eventually end up as JavaScript. The raw creativity of the web ecosystem is on full display when it comes to HTML/JS. And there is a certain zen to the chaos that I find intoxicating. I desperately want to be a part of that and the fact that I’m behind the curve is kind of depressing.

Helping Adobe

Which brings me to the second reason I’m planning to dedicate a ton of time to the PhoneGap stack. There are quite a few areas where the workflow is downright broken. My recent foray into on-device debugging is one example. Some of that is just that I don’t know enough, but there are also some real gaps in tooling, services, etc. We’ve got some smart people at Adobe who know the JS/HTML world pretty well. But we can always have more and if we want to provide value to developers in the space, that’s going to require knowing where the gaps are, knowing where to spend our time, and what kind of solutions will be helpful. I want to be able to provide that feedback and the best way to do that is to really know it. The hope is that I’ll be able to contribute in a small way to what Adobe will contribute to the open web ecosystem for developers.

Viva Flash!

So for me this particular foray goes beyond just learning PhoneGap to get up to speed. I think it’s a really cool time to be an Adobe evangelist and I came away from MAX a lot more invigorated than I’ve felt in a long time. Part of that is the Flash side (this session on the roadmap was excellent). But a big part of that was definitely that I think Adobe is going to make a positive impact in the HTML/JS space. The Nitobi guys are all insanely talented and I think that with them we’ve got a vision for mobile apps rooted in web technologies. I’m ready to contribute to that vision.

Update: And Ray pointed out he’s got a ton of stuff up as well.

The Problem with Technology Silos and Where Flash/HTML can Lead

There is a cool workshop being given by Jamie Kosoy called No Flash? No Problem and he had a great quote in the description:

There’s a long list of common complaints about the use of Flash, but many of the criticisms just aren’t true. Detractors say that Flash isn’t search engine friendly; Screen readers can’t understand Flash content; You can’t deeplink to specific pages…

You know what? They’re wrong. These criticisms are symptoms of misunderstanding by developers on the ways different technologies work together.

I think this is one of the biggest problems that Adobe has. Technology and development choices tends to be borderline religious in nature. And technology in general loves to have good guys and bad guys. That means the communities are very siloed and there is some resistance to incorporating or looking at other technologies. It’s HTML5 versus Flash, Microsoft versus Google, .NET versus Java, etc.

It’s also become a lot harder to be a generalist. Developers get rewarded (at least in terms of attention) for becoming experts in their niche. They’re asked to speak at conferences, they get better gigs, so becoming an expert has direct financial and publicity benefits. Who has time to dive into other technologies when there are so many advantages to drilling down into your own?

Because of that, I don’t think we’re seeing technology at its best. And it’s not limited to Flash. PhoneGap has been very successful by combining the iPhone with HTML/JS. But Flash suffers more than most. There are a lot of great integration points between HTML and Flash. We’ve got the Flex/Ajax bridge for Flex that lets you expose Flash methods to JavaScript and vice versa. We’ve got deep-linking support with SWFAddress that uses JavaScript and Flash. There are a lot of integration points but they don’t seem well publicized or well used. And there are no shortage of areas where Flash can augment JS/HTML to solve problems. File uploading, Webcam/Mic support, and charting.

But I also think Adobe is at fault. I don’t think we’ve done a good enough job of making it easy to integrate Flash and HTML. Even now internally you hear things like “HTML strategy”, or “HTML versus Flash” and I haven’t heard a lot of talk about how we’re going to take what we know about RIAs and web apps and apply that to both Flash and HTML.

But I think that’s changing. So part of the post is to give heart. We recently had a big re-organization and most of the Creative Suite web tools and the Platform (Flash/AIR/Flex,etc) are together in one business unit. I think that means you’re going to see a lot of Flash-knowledge applied to our HTML tools and hopefully you’ll see a lot more about using Flash and JavaScript together so we don’t need sessions like Jamie’s a year from now.

With the web design tools and developer tools in one place, I’m looking forward to talking a lot more about rich web solutions that provide some innovative examples of technology working together and encouraging HTML/JS developers to look at Flash where appropriate and Flash developers to think about HTML/JS when it makes sense. The easier we can make that for developers the more success we’ll have and the better applications we’ll see.

Flash Builder for Dreamweaver CS5 Users

Thanks to everyone who stuck out the preso on Flash Builder for Dreamweaver CS5 users. Clearly this isn’t my month for demos. I’ve uploaded the slides as well as the (working) source code. There are two directories: the Flex directory, which includes the source code for the Flex projects, and the html directory, which includes the HTML code.

It’s got examples for using ExternalInterface, the Flex/AJAX Bridge, and FlashVars. You can grab it here.

Flash and Standards Cold War

Very good perspective on Flash and standards.

Both the standards community and the Flash community are extremely good at sharing knowledge and supporting the people within their respective groups. The relationship across communities, however, isn’t nearly as cordial. Two things are happening: either the people within each camp stay to themselves, or one ignorantly hurls insults at the other.

I love that angle. Both camps have very passionate communities but the problem is that there’s not enough cross-pollination between groups. Part of that is that (I don’t think) Flash has done a good job of playing well with HTML. It has been and still is largely a black box. So at a technical level the two technologies don’t work as well as they should have. That carries over into the communities. As a company that makes tools for both HTML and Flash, it behooves us to be involved in both sides of the debate. My hope is that as Flash opens up more and hopefully works better with HTML, the people on both sides will start to work more closely as well.

HTML-Flash Geo

HTML and Flash working together to find each other.

Geolocation is a good example. HTML5 is going to get a geolocation API that works just beautifully even on devices with no GPS. Flash based applications will (currently) only get access to geolocation APIs when targeting the AIR runtime on mobile. Some browsers (I only know of Firefox 3.5 on Mac and the WebKit browser on the Nexus One) already support the HTML5 geolocation API… So why not use that to get geo information into your Flash based application?

There are few things I love more than geography and by extension, geolocation. It’s the digital overlay of the world. How can that not be cool? And this particular example is nice because it’s an area where HTML5 is ahead of Flash Player. Just like HTML can use Flash to implement ideas it hasn’t nailed down yet, Flash can use HTML to implement ideas that it hasn’t got yet. Bliss.

Non-Accessible HTML

YouTube opens up captioning for all videos….sort of.

I know I work for Adobe, but this is the kind of thing that pisses me off. Flash gets such a bad rap from the open standards crowd who hold accessibility so highly but as of right now there isn’t any way to do captioning in HTML5 videos. So when YouTube makes a big announcement about improving and enhancing accessibility by adding captions to all of their videos, no one mentions that it’s just the Flash videos.

I realize that the HTML5 feature on YouTube is in beta, but it isn’t like this is something that anyone has figured out yet for HTML5 video. It’s listed as “unwritten documentation” on the Chromium site, which basically means “we aren’t sure how this is going to work”. But no one does. The closest thing I’ve found is a jQuery plugin that’s in the early stages.

Not only is there no clear codec for HTML5 (something that in theory Google will remedy with the purchase of On2) but captioning support, something that Flash has made easy and ubiquitous, isn’t a feature that’s looking like it will be implemented soon.

But it’s going to kill Flash….riiiiiiiight….

Flex and PHP: Authentication With an HTML Login Page

One of the first things to think about when building a Flex application is how you’re going to do authentication. Most people seem to include a username and password box in Flex and then make an HTTPService or AMF call to pass the authentication credentials. But I hate that solution. Most major browsers now have support to save usernames and passwords with autocomplete and that’s become something people expect from their logins. I think it’s also important to be able to clear the “remember me” cookie just like any other cookie as opposed to having it saved in a Flash cookie. Whenever you can provide the behavior people expect from their browser, you should.

So in this example I’m going to show how you might implement an HTML form with PHP for a Flex application. As I’m new to PHP there may be some bad practices here but I’ll update the post as I get feedback.

Creating the login page in PHP and HTML

To start, we can just use PHP’s built in session functions to create the session variables and build the login page called login.php. You start off by creating a session with session_start() and then you set some session variables to their defaults. Then you’ll show the username and password fields only if the form hasn’t been submitted and use the $_SESSION variables to store the information from the user. Finally, when everything is authenticated you use the header() function to send the user to the Flex application.

<?php
session_start();
$_SESSION['logged_in'] = false;
$_SESSION['username'] = "";
 
if(isset($_POST['is_submitted']))
{
$username = $_POST['username'];
$password = $_POST['password'];
 
// If the "Remember my username" box is checked
// then we use the setcookie function to save it.
// Otherwise, we clear it out. 
if($_POST['keep_username'] == true)
     {
          setcookie("username",$username,time()+36000);
     } else {
          setcookie("username");
     }
 
// This is where you would look up the username
// and password. Normally this would be an LDAP call
// or a query to a database. In this case, I'm just
// accepting everything.
if($username && $password)
     {
// Set our session variables.
$_SESSION['logged_in'] = true;
$_SESSION['username'] = $username;
 
// Redirect to the Flex application
          header("location:flex/index.php");
     } else
{
echo "Go back and put in a username and password.";
     }
} else {
?>
 
<form name="login" action="<?php$_SERVER['PHP_SELF'] ?>" method="post">
     Username: <input type="text" name="username" value="<?php echo $_COOKIE['username']; ?>" /><br/>
     Password: <input type="password" name="password" /><br/>
     Remember my username: <input type="checkbox" name="keep_username" value="true"><br/>
<input type="hidden" name="is_submitted" value="true" />
<input type="submit" value="Submit" />
</form>
 
<?php 
}
?>

Notice the keep_username checkbox above. If the user checks that, you use the setcookie() method to create a cookie that will store the username on the next visit. If it is unchecked, the username will be blank.

Setting up the Flex Project

Even though most Flex applications take up the entire page, nearly all of the time you embed the actual SWF file on an HTML page. In Flash Builder when you create a new Flex application in creates the SWF files and the HTML files for you that embed your application. To do that it uses a template file that you can find in the html-template folder of your project. If you haven’t done so yet, go ahead and create a new Flex project. Use the defaults (do not use PHP as the server, leave it at None/Other). When you get to the second screen, set the output folder to a subdirectory named “flex” in the directory where your login.php file is located.

With the project created the first thing you’ll want to do is edit the template file. Go into the html-template directory and rename index.template.html to index.template.php. That will let you run PHP code inside of the template file. Flash Builder will automatically create an index.php file in the flex folder you specified in the create project wizard. Next you need to make sure your application will use the right file when you run or debug it. Right click on your project, select properties, and then select Run/Debug Settings. Now select your project in that box and click the “Edit” button. On the next screen, uncheck “Use default” in the lowest box and type the path to your application. You can see mine below (I’ve got http://localhost:8888 mapped to http://rainier.cascade.mtn but your local PHP server will probably use http://localhost).

Modifying the Index Template

Next you need to edit the template you just renamed. Open it up in Flash Builder (or your favorite text editor) and you should see a bunch of HTML. At the very top of that page you’re going to add some PHP code. First, you are going to check for a url parameter named logout to be passed. If it is, you destroy the session and log the user out. If that isn’t passed, you’re going to use the session information from your login page and save that information to variables on this page. This code goes at the very top before all of the HTML in your template page.

<?php     
// Always start the session first.
     session_start();
 
     // You will also use this page to log out. If 
     // ?logout=1 is passed in the URL, destroy the 
     // session and log the user out.
     if(isset($_GET['logout']))
     {
          if($_GET['logout'] == 1)
          {
              $params = session_get_cookie_params();
              setcookie(session_name(),"", time()-3600,
                  $params["path"], $params["domain"],
                  $params["secure"], $params["httponly"]);
               session_unset();
               session_destroy();
          }
     }
 
     // Create the default values for our session.    
     $session_id = "";
     $logged_in = false;
     $username = "";
 
     // If the session is valid, replace the default
     // values with our session values.
     if($_SESSION['logged_in'] == true)
     {
          $logged_in = true;
          $session_id = $_COOKIE['PHPSESSID'];
          $username = $_SESSION['username'];
?>

Now that your variables are set, you’ll send those to Flash Player. There are a number of ways to get data into your Flex application but the most straightforward is to use a concept referred to as “flashvars”. Flashvars are parameters you can put within the embed code that will then be accessible by the Flex application. Flashvars are a great way to take a dynamic site, like one written in PHP, and change the behavior of a Flex or Flash application based on that dynamic PHP data. Look for the JavaScript in the template that includes var flashvars = {} and replace it with this code.

var flashvars = {session_id:"<?php echo $session_id; ?>",               
logged_in:"<?php echo $logged_in; ?>",
username:"<?php echo $username; ?>"};

That code will make those three variables available to your Flex application. That way before you let the user do anything in your Flex application you can check to make sure the user is logged in correctly.

Finally, at the end of the template you’ll add some code to show the user an error message if they try to access the page without logging in.

<?php              
} else {
     echo "Not authorized, go back and log in.";
}
?>

Creating the Flex Application

In this example you’ll just create a very, very basic Flex application with two states, a beginning state and a logged in state. When the application loads, check the flashvars you added to the embed code and then change to the logged in state. The logged in state also contains a button that uses the logout functionality you added to the template code. Here’s the whole Flex application.

<?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" 
                  minWidth="955" minHeight="600" currentState="startingScreen"
                  creationComplete="application1_creationCompleteHandler(event)">
 
<fx:Script>
     <![CDATA[
          import mx.controls.Alert;
          import mx.events.FlexEvent;
          import mx.utils.ObjectUtil;
 
          protected function btn_clickHandler(event:MouseEvent):void
          {
               navigateToURL( new URLRequest( encodeURI("index.php?logout=1")), "_self");
          }
 
          protected function application1_creationCompleteHandler(event:FlexEvent):void
          {
               if(this.parameters.logged_in == 1)
               {
                    currentState = 'loggedIn';
               }
          }
 
     ]]>
</fx:Script>
 
<fx:Declarations>
     <s:State name="startingScreen" />
     <s:State name="loggedIn" />
</fx:Declarations>
 
     <s:Panel name="Test" left="25" right="25" top="20" 
               bottom="25" title="My Application">
          <s:Button id="btn" left="10" top="10" 
                    click="btn_clickHandler(event)" 
                    label="Log Out" includeIn="loggedIn" />
          <s:Label id="lbl" left="10" top="10" 
                    text="You need to log in" 
                    includeIn="startingScreen" />
     </s:Panel>
 
</s:Application>

Conclusion and Warnings

There are a couple of notes and warnings about this method. By using two states and checking the login parameters you aren’t just depending on the embed code. That means if someone browses right to the SWF file they won’t be able to access the application because it won’t move to the next state unless it gets those parameters. That’s also part of the problem in this very simple application.

In the Flex code that changes the state I just check to see if the flashvar logged_in is set to 1. If you were to download a local version of the PHP file as well as the SWF and change that embed code you’d have access to the application. In a more robust example you would want to add a couple of hooks into the database. One way to do that would be to store the session id and the username in the database in the login.php file. Then when your Flex application loaded you could make a call to another PHP page and pass the session id and username parameters to a function which would compare it to the session and username that were stored during login to make sure it matches up.

You might also want to implement a token system with a shared secret which is a good way to authenticate against external APIs, the kind that you would create in PHP and consume in a Flex application using AMF or REST.

So keep in mind that this isn’t ready for production. But hopefully it gets you started in the right direction when creating a PHP/Flex application that is going to use an HTML login form. The fewer Flex/Flash login forms there are the better. Update: I’ve added a GitHub repository with the code. I’m hoping to add to this as I fill in some of the gaps that I warned about above.

HTML5 Versus Flash Versions

Serge has a great post on Adobe and the open web. I don’t think Adobe gets enough credit for contributing to the open web. That takes a couple of approaches. One is, as Serge said, we participate in a lot of open source and open web initiatives. But we also spend a lot of time and money investing in the web and solving problems that we come across. Cross-domain support is a perfect example. It was a problem we saw coming long before Ajax and we created a solution in the Flash Player to support cross domain requests. I ran down some of the new APIs and changes between HTML5 and HTML4 according to Wikipedia and compared them to what we have in Flash and when we added it.

Not all of this is 100% accurate but it’s the best guess I have at 2:00 AM. I’ll update it as I get new info.

HTML5 Flash Version
Canvas Tag (2D Drawing and Animation) FutureSplash (Flash Player 1)
Video/Audio Support Flash 2 (Audio) Flash 6 (Video)
Offline Storage Database No real offline storage in Flash Player, Adobe AIR added it in version 1
Drag-and-drop Supported in ActionScript 1(Flash Player 5)
Cross-Document Messaging Cross-Domain support in Flash Player 7
MIME type and protocol handler registration I don’t think there is anything analogous to this in Flash.
New parsing rules N/A
New elements such as progress, nav, time, etc Largely covered with ActionScript 2 (Flash Player 7)
New form controls (dates, times, email, url) Shipped with Flash authoring (Flash Player 3/4)