HTML5-Highlights in APEX verwenden Andreas Wismann WHEN OTHERS Beratung | Projektmanagement | Coaching rund um Oracle Application Express … rund um Application Express Beratung | Projektmanagement | Coaching Andreas Wismann [email protected] +49 176 7800 3109 APEX Themes DOCTYPE • früher beispielsweise: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> • für HTML5: <!doctype html> • Schreibweise beliebig: <!DOCTYPE HTML> <!DOCTYPE html> <!doctype HTML> Minimaldokument HTML5 <!doctype html> <html lang=de> <head> <meta charset=utf-8> <title>HTML5</title> </head> <body> Hallo Welt </body> </html> Minimaldokument HTML5 <!doctype html> <html lang="de"> <head> <meta charset="utf-8"> <title>HTML5</title> </head> <body> Hallo Welt </body> </html> Welcher Browser unterstützt was? Demo 1 Welcher Browser unterstützt was? HTML5-Features zur Laufzeit prüfen • Modernizr (2.5.3 eingebaut in Theme 25) Demo 2 Welcher Browser unterstützt was? • Empfehlung: caniuse.com ("can I use") Graceful Degradation 1. Mindestfunktionen bereitstellen Textfelder und Buttons 2. Beherrscht der Browser HTML5? Prüfroutine in JavaScript 3. dann Zusatzfunktionen anbieten JavaScript ändert Textfelder zu Dragand-Drop-Flächen So nicht … nur kurz erwähnt … • Web SQL Database Spezifikation und Entwicklung werden offenbar z. Zt. nicht fortgeführt • Drag and Drop jQuery & Co. haben längst bessere Implementierungen • File API Lesen von Dateien vor dem Upload (kein geskripteter Vollzugriff auf das Dateisystem, sondern gekoppelt an Button) Progress-Bar • Fortschrittsbalken • Konfigurierbare Skala und Animation • Sehr ausführliche Anleitung unter http://www.useragentman.com/blog/2012/01/03/cross-browser-html5-progressbars-in-depth/ <audio>, <video> • Nativer Player für Multimedia-Dateien • Abspielen von Audio in den Formaten WAV, MP3, Ogg • Abspielen von Videos mit geeigneten Codecs • H.264, webM, V8, Ogg • kein DRM unterstützt Neue Dokumentgliederung <article> <aside> <footer> <header> <hgroup> <nav> <section> <small> Eigenständiger Inhaltsabschnitt Seitenbereich Fußbereich Kopfbereich Überschriftengruppierung Navigation, Menü Unterabschnitt "Kleingedrucktes" (Disclaimer) Navigation ein- und ausblenden $('nav').toggle(); APEX-Demo Exkurs: JavaScript in Navigation Bar • Entry vom Typ "URL" erzeugen • URL Target: #" onclick="$('nav').toggle();return false • Ergebnis: <a href="#" onclick="$('nav').toggle();return false">NAV</a> HTML5-Elemente in "alten" Browsern <p>Dies ist ein Absatz</p> Demo 3 <section> <p>Dies ist ein Absatz</p> </section> Canvas APEX-Demo • Pixel- und Vektorgrafiken • Bitmaps, Pfade, Formen, Farbverläufe, Muster • Transformatoren (Rotation, Skalierung, Image-Filter, …) • Export in Datei • processing.js (http://processingjs.org) Canvas Community-Beispiel von Carsten Czarksi: CANVAS zur Visualisierung von Tablespaces https://blogs.oracle.com/apexcommunity_deutsch/de/ https://blogs.oracle.com/apexcommunity_deutsch/entry/html5_für_apex_entwickler_anwendungen navigator.geolocation • getCurrentPosition • watchPosition • clearWatch Geolocation Beispiel var target = { latitude : 0, } longitude: 0, var options = { enableHighAccuracy: false, timeout: 5000, maximumAge: 0 }; var id = navigator.geolocation.watchPosition(success, error, options); function success(pos) { var crd = pos.coords; if (target.latitude === crd.latitude && target.longitude === crd.longitude) { console.log('Sie haben Ihr Ziel erreicht'); navigator.geolocation.clearWatch(id); }}; function error(err) { console.warn(err.message); }; Neue Eingabefeld-Typen <input <input <input <input <input type="date"> type="datetime"> type="email"> type="month"> type="number"> <input <input <input <input <input <input Demo 4 type="range"> type="search"> type="tel"> type="time"> type="url"> type="url"> Input-Plugins für APEX http://apex-plugin.com/oracle-apex-plugins/item-plugin/html5-input-item_107.html neue Input-Attribute … <input type = "text" value = "" autofocus required autocomplete = "off" placeholder = "Bitte ausfüllen" pattern = "^[0-9]{5}$" min = "5" max = "9999" /> Demo 5 CSS für die Validierung Demo 6 :invalid { background-color: red; } :valid { background-color: green; } input:invalid { background-color: red; } input:valid { background-color: green; } // durch Button die Klasse "ckecked" zuweisen… form.checked input:invalid { background-color: red; } form.checked input:valid { background-color: green; } Selbstdefinierte Attribute <input type = "text" value = "Spülmaschine" data-partno="BX-245788" data-price="499.00" /> Mit dem Namensprefix data- sind eigene Attributkreationen im HTML5-Standard möglich. navigator.onLine $('form').submit(function(){ if(navigator.onLine) { return true; } else { alert('keine Verbindung zum Server'); // Daten lokal speichern … return false; } }); Web Messaging • Nachrichten zwischen Domänen versenden • Beispiel: IFRAME-Formulare aus anderen Applikationen • Kommunikation zwischen Browserfenstern Web Messaging Sender: var o = document.getElementsByTagName('iframe')[0]; o.contentWindow.postMessage('Hallo', 'http://example.com/'); Empfänger: window.addEventListener('message', receiver, false); function receiver(event) { if (event.origin == 'http://example.com/') { if (event.data == 'Hallo') { event.source.postMessage('Selber hallo ', event.origin); } else { alert('Kommunikation mit ' + event.origin + ' ist unzulässig'); } } } Web Storage DatenbankServer "Web Storage" lokale Disk Begriffsvielfalt Web Storage ( DOM Storage ) Local Storage Session Storage Web Storage vs. Cookies Web Storage Cookies Anzahl unbegrenzt 20 Cookies pro Domain Volumen 5 MB pro Domain (typ.) 4 kB pro Cookie Gültigkeitsdauer Unbegrenzt (Local Storage) Session (Session Storage) Session oder begrenzt Teil des http-Dialogs nein ja Deaktivierung per Konfigurationseingriff im Browsermenü Verfügbarkeit in modernen Browsern in praktisch allen Browsern Local und Session Storage API Local Storage Schreiben localStorage.setItem ('key','value') localStorage.key='value' value = localStorage('key') Lesen value = localStorage.key Anzahl Einträge n = localStorage.length Key löschen localStorage.removeItem('key') alle Keys löschen localStorage.clear() je nach Bedarf localStorage durch sessionStorage ersetzen Hinweise zu Web Storage • Es werden Stringwerte gespeichert, "17" + "4" ergibt "174" • Objekte umwandeln und speichern: localStorage.key = JSON.stringify(object) • Objekte auslesen: object = JSON.parse(localStorage.key) jStorage http://www.jstorage.info/ • normalisiert die lokale Speicherung • bereits ab IE 6 (max. 128 kB) • implementiert einen Change Listener jStorage Browser Support Demo 7+a Application Cache • Definition von Dateien, die der Browser stets offline cachen darf • Typisch: CSS, JavaScript, statisches HTML • Konfiguration über Manifest-Datei Web Worker • Clientseitige "Threads" • Langwierige Berechnungen auslagern • Browser bleibt bedienbar Demo 8 Web Sockets • Bidirektionale Verbindung zwischen Server und Browser • Polling: Server kann Nachrichten senden • Latenz der Anwendung minimieren • Einfach zu implementieren: nodejs Live-Demo Web Sockets var socket = new WebSocket('ws://127.0.0.1:1337'); socket.onmessage = function (event) { alert(event.data); } • "Twitter"-Feeds • Daten-Aktualisierungen • Socket-Server muss nicht die Datenbank sein (Fremdanbieter, dedizierter Server, jsnode, …) Web Socket (serverseitig) CREATE OR REPLACE PACKAGE BODY websockets IS PROCEDURE push ( p_text IN VARCHAR2 ) IS l_clob CLOB; BEGIN l_clob := APEX_WEB_SERVICE.MAKE_REST_REQUEST ( p_url => 'http://127.0.0.1:1337' , p_http_method => 'POST' , p_body => '{"message":"'||p_text||'"}' ); END push; END websockets; Web Socket (serverseitig) BEGIN -- Daten-Änderung irgendwo in der Datenbank: UPDATE emp SET sal=sal+1 WHERE ename = 'KING'; COMMIT; -- Mitteilung an alle verbundenen -- APEX-Clients senden: websockets.push('REFRESH'); END; APEX-Report mit Websocket updaten $(function(){ window.WebSocket = window.WebSocket || window.MozWebSocket; if (!window.WebSocket) { console.log('Browser unterstützt die Websockets-Spezifikation nicht'); } else { var connection = new WebSocket('ws://127.0.0.1:1337'); connection.onerror = function (error) { console.log( 'Problem bei der Websocket-Kommunikation'); }; connection.onmessage = function (message) { try { var json = JSON.parse(message.data); if (json.message=='REFRESH') { apex.jQuery('#demoReport').trigger('apexrefresh'); // demoReport ist die statische ID des Interactive Reports } else { console.log(json.message); } } catch (e) { console.log('Ungültiges JSON-Format: ' + message.data); } }; } }); nodejs.org Tipps & Tricks zu nodejs • Anleitung zur Verwendung von node.js als Websocket-Server in Verbindung mit APEX: http://emoracle.wordpress.com/2012/04/11/using-websockets-in-apex-for-automatic-refresh-with-nodejs/ • Installation des nodejs-Moduls "websockets" unter Windows 7 funktionierte nur so: npm install [email protected] --force siehe http://stackoverflow.com/questions/14152635/node-js-websocket-module-installed-but-wont-work-in-scripts Websocket-Server • Eine Alternative: u.a. Beaconpush (beaconpush.com) • extern gehostet, kostenpflichtig, inkl. Support Empfehlungen • Bruce Lawson, Remy Sharp (D) • Setzt HTML- und JavaScript-Kenntnisse voraus • Knackige Codebeispiele • Lockerer Stil • nicht ganz aktuell, 2011 Empfehlungen • "Head First"-Reihe (D) • Fokus auf JavaScriptEinstieg • viele Illustrationen … rund um Application Express Beratung | Projektmanagement | Coaching Andreas Wismann [email protected] +49 176 7800 3109