Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

February 21, 2010

appify: Make Web Apps Look Like iPhone Apps

As you probably know, simple web pages can appear as 'normal' apps on your iPhone (or iPod touch) when you add them to your home screen using Safari's '+' menu. With some changes to the web site you can enhance the 'app feeling' even further. You can:
  • Give it a nice icon
  • Add a startup screen which appears when clicking the icon on your home screen
  • Hide the Safari address bar and the menu
All the details on what you have to do in your code can be found e.g. here.

And voilĂ , your web page looks like a normal iPhone app.


Left: My web page in Mobile Safari
Right: Same page through appify


But what if you cannot change the code (as it might not be your web site)? I wrote a small web app (I called it 'appify') which can do the trick for you. appify adds a new starting page to the web app of your choice, and adds all of the nice features I just listed. And after displaying that starting page, the browser is redirected to the actual web app.

You can appify a web app yourself. Or you simply try it on your iPhone with the appified mobile version of GMail.




Note: All of this is nice but has one drawback: When you click on a link on your appified web page, the iPhone will close the app and open the new page in Safari. This doesn't happen with AJAX web apps where you do not have 'normal' links. So appify might not be too useful for many web pages :-(. But it works great for e.g. GMail.
This does not only affect appify, but all web apps on the iPhone. If you know a way to avoid this, please let me know!

A small interesting details from the implementation: I have to give the user a chance to save the web site on the iPhone home screen BEFORE I redirect to the actual web app. I found an easy way to do this: In JavaScript you can detect if the app is in standalone mode (i.e. it is fullscreen without the address bar and menu):
if (window.navigator.standalone) {
// fullscreen mode
redirect();
}

So when we are not in fullscreen mode I do not redirect and the user can save the page to the home screen. When coming through the new home screen icon, Safari runs in standalone mode and the script redirects to the actual app.

September 14, 2009

Managing the browser history for AJAX apps with dojo

AJAX web application (or any web app using client side scripting to modify the page) suffer from the "Back button problem": Users are used to hit the browser back button to return to a previous page, but there are no "pages" to go to in a AJAX app. Instead users will be taken to the page they visited before navigating to your web app - and probably lose all the state changes done in the app.

Fortunately there are some libraries out there that come to the rescue. I'll present a very simple example using dojo, which should get you started quickly.

For the example I chose a simple javascript app which converts inches into centimeters. For every new conversion there is a new entry stored in the browser history. Without history support the code looks like this:


<form>
<input id="idInches" type="text"></input> inches
<button onclick="onConvert(); return false;">Convert</button>
</form>
<div id="idOutput"></div>

<script language="javascript">
function onConvert()
{
var input = document.getElementById('idInches').value;
convert(input);
}

function convert(input)
{
var cm = 2.54 * input;
var msg = (input==null || input=="") ?
"" : (input + " inches = " + cm + " centimeters");
document.getElementById("idOutput").innerHTML = msg;
}
</script>

Nothing unusual with that.
To enable the browser history we first add a function to restore a previous state. In our case we just restore the value of the input box and recalculate the result.


function restore(input)
{
document.getElementById('idInches').value = input;
convert(input);
}

Next we define a class which can store our state and restore it. It implements functions/properties that dojo will use:


function HistoryState(state)
{
this.state = state;
this.restoreState = function() {
restore(this.state);
};
// back, forward and changeUrl are needed by dojo
this.back = this.restoreState;
this.forward = this.restoreState;
this.changeUrl = true;
}

Then we add dojo and dojo.back, which includes the functionality for managing the browser history. First the dojo include (see details here):


<script type="text/javascript" src="dojo.js"
djConfig="preventBackButtonFix: false">
</script>

Load and initialize dojo.back:


dojo.require("dojo.back");
dojo.back.init();
dojo.back.setInitialState(new HistoryState(""));

The last line of this sets the state the page initially has. In our example the input text field is empty initially, so we just pass an empty string.

Now the only thing missing is to tell dojo when we reached a new state. We do this every time the convert button is pressed, so we add the following to onConvert:


dojo.back.addToHistory(new HistoryState(input));


That's it! See the example live here. Convert a few different values and then try the back/forward buttons of you browser.

Note: When trying yourself, always use a web server! Some things do not work when opening the file directly from the file system.

Note 2: You do not need all of dojo if you only want dojo.back. At the time of writing (dojo 1.3.2) only dojo.js, back.js and resources/iframe_history.html are needed.