Enterprise AIR Development for JavaScript Developers
Post on 16-Nov-2014
7994 Views
Preview:
DESCRIPTION
Transcript
ENTERPRISE AIR ENTERPRISE AIR FOR JAVASCRIPT FOR JAVASCRIPT DEVELOPERSDEVELOPERSAndre Charland (andre@nitobi.com), Alexei White (alexei.white@nitobi.com)Nitobi Software, ltd.
Flex or Ajax?
Spaz (Twitter client)
http://funkatron.com/index.php/site/comments/spaz_a_twitter_client_for_mac_os_x_windows_and_linux/
Flex or Ajax?
iFreelance http://www.pixelfumes.com/blog/aug07/iFreelance.zip
Flex or Ajax?
Pownce http://www.pownce.com
About Us
Andre Charland Nitobi Usability & RIA Ajax Component suite Design and Development
Alexei White Nitobi Developer, Designer RIA (Ajax, Flash, etc) Nintendo, RobotReplay,
SayZu
Our Customers
The Nitobi Perspective – Components
Ajax User Interface Component suite (9)
Cross platform Java ASP.NET/ASP PHP Coldfusion
The Nitobi Perspective - Services
Enterprise Web Systems Development UI Visioning and development Intranets ‘In the field’ web systems
Consumer Web Systems Development Web strategy Application development
The Nitobi Perspective
Weighing the Alternatives
Rich Internet Applications (RIA)
Rich Internet Applications
AJAX Java
WebStart Applets JavaFX
Flash Flex Silverlight / WPF Adobe Integrated Runtime (AIR)
(Nobody uses this)
(Lame-o)
Why RIA?
User Retention Brand Development User Efficiency
Steps to complete a task Training costs Uninterrupted workflow Time spent waiting*
32
%
32
%
SA
VIN
GS
SA
VIN
GS
http://www.developer.com/java/other/article.php/3554271
AJAX Frameworks
Dojo Adobe Spry Script.aculo.us Prototype Moo.fx
Google Web Toolkit Mochikit Yahoo User Interface
Library Direct Web Remoting
(DWR) JQuery
Rico ASP.NET Ajax (Atlas) CakePHP AjaxTags Django
Rails-supported Sarissa SAJAX XAJAX Rialto
Nitobi Backbase TIBCO Nexaweb Laszlo
Telerik Infragistics IceSoft ActiveWidgets Dart
Gaia Ajax.NET Ajaxium Anthem.NET AjaxAspects Bitkraft ComfortASP.NET emergetk FastPage MagicAjax.NET mxAjax
Cajax Claw FURIA Guava HTS jPOP JPSpan My-BIC Kumbia NanoAjax Noculo PHPLiveX Picora Qcodo sniPEAR Symfony PAJAX PAJAJ Tigermouse XOAD
PHPLiveX Picora Qcodo sniPEAR Symfony PAJAX PAJAJ Tigermouse XOAD Zephyr ADF ADL
Restlet SWATO Tacos Telosys ThinkCAP JX Wicket WidgetServer Wonder XANDRA xWire ZK
AJASON aSSL AjaxAC Ajax Agent Cajax Claw FURIA Guava HTS jPOP JPSpan My-BIC Kumbia`
Cerny EXT JackBe Javeline JsLINB JsRia Macao OpenLink Plex Toolkit Qooxdoo
IWF Zimbra AjaxTk JuiseLib AjaxCaller AjaxGears AjaxToolbox AJFORM Jx/jxs Lokris MAJAX RSLite Sack UniAjax XHConn
Ajax Client Engine Ajax Queue Class Lumberjack JSLog jsTracer CAPXOUS Walter Zorn
Framework
SmartClient Subsys_jsHttpRequ
est ThyAPI TIBET twoBirds
AjaxCFC JSMX WDDXAJAX Akelos AModules3 AJASON aSSL AjaxAC Ajax Agent
MOJO Zapatec Component
One Farpoint DevExpress Janus
Why AIR Appeals to Ajax Developers Same skill set Great offline capabilities File-system and Desktop integration Code re-use Strengths of HTML
Cost of development Rapid prototyping Ease of distribution
Technology Growth
Ajax is better in AIR
Files (The Files are in the computer) Windows & Chrome Drag and Drop Copy and Paste (better) Offline Background process Notifications Keyboard Shortcuts
Usability Gotchas
Keyboard shortcuts (tab, enter…) Throbbers / Activity indicators – no
spinning IE Allow text to be copied Add functions for minimize, move, resize,
close when chromeless Mouse hints (invitations)
AIR Versus Web Desktop
What the heck is a Web Desktop? How is AIR the opposite of a Web
Desktop?
Practical AIR Applications
What Makes up a HTML AIR App? A JS-based AIR app always includes:
An HTML file An XML App Descriptor
May also include: External JavaScript and CSS files Documents and images Flash files
Hello World
<head><head><title>Untitled Document</title><title>Untitled Document</title></head></head>
<body><body>
<h1> Main Content </h1><h1> Main Content </h1><p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Praesent <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Praesent aliquam, justo convallis luctus rutrum, erat nulla fermentum diam, at aliquam, justo convallis luctus rutrum, erat nulla fermentum diam, at nonummy quam ante ac quam. Maecenas urna purus, fermentum id, nonummy quam ante ac quam. Maecenas urna purus, fermentum id, molestie in, commodo porttitor, felis. Nam blandit quam ut lacus. molestie in, commodo porttitor, felis. Nam blandit quam ut lacus. Quisque ornare risus quis ligula. Phasellus tristique purus a augue Quisque ornare risus quis ligula. Phasellus tristique purus a augue condimentum adipiscing. Aenean sagittis. Etiam leo pede, rhoncus condimentum adipiscing. Aenean sagittis. Etiam leo pede, rhoncus venenatis, tristique in, vulputate at, odio. Donec et ipsum et sapien venenatis, tristique in, vulputate at, odio. Donec et ipsum et sapien vehicula nonummy. Suspendisse potenti. Fusce varius urna id quam. Sed vehicula nonummy. Suspendisse potenti. Fusce varius urna id quam. Sed neque mi, varius eget, tincidunt nec, suscipit id, libero. In eget neque mi, varius eget, tincidunt nec, suscipit id, libero. In eget purus. </p>purus. </p>
</body></body></html></html>
<?xml version="1.0" encoding="utf-8" ?><?xml version="1.0" encoding="utf-8" ?><application <application xmlns="http://ns.adobe.com/air/application/1.0.M5"xmlns="http://ns.adobe.com/air/application/1.0.M5" appId="com.example.ExampleApplication"appId="com.example.ExampleApplication" version="1.0 Beta">version="1.0 Beta">
<name>HelloWorld</name><name>HelloWorld</name>
<description>My Test Application</description><description>My Test Application</description>
<copyright></copyright><copyright></copyright> <initialWindow><initialWindow> <title>HelloWorld</title><title>HelloWorld</title> <content>helloworld.htm</content><content>helloworld.htm</content> <systemChrome>standard</systemChrome><systemChrome>standard</systemChrome> <transparent>false</transparent><transparent>false</transparent> <visible>true</visible><visible>true</visible> </initialWindow></initialWindow> <icon></icon><icon></icon> <fileTypes><fileTypes> </fileTypes></fileTypes></application></application>
Think Outside the Box
Creative Applications
Nitobi Fisheye – in AIR
Nitobi Fisheye – in Firefox
SA
ME C
OD
ES
AM
E C
OD
E
Creating the Fisheye – 1/2
<img src="grabby.png" <img src="grabby.png" onmousedown="window.nativeWindow.startMove();" onmousedown="window.nativeWindow.startMove();" />/><img src="grabby.png" <img src="grabby.png" onmousedown="window.nativeWindow.startMove();" onmousedown="window.nativeWindow.startMove();" />/>
Creating the Fisheye – 2/2
Application.xml<?xml version="1.0" encoding="UTF-8"?><?xml version="1.0" encoding="UTF-8"?><application appId="com.adobe.nitobiDeskEye" version="1.0" <application appId="com.adobe.nitobiDeskEye" version="1.0" xmlns="http://ns.adobe.com/air/application/1.0.M4">xmlns="http://ns.adobe.com/air/application/1.0.M4"><name>DeskEye</name><name>DeskEye</name>
<installFolder>nitobi/AIR/DeskEye</installFolder> <installFolder>nitobi/AIR/DeskEye</installFolder>
<description>The Nitobi Fisheye running in an Adobe AIR environment</description><description>The Nitobi Fisheye running in an Adobe AIR environment</description><copyright>© 2007 Nitobi Inc.</copyright><copyright>© 2007 Nitobi Inc.</copyright><rootContent <rootContent systemChromesystemChrome="none" ="none" transparenttransparent="true" ="true" visiblevisible="true" ="true" widthwidth="800" ="800" heightheight="300">="300">
index.htmlindex.html</rootContent></rootContent></application></application>
C:\dev\air>adt –package DeskEye.air application.xml *C:\dev\air>adt –package DeskEye.air application.xml *
C:\dev\air>C:\dev\air>
C:\dev\air>adt –package DeskEye.air application.xml *C:\dev\air>adt –package DeskEye.air application.xml *
C:\dev\air>C:\dev\air>
A Hypothetical Enterprise App The requirements:
Allow in-the-field reps to access SF.com DB Make changes offline Take a VCARD from an email and easily
import it into the application Support Mac / PC / Linux (1.0) Branded UI Export contacts as VCARDS for use in
Outlook etc.
Solution: Salesforce Customer Manager SalesForce API (Salesforce.com AJAX
Connector 8.0) AIR
Ajax Client for SalesForce API Online/Offline (servicemonitor.swf) Drag and Drop File Parsing (Vcard) Saving XML Files to disk
Yup. Some simple examples.
In JavaScript? Really?
Problem 1 - Socket Communication How do we communicate with a foreign
web service? Model for socket communication is flexible Cross domain OK Tools for handling sparse connections Upload files Use non-supported protocols
Monitoring Remote WS
URLLoader simplifies XHR madness
Start with an existing web service: http://www.nitobi.com/air/customerservice
It returns XML:
Monitoring Remote WS
Build a web form in an HTML page:
Perform a URLRequest to retrieve the data based on the keyword.
<form onsubmit="performSearch(); return false;"><form onsubmit="performSearch(); return false;"> <p>Customer Search: <p>Customer Search: <input type="text" name="customerName" onkeyup="performSearch();" /> <input type="text" name="customerName" onkeyup="performSearch();" /> <input type=submit /></p><input type=submit /></p></form></form>
<br /><br /><div id="resultsBlock"></div><div id="resultsBlock"></div>
function performSearch() {function performSearch() {var url = "http://www.nitobi.com/air/customerservice?name=" + var url = "http://www.nitobi.com/air/customerservice?name=" +
document.forms[0].customerName.value;document.forms[0].customerName.value;var request = new air.URLRequest(url);var request = new air.URLRequest(url);var loader = new air.URLLoader();var loader = new air.URLLoader();loader.dataFormat=air.URLLoaderDataFormat.TEXT;loader.dataFormat=air.URLLoaderDataFormat.TEXT;loader.addEventListener(air.Event.COMPLETE,displayResults);loader.addEventListener(air.Event.COMPLETE,displayResults);loader.load(request);loader.load(request);
}}
air.ProgressEvent.PROGRESS, SECURITY_ERROR, OPEN, COMPLETE, HTTP_STATUS, IO_ERROR
Monitoring Remote WS
Grab the result, convert to an XML document
JSON is possible but requires extra steps Current security model inhibits use of eval();
function displayResults(event){function displayResults(event){var loader2=event.target;var loader2=event.target;var parser = var parser = new DOMParser();new DOMParser();var doc = var doc = parser.parseFromString(loader2.data,"text/xml");parser.parseFromString(loader2.data,"text/xml");var companyList = var companyList = doc.getElementsByTagName("company");doc.getElementsByTagName("company");
var resultString = ""var resultString = ""for (var i = 0; i < companyList.length; i++) {for (var i = 0; i < companyList.length; i++) {
resultString += companyList[i].firstChild.nodeValue + ", ";resultString += companyList[i].firstChild.nodeValue + ", ";}}document.getElementById('resultsBlock').innerHTML = resultString;document.getElementById('resultsBlock').innerHTML = resultString;
}}
Going Offline
Toolbox for working offline helps with business applications. Monitor network connectivity with
servicemonitor.swf Use local SQL database to cache data Reconnect later Transmit
Going Offline with servicemonitor.swf Checks connectivity to website or socket
connection Periodic polling
Going Offline with servicemonitor.swf Use of external SWF library
Checking availability of particular URL:
Checking availability of particular socket:
var monitor;var monitor;
function checkURLStatus(url) {function checkURLStatus(url) {var req = new air.URLRequest(url);var req = new air.URLRequest(url);monitor = new window.runtime.air.net.URLMonitor(req);monitor = new window.runtime.air.net.URLMonitor(req);monitor.pollIntervalmonitor.pollInterval = 5000; = 5000;monitor.addEventListener(air.StatusEvent.STATUS, monitor.addEventListener(air.StatusEvent.STATUS, showStatusshowStatus););monitor.start();monitor.start();
}}
function checkSocketStatus(host,port) {function checkSocketStatus(host,port) {monitor = new window.runtime.air.net.SocketMonitor(monitor = new window.runtime.air.net.SocketMonitor(hosthost, , portport););monitor.pollInterval = 5000;monitor.pollInterval = 5000;monitor.addEventListener(air.StatusEvent.STATUS, showStatus);monitor.addEventListener(air.StatusEvent.STATUS, showStatus);monitor.start();monitor.start();
}}
<script type="application/x-shockwave-flash" <script type="application/x-shockwave-flash" src="servicemonitor.swf"src="servicemonitor.swf"></script>></script>
Drag and Drop
File type associations Drag-on behavior Bidirectional
Drag and Drop
Add event listeners
Accept onEnter
Accept onDrop
function setupEvents() {function setupEvents() { window.htmlControl.addEventListener( runtime.flash.events.NativeDragEvent.NATIVE_DRAG_ENTER, doEnter );window.htmlControl.addEventListener( runtime.flash.events.NativeDragEvent.NATIVE_DRAG_ENTER, doEnter ); window.htmlControl.addEventListener( runtime.flash.events.NativeDragEvent.NATIVE_DRAG_DROP , doDrop ); }window.htmlControl.addEventListener( runtime.flash.events.NativeDragEvent.NATIVE_DRAG_DROP , doDrop ); }
function doEnter( event ) {function doEnter( event ) { runtime.flash.desktop.DragManager.acceptDragDrop( window.htmlControl ); }runtime.flash.desktop.DragManager.acceptDragDrop( window.htmlControl ); }
function doDrop( event ) {function doDrop( event ) { var fileString = '';var fileString = ''; var files = var files = event.transferable.dataForFormat(air.TransferableFormats.FILE_LIST_FORMAT,air.TransferableTransferMode.CLONEevent.transferable.dataForFormat(air.TransferableFormats.FILE_LIST_FORMAT,air.TransferableTransferMode.CLONE_PREFERRED );_PREFERRED ); for( var f = 0; f < files.length; f++ ) {for( var f = 0; f < files.length; f++ ) { var fileStream = new runtime.flash.filesystem.FileStream();var fileStream = new runtime.flash.filesystem.FileStream(); fileStream.open(files[f], runtime.flash.filesystem.FileMode.READ);fileStream.open(files[f], runtime.flash.filesystem.FileMode.READ); var fileBytes = new runtime.flash.utils.ByteArray();var fileBytes = new runtime.flash.utils.ByteArray(); fileStream.readBytes(fileBytes);fileStream.readBytes(fileBytes); var fileString = fileBytes.toString();var fileString = fileBytes.toString(); fileStream.close();fileStream.close(); }} displayGrid(fileString);displayGrid(fileString);}}
Drag and Drop
Draw the grid from the CSV data:function displayGrid(csvdata) {function displayGrid(csvdata) { dataSet = csvdata.split("\n");dataSet = csvdata.split("\n");
for (i = 0; i <dataSet.length; i++) {for (i = 0; i <dataSet.length; i++) { dataSet[i] = dataSet[i].split(",");dataSet[i] = dataSet[i].split(","); }}
var resString = "<form name=\"csvForm\"><table>";var resString = "<form name=\"csvForm\"><table>";
for (i = 0; i <dataSet.length; i++) {for (i = 0; i <dataSet.length; i++) { resString += "<tr>";resString += "<tr>"; for (b = 0; b <dataSet[i].length; b++) {for (b = 0; b <dataSet[i].length; b++) { if (!isNumeric(dataSet[i][b]) || (dataSet[i][b].length < 1)) {if (!isNumeric(dataSet[i][b]) || (dataSet[i][b].length < 1)) { resString += "<td style=\"background-color: #f0f0f0; font-weight:bold; color:#000099;\">" + resString += "<td style=\"background-color: #f0f0f0; font-weight:bold; color:#000099;\">" + dataSet[i][b] + "</td>";dataSet[i][b] + "</td>"; } else {} else { resString += "<td><input type=text name=\"c" + b + "_" + i + "\" value=\"" + dataSet[i][b] + "\" resString += "<td><input type=text name=\"c" + b + "_" + i + "\" value=\"" + dataSet[i][b] + "\" size=\"6\"></td>";size=\"6\"></td>"; }} }} resString += "</tr>";resString += "</tr>"; }}
resString += "</table></form>";resString += "</table></form>";
document.getElementById('tableData').innerHTML = resString;document.getElementById('tableData').innerHTML = resString;} }
File IO – Saving back to Excel Serialize your data to a string:
function serializeToXLS() {function serializeToXLS() { var resString = "<table>";var resString = "<table>"; for (i = 0; i <dataSet.length; i++) {for (i = 0; i <dataSet.length; i++) { resString += "<tr>";resString += "<tr>"; for (b = 0; b <dataSet[i].length; b++) {for (b = 0; b <dataSet[i].length; b++) {
if (!isNumeric(dataSet[i][b]) || (dataSet[i][b].length < 1)) {if (!isNumeric(dataSet[i][b]) || (dataSet[i][b].length < 1)) { resString += "<td style=\"background-color: #f0f0f0; font-weight:bold; resString += "<td style=\"background-color: #f0f0f0; font-weight:bold; color:#000099;\">" + dataSet[i][b] + "</td>";color:#000099;\">" + dataSet[i][b] + "</td>";
} else {} else { resString += "<td>" + document.forms["csvForm"]["c" + b + "_" + i].value + "</td>” resString += "<td>" + document.forms["csvForm"]["c" + b + "_" + i].value + "</td>” } }}}resString += "</tr>";resString += "</tr>";
}} resString += "</table>";resString += "</table>"; return resString;return resString;
}}
JavaScript String
File IO – Saving back to Excel Use FileStream to write to the disk
Deposit file on Desktop or any other location
OS Independent Charset aware.
function saveData() {function saveData() {var file = var file = air.File.desktopDirectory.resolvePath("out.xls");air.File.desktopDirectory.resolvePath("out.xls");var stream = var stream = new air.FileStream();new air.FileStream();stream.open(file, air.FileMode.WRITE );stream.open(file, air.FileMode.WRITE );stream.writeMultiByte( serializeToXLS(), air.File.systemCharset );stream.writeMultiByte( serializeToXLS(), air.File.systemCharset );stream.close();stream.close();
}}
Changes to Ajax Security
Beta 2 introduces improved security model
Different security sandboxes Prevent Cross site Scripting Script Injection
What does it all mean?
Market Opportunities
API Libraries File Libraries Advanced features – syncing, etc.. Casual games Downloadable games
AIR Resources
http://www.nitobi.com/air/ Enterprise Ajax
www.enterpriseajax.com Kevin Hoyt’s AIR Examples
http://blog.kevinhoyt.org/2007/06/27/35-air-examples-for-javascript-developers/
AIR for JavaScript Developers (Pocket Guide) http://ajaxian.com/archives/adobe-air-free-book-download
Adobe Labs Ajax Resources http://labs.adobe.com/technologies/air/develop_ajax.html
Dreamweaver Extension for AIR http://labs.adobe.com/wiki/index.php/
AIR:Dreamweaver_CS3_Extension AIR Downloads
http://labs.adobe.com/downloads/air.html
Ask us Questions
35% Discount CouponEmail andre@nitobi and mention the OnAirBusTour.
Andre Charlandwww.nitobi.com http://blogs.nitobi.com/andre andre@nitobi.com
Alexei Whitewww.nitobi.com http://blogs.nitobi.com/alexei alexei.white@nitobi.com
top related