220 likes | 386 Views
Spiffy client-side APIs for mobile. http://www.flickr.com/photos/yourdon/3599753183/. Going from good to great on the client. Form validation Persistence Geolocation Canvas Orientation Detecting mobile Hiding browser chrome Custom bookmark icons. Form validation.
E N D
Spiffy client-side APIs for mobile http://www.flickr.com/photos/yourdon/3599753183/
Going from good to great on the client Form validation Persistence Geolocation Canvas Orientation Detecting mobile Hiding browser chrome Custom bookmark icons
Form validation • Validation = checking if data values are ok • Crucial for security, reliability and usability • Prevents users from… • Putting evil data into your database • Crashing your web page (e.g., using "Bob" as an int) • Getting confused about why stuff doesn't work right
Validate inputs on the client & server • Validation on the client • Help the user to find and fix mistakes fast • Validation on the server • Help protect your database and web app Web server Browser Validate Validate
Declarative validation with jQuery <!DOCTYPE html> <html> <head> <title>Your page title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" /> <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script> <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script> <script src="jquery.validate.js"></script> <script> $(document).bind('pageinit', function() { $("#frm").validate(); }); </script> <style> label.error {color: red; display: block; padding-bottom: 10px; } </style> </head> <body> <div data-role="page"><div data-role="header"><h1>Some page title</h1></div><div data-role="content"> <form id="frm"> Some text: <input class="required" name="mytext"><BR> Some email: <input class="required email" name="myemail"><BR> Some int: <input class="required digits" name="myint"><BR> <input type="submit" value="OK"> </form> </div></div></body></html>
jquery.validate.js • Currently available from • http://jqueryjs.googlecode.com/svn-history/r6243/trunk/plugins/validate/jquery.validate.js • Supported validation classes • required: This field is required • remote: Please fix this field • email: Please enter a valid email address • url: Please enter a valid URL • date: Please enter a valid date • number: Please enter a valid number • digits: Please enter only digits, • creditcard: Please enter a valid credit card number • equalTo: Please enter the same value again • accept: Please enter a value with a valid extension • maxlength: Max # characters allowed • minlength: Min # characters allowed • max: Max number value allowed • min: Min number value allowed
If you want to write your own jQuery validation plugin, you may need these APIs $("#elementid").val() • Retrieves the value of some HTML form element $("<span id='myspan'></span>").insertAfter("#elementid") • Creates a span and inserts it after someNode $("#elementid").bind('change', jsFunction); • Registers jsFunction to be called on a change event, such as function jsFunction() {alert($(this).text());} $("#myspan").show() and .hide() • Makes an element visible or invisible $(".myclass").each(someFunction) • Runs someFunction on each item in wrapped set $("div.myclass").get(0) • Gets the first actual DOM node (unwrapped) in the wrapped set
Persistence • Data stored on the client side • Provides a means for user-customization • Eliminates the need to retrieve the data off server • Facilitates off-line mode for web sites • Options available to you • Local storage: short strings, not automatically copied • Cookies; short strings, automatically copied to server • Database: structured data, not automatically copied
Persistence with local data • You can store data on the user's flash memory (or hard drive), then retrieve it later on. • Such data is not automatically sent to servers • As with cookies and client databases, all local data is stored unencrypted.
localStorage example <!DOCTYPE html> <html> <head> <title>Your page title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" /> <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script> <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script> <script src="jquery.validate.js"></script> <script> $(document).bind('pageinit', function() { if (!window["localStorage"]) { alert("No local storage. Should use cookie instead."); } else { varcurrentCount = localStorage["count"]; varcountAsNumber = parseFloat(currentCount); countAsNumber = isNaN(countAsNumber) ? 1 : countAsNumber+1; localStorage["count"] = countAsNumber; $("#counter").text(countAsNumber); } }); </script> <style> label.error {color: red; display: block; padding-bottom: 10px; } </style> </head> <body> <div data-role="page"><div data-role="header"><h1>Some page title</h1></div><div data-role="content"> <div id="counter"></div> </div></div></body></html>
Other local persistence options • Covered in CS494 • Cookies: strings automatically sent to the server • Local database: structured data not sent to server • APIs are in flux at the moment • Should settle out
Geolocation <!DOCTYPE html> <html> <head> <title>Your page title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" /> <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script> <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script> <script src="jquery.validate.js"></script> <script> $(document).bind('pageinit', function() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(callbackFunction); } else { alert("Not supported"); } }); function callbackFunction(pos) { $("#latlong").text("lat:"+pos.coords.latitude+";long:"+pos.coords.longitude); } </script> <style> label.error {color: red; display: block; padding-bottom: 10px; } </style> </head> <body> <div data-role="page"><div data-role="header"><h1>Some page title</h1></div><div data-role="content"> <div id="latlong"></div> </div></div></body></html>
Geolocation cautions • Don't repeatedly read location in a tight loop • This would use up the battery very quickly. • If you need to repeatedly read location, use setTimeout with a long timer (minutes, at least). • Don't assume that geolocation will work • Some devices have geolocation turned off • Emulator won't work unless you configure it using telnet… usually not worth the effort: just borrow a real phone. • Users can decline to give your app permission • Provide a reasonable default in case of no geoloc!
Drawing pictures on canvas <!DOCTYPE html> <html> <head> <title>Your page title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" /> <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script> <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script> <script src="jquery.validate.js"></script> <script> $(document).bind('pageinit', function() { varmyCanvas = $("#canvas1").get(0); var context = myCanvas.getContext("2d"); context.fillStyle = "#00ff00"; context.fillRect(10, 40, 100, 200); // x, y, width, height context.strokeStyle = "#ff0000"; context.moveTo(200, 300); // x, y context.lineTo(350, 350); // x, y context.stroke(); }); </script> <style> label.error {color: red; display: block; padding-bottom: 10px; } </style> </head> <body> <div data-role="page"><div data-role="header"><h1>Some page title</h1></div><div data-role="content"> <canvas id="canvas1" height="400" width="400" ></canvas> </div></div></body></html>
Touch and move on a canvas • Touch only works well on real devices • Some code to get your started $('#mycanvas').bind('touchstarttouchmovetouchend', function(e){ // disable default behavior to implement your own e.preventDefault(); e.stopPropagation(); var touches = e.originalEvent.changedTouches;
Reading orientation (part 1) <!DOCTYPE html> <html> <head> <title>Your page title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" /> <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script> <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script> <style> #block { width: 200px; height: 150px; border: 1px solid black; display: inline-block; vertical-align: top; } .btn { padding: 10px 10px10px10px; } #main { text-align: center; } </style> </head> <body> <div data-role="page"> <div data-role="header"><h1>Random walk</h1></div> <div data-role="content" id="main"> <div id="block">CS496 something somethingsomethingsomethingsomethingsomethingsomethingsomething something</div> <div id="controls"> <div class="btn">Button1</div> <div class="btn">Button2</div> <div class="btn">Button3</div> </div> </div>
Reading orientation (part 2) <script> $(function() { // $(window).bind('resize', layout); // $(window).bind('devicemotion', layout); $(window).bind('orientationchange', layout); function layout() { varwid = $(window).width(); varhgt = $(window).height(); if (wid > hgt) { $("#controls").css("display", "inline-block"); $(".btn").css("display", "block"); } else { $("#controls").css("display", "block"); $(".btn").css("display", "inline-block"); } } layout(); }); </script> </div></body></html>
About device rotation • The purpose of different events… • Detect orientationchange if you just want to tell when user goes from portrait to landscape • Detect resize to detect window dimension change • Detect devicemotion to read acceleration • Of the three events, this uses the most CPU and battery because lots of these events would be generated • Hard to say if all of these work on all phones • Consider detecting resize andorientationchange any time you want orientation change
Detecting mobile • You can have a single site that looks good in mobile OR desktop browsers • Just output a different stylesheet reference depending on user agent (or screen.width) var MOBILE = navigator.userAgent.match( /Android|BlackBerry|iPhone|iPad|iPod|IEMobile/i) ? true : false; document.write("<link rel=stylesheethref='mobile"+MOBILE+".css'>");
Full-screen (hiding chrome) • For when user bookmarks site to iOS "home" <meta name="apple-mobile-web-app-capable" content="yes" /> <link rel="apple-touch-icon-precomposed" href="logo.png"/> • Android (document must be at least as long as the window is high – add content if needed!) <script>window.scrollTo(0,0); </script>
Custom bookmark icons Different devices & operating systems will use different icons. Check docs often for updates. <link rel="apple-touch-icon" sizes="72x72" href="ipad7272.png" /> <link rel="apple-touch-icon" sizes="114x114" href="114114iphoneretina.png" /> <link rel="apple-touch-icon" sizes="144x144" href="144144ipadretina.png" /> <link rel="apple-touch-icon" href="4848default.png" /> <link rel="apple-touch-icon-precomposed" href="4848shaded.png"/>
There's always more to learn • For your How-To, consider covering a JS API • For ideas, refer to • http://diveintohtml5.info • http://www.html5rocks.com/en/mobile • http://jquerymobile.com/demos/1.2.0/ • http://jquery.com