prototype 1.7

98
Prototype

Upload: msebel

Post on 13-Apr-2017

659 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Prototype 1.7

Prototype

Page 2: Prototype 1.7

Inhalte Prototype

AjaxResponders, Response, Request, (Periodical)Updater

DOMJSON, $, $F, Abstract, Element, Form, document

SpracherweiterungenWeitere $‘s, Array, Class, Date, Function, Object, String,Template, Enumerable, RegExp, Prototype/Try

Page 3: Prototype 1.7

Prototype: Ajax.Responders

FunktionGlobale Events/Callbacks für alle Ajax Requests

RegistrationAjax.Responders.register/unregister

CallbacksonCreate, onComplete, onException

Page 4: Prototype 1.7

Prototype: Ajax.Responders

Herkömmlicher Ajax Responder

Ajax.Responders.register({onCreate: function(request,XmlHttpRequest,Json) {

alert('new request registered');Ajax.activeRequestCount++;

},onComplete: function(request,XmlHttpRequest,Json) {

alert('request has ended');Ajax.activeRequestCount--;

}});

Page 5: Prototype 1.7

Prototype: Ajax.Request

FunktionGewöhnlicher Ajax Request

Wichtige Optionenasynchronous = true: (A)synchrone AnfragecontentType: Ändern wenn man z.B. XML senden willencoding = UTF8: Falls es mal Probleme mit Kodierung gibtparameters: Parameter im URL oder JSON Format

Wichtige CallbacksonFailure: Wird bei HTTP Errors geworfen 40x – 50xonSuccess: Kommt zum Zug bei 20x Statuscodes

Page 6: Prototype 1.7

Prototype: Ajax.Request

JSON Antwortobjekt

var data = {};data.getres = 1001;data.language = SV_LANG_DE;data.isIE = true;

new Ajax.Request('/pfad/zum/script/?id=685', {parameters : data,method : 'post',onSuccess: function(response) {

var json = response.responseText.evalJSON();alert('Antwort: ' + json.message);

}});

Page 7: Prototype 1.7

Prototype: Ajax.Request

Synchroner Request

var data = {};data.getres = 1001;data.language = SV_LANG_DE;data.isIE = true;

var myRequest = new Ajax.Request('/service/class/getres/', {parameters : data,method : 'post',asynchronous : false

});

alert(myRequest.transport.responseText);

Page 8: Prototype 1.7

Prototype: Ajax.Response

FunktionAntwortobjekt eines Ajax.Request

Wichtige PropertiesresponseText: Text der Ajax AntwortresponseXML: XMLDOM Objekt, wenn application/xml Header responseJSON: JS Objekt, wenn application/json Headertransport: Zugriff auf das Native XmlHttpRequest Objekt

Page 9: Prototype 1.7

Prototype: Ajax.Updater

FunktionUpdatet einen Container, erbt von Ajax.Request

Und wozu ist das gut?- Vereinfachung eines oft verwendeten Use-Case- Verwendet das verhalten von Element.update()

Zusätzliche PropertiesevalScripts = false: Führt Code in <script> Tags ausinsertion: Mögliche Werte: top, bottom, before, after-> Mehr dazu bei den Element Methoden

Page 10: Prototype 1.7

Prototype: Ajax.Updater

Codebeispiel

<script type="text/javascript">function UpdateChat() {

new Ajax.Updater({ success: 'chatWindow' }, '/getmessage/?chat=45764',{ insertion: 'top‚ }

);setTimeout('UpdateChat()',1000);

}UpdateChat();

</script><div id="chatWindow"></div>

Page 11: Prototype 1.7

Prototype: Ajax.PeriodicalUpdater

FunktionWie Updater, führt sich aber periodisch selbst wieder aus

Wichtige Optionenfrequency = 2: Warten zwischen Abfragendecay = 1: Erhöht die Rate von frequency, wobei der übergebene Wert ein Multiplikator ist. 1 Hat daher keine Wirkung, 2 z.B. verdoppelt den Wert von frequency. Wenn Resultat !=, wird frequency zurückgesetzt.

Nutzen- Sehr wenig Code nötig für automatische Updater- Spart Ressourcen durch den decay Parameter

Page 12: Prototype 1.7

Prototype: Ajax.PeriodicalUpdater

Codebeispiel

<script type="text/javascript">new Ajax.PeriodicalUpdater(

{ success: 'chatWindow'‚ failure : 'errorMsg' }, '/getmessage/?chat=34756',{ insertion: 'top', frequency: 2 }

);</script><div id="chatWindow"></div><div id="errorMsg"></div>

Page 13: Prototype 1.7

Kurze Einführung: JSON

Wer ist Jason?Die Javascript Object Notation

Wozu wird es verwendet?- Objektorientiertes Javascript- Interner Datenaustausch (z.B. Funktionsparameter)- Externer Datenaustausch (z.B. Ajax)

SyntaxProperties, Arrays, Objektarrays, Funktionen…… mit relativ wenig Zeichen (Leichtgewichtig)

Page 14: Prototype 1.7

Kurze Einführung: JSON

Einfache Daten und Arrays

var object = {message : 'this is json',really : true,howmany : 1337,inner : {

value : 'inneres objekt',great : false

},array : [ 1,2,3,4,5,6,7,8 ],strings : [ 'hello', 'world' ]

};

Page 15: Prototype 1.7

Kurze Einführung: JSON

Objektarrays (Einfaches verschachteln)

var object = {objectarray : [

{ message : 'this is json', really : true },{ message : 'this is xml', really : false },{ message : 'this is asp', really : false }

],additional : 'hello world'

};

Page 16: Prototype 1.7

Kurze Einführung: JSON

Funktionen (Dazu mehr unter „Klassen“)

var Calculator = {Add : function(param1,param2) {

return(param1 + param2);},Subtract: function(param1,param2) {

return(param1 – param2);},

};

Page 17: Prototype 1.7

Prototype: $... Die Funktion

FunktionAlias für document.getElementById und mehr

Wie mehr?$(‘eleID‘) gibt ein Element zurück$(‘eleID‘,‘inputID‘,‘textID‘) gibt ein Array zurückDOM der Elemente wird erweitert (Dazu gleich mehr)

NutzenEffizienter / besser lesbarer Code

Page 18: Prototype 1.7

Prototype: $... Die Funktion

Typischer Code einer Validierungsroutine

// Validierbares Element holenvar ele = document.getElementById('eleID');// Array von Werten für For bastelnvar some = [];some[0] = document.getElementById('eleID');some[1] = document.getElementById('inputID');some[2] = document.getElementById('textID');// Error Message Divs ausblendendocument.getElementById('errorMessage').style.display = 'none';document.getElementById('errorDiv').style.display = 'none';

Page 19: Prototype 1.7

Prototype: $... Die Funktion

Typischer Code gleicher Code mit Prototype

// Validierbares Element holenvar ele = $('eleID');// Array von Werten für For-Schlaufevar some = $('eleID','inputID','textID');// Mit „hide“ Funktion auf allen Elementen, Divs ausblenden$('errorMessage','errorDiv').invoke('hide');

Anmerkung: Die hide() und show() Methode ist nur eine derzahlreichen DOM Erweiterungen die jedes Element bekommt

Page 20: Prototype 1.7

Prototype: Geht‘s noch schneller?

Eine Nanosekunde effizienterJa, mit der $F() Methode

Formularwert holenErwartet eine ID als Wert, und gibt den Wert des dahinterliegenden Formularfeldes mit der getValue() Methode zurück.

$(‘example‘).getValue()Gleich wie .value Property ausser bei Multiselect,da kommt immer ein Array zurück

Page 21: Prototype 1.7

Prototype: Geht‘s noch schneller?

Schnell ein Formular speichern

var Assistant = Class.create();Assistant.prototype = {

Save : function() {new Ajax.Request('/admin/content/?id=324',

method : 'post',parameters : {

'Name' : $F('Name'),'Firstname' : $F('Firstname'),'Email' : $F('Email')

});

}};

Page 22: Prototype 1.7

Prototype: Klassen

Objektbasiert?Orientiert, wir können Abstrakt.

Wie kann man vorgehen- Klasse leer erstellen und Body erweitern- Klasse direkt vollständig ausprogrammieren

EigenheitenKlassendefinitionen sind zur Laufzeit erweiterbar (Für alle Instanzen)Statische Properties kennt Javascript nichtPublic, Private, Protected? Umsetzbar, aber kein Bestandteil

Page 23: Prototype 1.7

Prototype: Klassen

Erstellen und erweitern…

var Assistant = Class.create();Assistant.prototype = {

// Konstruktorinitialize : function() {

},

// SpeicherfunktionSave : function() {

alert('data saved');}

};

Page 24: Prototype 1.7

Prototype: Klassen

…oder direkt ausprogrammieren

var Assistant = Class.create({

// Konstruktorinitialize : function(id) {

// Hier sind meist window.onload/dom:loaded Events},

// SpeicherfunktionSave : function() {

alert('data saved');}

});

Page 25: Prototype 1.7

Prototype: Klassen

Erben des einer Klasse

var BetterAssistant = Class.create(Assistant,{

// Konstruktorinitialize : function($super,id) {

// Parent Methode aufrufen, geht bei allen überschriebenen

$super(id);},

// Speicherfunktion überschreibenSave : function($super) {

this.Validate(); // Erst validieren$super();

}});

Page 26: Prototype 1.7

Prototype: Klassen

Methoden überschreiben (Clean way)

BetterAssistant.addMethods({// Speichern geht noch besserSave : function($super) {

// Validieren und speichern$super();// Meldung an User gebenthis.Notify();

},// Meldung an UserNotify : function() {

$('message').update('Daten gespeichert!');$('message').show();

}});

Page 27: Prototype 1.7

Prototype: Element Erweiterungen

Wie bekomme ich die ErweiterungenMit Element.method() oder $(‘someElement‘).method()

Einige Beispiele- Element.update(): Ein Block Element verändern- Element.setStyle()/getStyle(): CSS, Browserkompatibel- Element.show()/hide()/toggle(): Anstatt direkt CSS zu modifizieren- Element.absolutize()/relativize(): Element Positionstyp ändern- Element.removeClassName()/addClassName(): Sprechend- Und 76 weitere Methoden

Welche wir hier findenGibt es hier: http://api.prototypejs.org/dom/element/

Page 28: Prototype 1.7

Prototype: Element Erweiterungen

Element.update() - Beispiel

var html = '<p>Gleich passiert was<p>' +'<script type="text/javascript">' +' alert("sehen sie?");' +'</script>';$('message').update(html);

Page 29: Prototype 1.7

Prototype: Element Erweiterungen

Anwendung der toString() Methode mit Element.Update()

var Fruit = Class.create({initialize : function(name) {

this.Name = name;}toString: function() {

return('Hey ' + this.Name + '! I'm an orange.');}

});var apple = new Fruit('apple');$('fruits').update(apple);$('fruits').innerHTML;

Page 30: Prototype 1.7

Prototype: Element Erweiterungen

Klassen hinzufügen oder entfernen

<div id="msg" class="float left invisible">&nbsp;</div><script type="text/javascript">

$('msg').addClassName('visible','error');$('msg').removeClassName('invisible');// -> float left visible error// -> toggleClassName(cssClass)

</script>

Page 31: Prototype 1.7

Prototype: Element Erweiterungen

XML Arbeit vereinfachen

<ul id="apples"><li>Mutsu</li>

</ul><script type="text/javascript">

$('apples').firstChild.innerHTML;// -> undefined$('apples').cleanWhitespace();$('apples').firstChild.innerHTML;// -> 'Mutsu'

</script>

Page 32: Prototype 1.7

Prototype: Element Erweiterungen

Elementinhalt Erweitern oder umranden

// Paragraph in ein Element einbauen$('element').insert('<p>HTML to append</p>');// Fügt über den Paragraphen ein Bild ein$('element').insert({

top: Element('img', {src: 'logo.png'})});// Fügt vor und nach dem Element ein HR ein$('element').insert({

before: '<hr>',after: '<hr>'

});

Page 33: Prototype 1.7

Prototype: Element Erweiterungen

Element bzw. Object.inspect()

$('element').inspect();// -> <div id="element" class="hello world">Object.inspect();// -> 'undefined'Object.inspect(null);// -> 'null'Object.inspect(false);// -> 'false'Object.inspect([1, 2, 3]);// -> '[1, 2, 3]'Object.inspect('hello');// -> "'hello'"

Page 34: Prototype 1.7

Prototype: Element.Layout

WozuVerschiedene Grössen/Abstände eines Elements lesen

Vorteile- Geht auch, wenn alles in CSS definiert ist- Umgeht die Tendenz, dass Browser inkorrekte Werte liefern- Umgeht den Quirksmodus, welcher meist gar nichts liefert- Umgeht die Schwierigkeit mit unsichtbaren Elementen

VorsichtDa Resourcenintensiv sind die Werte gecached!

Page 35: Prototype 1.7

Prototype: Element.Layout

Instanz des Layout Objekts holen

// Mit der Element Methode verwendenlayout = new Element.Layout(element);// Als Instanzmethode eines Elementslayout = $('element').getLayout();// Wert lesen, CSS Version ausgebenvar pl = layout.get('padding-left');var css = layout.toCSS();

Page 36: Prototype 1.7

Prototype: Element.Layout

Weitere Properties

height, widthtop, left, right, bottomborder-left, border-right,border-top, border-bottompadding-left, padding-right, padding-top, padding-bottommargin-top, margin-bottom, margin-left, margin-rightpadding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height

Page 37: Prototype 1.7

Prototype: Event Objekt

Events: Ein geordnetes ChaosError 10050, too many nerves wasted

Vorteile- Einfache Eventregistration- Einheitliche KEY_ Konstanten- Einheitliches Event-Daten Objekt- Diverse Helper Methoden

Page 38: Prototype 1.7

Prototype: Event Objekt

KEY_ Konstanten

KEY_BACKSPACE, KEY_TAB,KEY_RETURN, KEY_ESC,KEY_LEFT, KEY_UP,KEY_RIGHT, KEY_DOWN,KEY_DELETE, KEY_HOME,KEY_END, KEY_PAGEUP,KEY_PAGEDOWN, KEY_INSERT

Page 39: Prototype 1.7

Prototype: Event Objekt

Standard Event registrieren

function SomeFunction(event) {// Event ist immer "event", auch im IE!// Dieses Event Objekt ist ebenfalls erweitert

}

Event.observe(window, 'load', SomeFunction);$(window).observe('load', SomeFunction);$('element').observe('click', SomeOtherFunction);

Page 40: Prototype 1.7

Prototype: Event Objekt

Events löschen

// Genau einen Event löschen, Handler muss übergeben werdenElement.stopObserving(element,'click',SomeFunction);$('element').stopObserving('click',SomeFunction);// Alle Events eines Typs löschen (Keinen Handler übergeben)Element.stopObserving(element,'blur');$('element').stopObserving('blur');// Oder komplett alle Event entfernenElement.stopObserving(element);$('element').stopObserving();

Page 41: Prototype 1.7

Prototype: Event Objekt

Intelligente Events (Mit Daten)

function SomeFunction(event,param) {if (event.keyCode == KEY_RETURN) {

alert('daten sind: ' + param);}

}

$(window).observe('keydown',function(event) {SomeFunction(event,$('content').getValue());

});

Page 42: Prototype 1.7

Prototype: Event Objekt

Do it the OOP way

var AssistantClass = Class.create({initialize : function() {

this.Input = $('myInput');this.WeWillUseThatLater = 'Hello World';this.Input.observe('blur',this.Validate.bind(this));

},Validate : function(event) {

// Das Event wird im Objekt Kontext ausgeführtalert(this.WeWillUseThatLater);

}});

Page 43: Prototype 1.7

Prototype: Event Extensions

Erweiterungen am Event ObjektAlle registrierten Events liefern ein modifiziertes ‚event‘ zurück

Beispiele- event.element(): Das Element auf dem der Event ausgeführt wurde- event.findElement(): Findet Objekte innerhalb des Event Elements- event.pointerX/Y(): Für Maus Events, immer absoluter Pixelwert!- event.is[Left|Right|Middle]Click(): Wie genau wurde geklickt?

Page 44: Prototype 1.7

Prototype: CSS Selektoren

Exkursion zu $$Damit holen wir alles was mit CSS zu holen ist

Syntax Beispiele$$(‘div.myclass‘): Alle Divs mit der Klasse myclass $$(‘.myclass‘): Alle Elemente mit der Klasse myclass $$(‘.myclass .error‘): Alle Elemente mit myclass und error $$(‘#mydiv‘): Element mit der ID mydiv $$(‘#mydiv input[type=checkbox]‘): Alle Checkboxen in #mydiv $$(‘:checked‘): Alle ausgewählten Elemente. Weitere, :disabled :enabled$$(‘#mytable tr:nth-child(even)‘): Alle geraden Zeilen von #mytable

…Und alles weitere was bis und mit CSS3 möglich ist!

Page 45: Prototype 1.7

Prototype: CSS Selektoren

Alle Checkboxen markieren

$$('#mycheckerdiv input[type=checkbox]').each(function(f) {f.checked = true;

});

Schöne Tabelle bauen

$$(‘#mytable tr:nth-child(even)‘).each(function(tr) {tr.className = 'AdminTabRowDark';

});$$(‘#mytable tr:nth-child(odd)‘).each(function(tr) {

tr.className = 'AdminTabRowLight';});

Page 46: Prototype 1.7

Prototype: Event.Handler

Zurück bei den EventsDiese arbeiten auf Wunsch auch mit Selektoren

Wozu ein weiterer Handler- Der Event.Handler delegiert an Unterelemente- Delegation des Callback erfolgt über CSS Selektoren

Page 47: Prototype 1.7

Prototype: Event.Handler

Einen Event Handler definieren

function SaveForm(event) {// Formular per Prototype Ajax Post speichernevent.element.request();

}// Speichern aller "saveable" Forms, beim verlassen der Seiteobserver = new Event.Handler(

window, // Auf das Window hören'unload', // Wenn es verlassen wird'form.saveable', // Alle Forms mit "saveable" KlasseSaveForm // SaveForm Methode ausführen

);observer.start();

Page 48: Prototype 1.7

Prototype: Der Form Namespace

Auch die Forms sind erweitert…Sofern diese mit der $-Funktion geladen werden

Einige Methoden im Überblick- $(‘frm‘).disable(): Deaktiviert alle Formularelemente- $(‘frm‘).enable(): Aktiviert alle Formularelemente- $(‘frm‘).getElements(): Array aller Formularelemente- $(‘frm‘).getInputs(type): Gibt z.B. alle Checkboxen eines Forms zurück- $(‘frm‘).request(): Formular per Ajax Posten/Requesten- $(‘frm‘).serialize(true): Formular Daten als JSON oder Query holen

Page 49: Prototype 1.7

Prototype: Der Form Namespace

Und sonst?…nur einige Convenience Methoden

Form.Observer- Trackt Änderungen in einem Formular- Kann für generische Validation verwendet werden

Form.Element.Observer- Gleich wie Form.Observer, auf ein einzelnes Element- Explizite automatische Validation eines Feldes

Page 50: Prototype 1.7

Prototype: Der Form Namespace

Beispiele von Form(.Element).Observer

// Formular alle 500ms prüfennew Form.Observer(myFrm, 0.5, GenericValidation);

// Formularelement alle 300ms prüfennew Form.Element.Observer(myEle, 0.3, ExplicitValidation);

Page 51: Prototype 1.7

Prototype: Selector

Noch mehr CSS SelektorenMit dem ‚Selector‘ kann nach Elementen gesucht werden

Ist doch das gleiche wie $$?- Genau, plus eine spezielle Funktion- .match() gibt an, ob ein Element dem Selektor entspricht

Und sonst?Das Objekt ist schlecht dokumentiert, kann aber wahrscheinlicheffektiv nicht viel mehr als ein Aufruf der $$-Funktion

Page 52: Prototype 1.7

Prototype: Selector

Anwendung des Selector

// <div id="firstFormContainer" class="FormContainer" />// <div id="anotherFormContainer" class="FormContainer" />// <div id="aFormContainer" />var Sel = new Selector('div.FormContainer');Sel.match($('someOtherDiv')); // falseSel.match($('firstFormContainer')); // true// Beide obigen Container holenvar cont1 = Sel.findElements();// Oder wenn man es in einem bestimmten div suchen willvar cont2 = Sel.findElements($('containsDivs'));

Page 53: Prototype 1.7

Prototype: document

Erweiterungen des document ObjektsEs wird das registrieren/abfeuern von Events ermöglicht mit den bekannten Methoden „observe“ und „stopObserving“

Der viewport (was im Browser sichtbar ist)document.viewport.getHeight(): Höhe des sichtbaren Bereichsdocument.viewport.getWidth(): Breite des sichtbaren Bereichsdocument.viewport.getScrollOffsets(): left/top Offset des Scrollbalken

Page 54: Prototype 1.7

Prototype: $A

Arrays castenHiermit kann man so gut wie alles zu einem Array casten

Warum? Weil man……oft eine NodeList oder eine HTMLCollection bekommt unddiese nicht mit Prototype Features erweitert werden (können)

Was kann ein Prototype ArrayBasiert auf „Enumerable“ und bietet damit 44 neue Methodenzum iterieren, suchen und arbeiten mit Arrays

Page 55: Prototype 1.7

Prototype: $A

Beispiel inkl. each() Funktion

var ps = $A(document.getElementsByTagName('p'));// Nun können wir mit Each jedes Element durchgehenps.each(function(item) {

alert(item.innerHTML);});// Oder eine bestehende Funktion darauf ausführenps.each(Element.hide);

Page 56: Prototype 1.7

Prototype: Array Funktionen

Prüfen ob alle Elemente einem Wert entsprechen

// -> true (Ein leeres Array hat keine falschen Werte)[].all();// -> true (Alle Werte in 1 bis 5 sind true)$R(1, 5).all();// -> false (0 gilt als false)[0, 1, 2].all();// -> false (Auf 9 kommt false zurück)[9, 10, 15].all(function(n) { return n >= 10; });// Selbe Funktion mit "any", gibt jedoch schon bei// einem gültigen Wert true zurück

Page 57: Prototype 1.7

Prototype: Array Funktionen

Funktionsauswertung aller Elemente als Array

// Gibt folgendes Array ['H', 'H', 'G']['Hitch', "Hiker's", 'Guide'].collect(function(s) {

return(s.charAt(0).toUpperCase());});// Gibt alle Quadratzahlen von 1 bis 5 [1, 4, 9, 16, 25]$R(1,5).collect(function(n) {

return(n * n);});

Page 58: Prototype 1.7

Prototype: Array Funktionen

Geprüfte Werte zurück bekommen

// Wir wenden auf jedes Objekt Object.IsString an// Alle Werte die "true" ergeben kommen als Array zurück[1, 'two', 3, 'four', 5].filter(Object.isString);// Resultiert daher in ['two','four']

// Wir wenden auf jedes Objekt Object.IsString an// Alle Werte die "false" ergeben kommen als Array zurück[1, 'two', 3, 'four', 5].reject(Object.isString);// Resultiert daher in [1,2,3]

// Das geht auch mit eigenen Funktionen[1, 'two', 3, 'four', 5].filter(function(item)) {

// Hier item prüfen und true/false zurückgeben});

Page 59: Prototype 1.7

Prototype: Array Funktionen

Das selbe noch mit Regex

// Alle Strings mit Doppelbuchstaben finden['hello', 'world', 'this', 'is', 'cool'].grep(/(.)\1/);// Ergibt folgendes Array: ['hello', 'cool']

// Innerhalb 1 bis 30 alle Zahlen die mit 0 oder 5// enden holen und eins davon abziehen$R(1, 30).grep(/[05]$/, function(n) { return(n - 1); });// Ergibt folgendes Array: [4, 9, 14, 19, 24, 29]

Page 60: Prototype 1.7

Prototype: Array Funktionen

Zahl, String oder Objekt in einem Array finden

// Gibt true, da 10 im Range 1 bis 15 vorkommt$R(1, 15).include(10);// Gibt false, da Gross-/Kleinschreibung beachtet wird['hello', 'world'].include('HELLO');// Gibt true, da hello 1:1 so vorkommt['hello', 'world'].include('hello');// Gibt true, da 3 == '3' in JS true ergibt[1, 2, '3', '4', '5'].include(3);

Page 61: Prototype 1.7

Prototype: Array Funktionen

Objektmethoden aufrufen

// Einfacher Aufruf, der Arraywert ist immer der 1. Parameter// Resultat ergibt: ['HELLO', 'WORLD']['hello', 'world'].invoke('toUpperCase');

// Parameter folgen dem Methodennamen// Substring calls ergeben: ['hel', 'wor']['hello', 'world'].invoke('substring', 0, 3);

// Stoppt den 'change' event auf allen Input Feldern$$('input').invoke('stopObserving', 'change');

Page 62: Prototype 1.7

Prototype: Array Funktionen

Objektmethoden aufrufen (An eigenen Objekten)

var AddCalc = Class.create({initialize : function(first,second) {

this.First = first;this.Second = second;

},Compute : function() {

return(this.First + this.Second);}

});[ new AddCalc(5,5), new AddCalc(8,9)].invoke('Compute');// Ergibt folgendes Array [10, 17]

Page 63: Prototype 1.7

Prototype: Array Funktionen

Feldwerte lesen und als Array zurückbekommen

// Stringlänge aller Objekte herausfinden// Gibt folgendes Array: [5, 5, 4, 2, 4]['hello', 'world', 'this', 'is', 'nice'].pluck('length');

// checked Feld aller Checkboxen lesenvar checks = $$('input[type=checkbox]');var values = checks.pluck('checked')// Alles umkehrenfor (i = 0;i < checks.length;i++) {

checks[i].checked = !values[i];}

Page 64: Prototype 1.7

Prototype: Array Funktionen

Array Sortieren

// Nach Stringlänge sortieren// Ergibt: ['is', 'nice', 'this', 'world', 'hello']['hello', 'world', 'this', 'is', 'nice'].sortBy(function(s) {

return(s.length);});

// Objekte mit internem Sortierwert sortierenMyObjectArray.sortBy(function(s) {

// Mit „this“ könnte man hier auf das ganze Array zugreifenreturn(s.GetInternalOrder());

});

Page 65: Prototype 1.7

Prototype: Array Funktionen

Zusammenführen von Arrays

var firstNames = ['Jane', 'Nitin'];var lastNames = ['Doe', 'Patel'];var ages = [23, 41];// Ergibt: [['Jane', 'Doe'], ['Nitin', 'Patel']]firstNames.zip(lastNames);// Ergibt [['Jane', 'Doe', 23], ['Nitin', 'Patel', 41]]firstNames.zip(lastNames, ages);// Oder wir wenden eine Funktion an, um das // resultierende Array zu beeinflussen// Ergibt: ['Jane Doe is 23', 'Nitin Patel is 41']firstNames.zip(lastNames, ages, function(tuple) {

return(tuple[0] + ' ' + tuple[1] + ' is ' + tuple[2]);});// Man kann so z.B. Objekte aus Arrays kreieren

Page 66: Prototype 1.7

Prototype: $H / Hash

Was ist ein Hash?Äquivalent zu „Dictionary“ in ASP oder .NET

Zusammenfassen von DatenKann als alternative zu Objekten verwendet werden. Ein HashHat zudem einige Hilfreiche Funktionen

Methoden des HashtoQueryString(): Falls Post nicht möglich, Daten als QuerystringtoJSON()/toObject(): Liefern beide ein Objekt für z.B. Ajax Postsset()/get()/unset(): Kommen gleich im Codebeispielupdate(): Erweitert den Hash mit dem übergebenen Objektkeys()/values(): Liefert entsprechende Arrays

Page 67: Prototype 1.7

Prototype: $H / Hash

Anwendung des Hash

var h = $H({name: 'Michael', age: 21, country: 'England'});// Ist das selbe wie...var h = new Hash({name: 'Michael', age: 21, country: 'England'});// Mit "get" erhält man den entsprechenden Wertvar country = h.get('country');// Mit "set" kann man einen neue Wert setzen oder bearbeitenh.set('name','John');h.set('lastname','Doe');// Iterieren kann man auch hier mit der "each" Methodeh.each(function(pair,index) {

alert('on ' + index + ': ' + pair.key + '=' + pair.value);});

Page 68: Prototype 1.7

Prototype: $R / ObjectRange

Was ist ein ObjectRange?Ein Objekt, welches einen Range (Array) kreiert

Wozu kann man es verwenden?Man weiss es nicht. z.B. um ein Zahle-n oder Buchstabenarray zu erzeugen, welches man dann irgendwie weiter verwenden kann

Was kann der RangeAls erstes: Alles was eine Enumeration auch kanninclude(): Überschreibt include() der Enumerationend/start: Properties für das beginnende und endende Objekt

Page 69: Prototype 1.7

Prototype: $R / ObjectRange

Anwendung des Range

// Range von 1 - 10$R(0, 10)// Range von String aa bis ah: aa ab ac ad af ag ah$R('aa', 'ah')// Range von 1 bis 10 ohne letzte Zahl (Also 1 bis 9)$R(0, 10, true).include(10)// Range gibt eine Enumeration, man kann also each verwenden$R(0, 10, true).each(function(value) {

alert(value);});

Page 70: Prototype 1.7

Prototype: $R / ObjectRange

Anwendung des Range mit eigenem Objekt

var BigCounter = Class.create({initialize : function(value) {

this.Value = value},succ : function() {

return(this.Value + 750);}

});// Range mit BigCountern: 1500, 2250 ... 6000, 6750$R(new BigCounter(1500),new BigCounter(6750));

Page 71: Prototype 1.7

Prototype: Funktionserweiterungen

Methoden für FunktionenPrototype erweitert die Funktionsreferenzen automatisch

Hier kommt Magie zum EinsatzDas gibt‘s sonst nirgendwo: Deferier- und delaybare Aufrufe, Parametererweiterungen und Methodisierung

Page 72: Prototype 1.7

Prototype: Funktionserweiterungen

Parameternamen herausfinden

// Funktion. (Das alles geht auch mit Objektmethoden)function add(first, second) {

return(first + second);}// Array der Argumente holen: ['first', 'second']add.argumentNames();

Page 73: Prototype 1.7

Prototype: Funktionserweiterungen

Kontext binden (Wichtig für OOP implementationen)

var AlertOnClick = Class.create({initialize: function(msg) {

this.msg = msg;// Klappt nicht, da Events „kontextlos“ sind$('submit').observe('click', this.Click);// Klappt, da der Objektkontext übergeben wird $('submit').observe('click', this.Click.bind(this));

},Click: function(event) {

event.stop();$('message').update(this.msg).show();

}});

Page 74: Prototype 1.7

Prototype: Funktionserweiterungen

Parametererweiterung (Do it the indian way)

function showArgs() {// 'arguments' ist ein Array aller Paremteralert($A(arguments).join(', '));

}// Liste der Parameter ausgeben: '1, 2, 3'showArgs(1,2,3);// Mit Curry eine Funktionskopie erstellen, welche// Die Funktion mit Default 1,2,3 aufruftvar showExtended = showArgs.curry(1,2,3);// Diese mit weitere Parametern aufrufen: '1, 2, 3, a, b'showExtended('a','b');

Page 75: Prototype 1.7

Prototype: Funktionserweiterungen

Deferieren (Verschieben ans Ende)

// Funktionen die mit "defer" aufgerufen werden, wird der// Interpreter erst Ausführen wenn er nichts mehr zu tun hatfunction showMsg(msg) {

alert(msg);}showMsg("One"); // Normaler AufrufshowMsg.defer("Two"); // Verschobener AufrufshowMsg("Three"); // Normaler Aufruf// Output: One, Three, Two

Page 76: Prototype 1.7

Prototype: Funktionserweiterungen

Klassisches Beispiel (defer Methode)

// Klassiker, den man immer wieder sieht:var Assistant = Class.create({

function : initialize() {},// Funktion die ein Control per Effekt einblendetfunction : ShowInput(ele) {

$(ele).appear({ duration: 3.0 });// 1. Nicht im Objekt Kontext, 2. UnschönsetTimeout('MyObject.DoSomething()',3000);

},// Funktion die nach dem Effekt aufgerufen werden sollfunction : DoSomething() {}

});

Page 77: Prototype 1.7

Prototype: Funktionserweiterungen

Klassisches Beispiel (defer Methode)

var Assistant = Class.create({function : initialize() {},// Funktion die ein Control per Effekt einblendetfunction : ShowInput(ele) {

$(ele).appear({ duration: 3.0 });// 1. Im Objektkontext, 2. Optimal, da am

Funktionsende.// Wird ausgeführt wenn der Interpreter idle ist,

und das// ist er zufälligerweise erst, wenn der Effekt

beendet istthis.DoSomething.defer();

},// Funktion die nach dem Effekt aufgerufen werden sollfunction : DoSomething() {}

});

Page 78: Prototype 1.7

Prototype: Funktionserweiterungen

Delayen (Verschieben auf fixen Zeitpunkt)

// Ist defer nicht sicher genug, geht es immer noch sovar Assistant = Class.create({

function : initialize() {},// Funktion die ein Control per Effekt einblendetfunction : ShowInput(ele) {

$(ele).appear({ duration: 3.0 });// Funktonsaufruf gleich wie Effekt delayenthis.DoSomething.delay(3.0);

},// Funktion die nach dem Effekt aufgerufen werden sollfunction : DoSomething() {}

});

Page 79: Prototype 1.7

Prototype: Funktionserweiterungen

Delayen mit Parameter

var Assistant = Class.create({function : initialize() {},// Funktion die ein Control per Effekt einblendetfunction : ShowInput(ele) {

$(ele).appear({ duration: 3.0 });// Erst das Timeout, dann die Parameterthis.DoSomething.delay(3.0, 'hello', 'world');

},// Funktion die nach dem Effekt aufgerufen werden sollfunction : DoSomething(param1, param2) {}

});

Page 80: Prototype 1.7

Prototype: Funktionserweiterungen

Methodisierung (Statische Funktionen an Objekte binden)

// Funktion, die auf ein Objekt, das "name" Prop. setztfunction setName(target, name) {

target.name = name;}// Kann man z.B. so ohne Kontext verwendenobject = {};setName(object, 'Fred');

// Man kann aber auch das Objekt "Methodisieren"obj.setName = setName.methodize();// "target" ist nun "this" und wird direkt angewendetobj.setName('Barney');// Prototype setzt dies für fast alle Funktionen ein

Page 81: Prototype 1.7

Prototype: Funktionserweiterungen

Bestehende Methoden erweitern

// capitalize Funktion mit einem Parameter erweiternString.prototype.capitalize = String.prototype.capitalize.wrap(

function(OriginalMethod, eachWord) {if (eachWord && this.include(" ")) {

// Wenn Parameter (true), jedes Wort kapitalisieren

return(this.split(" ").invoke("capitalize").join(" "));

} else {// Oder die bisherige Standarmethode

anwendenreturn(OriginalMethod());

}}

);"hello world".capitalize(); // "Hello world""hello world".capitalize(true); // "Hello World"

Page 82: Prototype 1.7

Prototype: Number Methoden

Erweiterung von „Math“Number vereint Math und mehr

Beispiele- Fügt für jede Zahl abs(), ceil, floor(), und round() hinzu- toColorPart(): Gibt die Hex Version einer Zahl zurück- toPaddedString(n): Gibt den Zahlenwert mit führenden Nullen zurück

Page 83: Prototype 1.7

Prototype: The Object Object

Wer profitiert davonAlle primitiven Datentypen, alle Objekte, selbst Eigenbauten

Hilfreiche Funktionen- clone(): Erzeugt eine Shallow Copy. Deep Copy umsetzbar- extend(): Erweitert ein bestehendes Objekt- inspect(): Gibt Debug-Informationen des Objekts aus- Anwendbar statisch oder im Objektkontext als Methode

ValidierungValidierung (Nur statisch) kann nicht schaden: isArray(), isElement(), isFunction(), isHash(), isNumber(), isString(), isUndefined().

Page 84: Prototype 1.7

Prototype: PeriodicalExecuter

Warum nicht setInterval?Weil die Ausführungszeit dort nicht eingerechnet ist

Und sonst?- Die stop() Methode haltet den Executer an- Geeigneter für OOP da Kontextübergabe möglich

Page 85: Prototype 1.7

Prototype: PeriodicalExecuter

Simpler Aufruf

// Übergabe einer direkten Funktionnew PeriodicalExecuter(function(executer) {

if (!confirm('Hey bananas, what\'cha doin\'?')) {executer.stop();

}}, 5.0);

// Verwendung innerhalb eines Objektsthis.Exec = new PeriodicalExecuter(this.DoIt.bind(this),5.0);// Funktion DoIt als BeispielDoIt : function(pe) {

pe.stop(); // Übergebenen Executer stoppenthis.Exec.stop(); // Oder die Objektreferenz, da Kontext

}

Page 86: Prototype 1.7

Prototype: Prototype.Browser

Der Prototype NamespaceBietet nicht viel gescheites ausser „Browser“

Ein Set von BooleansWenns mal doch nicht klappt: Prototype.Browser.IE: Check ob IE vorhanden (Zudem: IE6, IE7, IE8).Opera: Check auf jegliche Versionen von Opera.WebKit: Check auf Webkit Browser (Safari, Anroid).MobileSafari: Expliziter Check auf iPhone Browser.Gecko: Browser basierend auf Gecko (Firefox, Netscape)

Page 87: Prototype 1.7

Prototype: String

Sind wir nicht endlich durch?Nein. Mit dem String Objekt kommt nochmal eine grobe Sache

Gültigkeit der MethodenJeder String besitzt die neuen Methoden, da Prototype direktdas String Objekt erweitert (Wie bei Zahlenwerten)

Wichtige Funktionen.capitalize(): Ersten Buchstaben gross schreiben.endsWith()/startsWith(): Start oder Ende des Strings prüfen.(un)escapeHtml(): Konvertiert reinen Text in HTML Entitäten und zurück

Page 88: Prototype 1.7

Prototype: String

Noch etwas mehr Funktionen.evalJSON(): JSON String zu einem Objekt konvertieren.isJSON(): Gibt an, ob der String evaluierbares JSON enthält.evalScripts(): Javascript Code innerhalb des Strings ausführen.extractScripts(): Gibt ein Array aller Javascript Codezeilen zurück.sub()/.gsub(): Einfache Form von Regex und/oder Replace.scan(): Erlaubt die Anwendung eines Callback für jeden Teilstring.stripScripts(): Löscht alle <script> Tags und JS Codes aus dem String.stripTags(): Entfernt alle HTML Tags aus dem String.toArray(): Erstellt ein Char Array aus dem String.toQueryParams(): Erstellt JSON Code aus URL Parametern.truncate(): Kürzt den String auf X-Zeichen und fügt Suffix an

Page 89: Prototype 1.7

Prototype: Template

Sowas wie String.Format in .NETString mit Variablen durch Objektproperties ersetzen

Gedacht für mehrfache VerwendungDas Template ist z.B. für Listenansichten sehr geeignet, lässt aberauch herkömmlichen „Verknüpfungscode“ schöner aussehen

Wichtige Funktionen.evaluate(obj): Ersetzt die Templatevariablen mit entsprechenden Variablen im gegebenen Objekt (JSON oder Prototype Objekt)

Page 90: Prototype 1.7

Prototype: PeriodicalExecuter

Anwendung des Template

var conv1 = { from: 'meters', to: 'feet', factor: 3.28 };var conv2 = { from: 'kilojoules', to: 'BTUs', factor: 0.9478 };var conv3 = { from: 'megabytes', to: 'gigabytes', factor: 1024 };// Template erstellenvar tpl = new Template(

'Multiply by #{factor} to convert from #{from} to #{to}.');// Alle formatieren... mit on-the-fly-array-each :D[conv1, conv2, conv3].each(function(conv){ tpl.evaluate(conv);});// -> Multiply by 3.28 to convert from meters to feet.// -> Multiply by 0.9478 to convert from kilojoules to BTUs.// -> Multiply by 1024 to convert from megabytes to gigabytes.

Page 91: Prototype 1.7

Inhalte Scriptaculous

EffekteEffektbeispiele, Queues, Combination, Toggle

ControlsSlider, Sortable(s), Ghostly, Test.Unit

AjaxAutocompleter, In Place Editing

Page 92: Prototype 1.7

Scriptaculous: Effekte

Zurück zum KerngeschäftScriptaculous bietet Effekte und Controls

Warum bietet Prototype das nicht an?Prototype und Scriptaculous haben eine strikte Trennung ausfunktionalem Framework und Effekten/Controls

EffekttypenEs wird zwischen Kerneffekten und Kombinationseffekten unterschieden

Page 93: Prototype 1.7

Scriptaculous: Effektbeispiele

Anzeige-EffekteEffect.Highlight: Lässt die Hintergrundfarbe kurz aufblinkenEffect.Morph: Erlaubt Farbwechsel zwischen zwei FarbenEffect.Move: Absolute oder Relative Veränderung der Position

Erschein-EffekteEffect.Appear: Sanftes Einblenden eines ControlsEffect.BlindDown: Herunterfahren eines Controls

Ausblende-EffekteEffect.Fade: Sanftes ausblenden eines ControlsEffect.BlindUp: Herauffahren eines Controls

Page 94: Prototype 1.7

Scriptaculous: Effekt Queues

Effect.QueueJeder Effekt lässt sich in eine Queue stellen, da er ansonstenparallel mit anderen Effekten ausgeführt würde

EinschränkungMan muss eindeutige „Scopes“ definieren, um Sie während derLaufzeit mit Effect.Queue steuern (z.B. Abbrechen) zu können

BeispielDas folgende Beispiel zeigt die Grundlegende Arbeit mit Queues.Merke: Queues sind nur nötig, wenn Effekte auf dem selben Element nacheinander anstatt gleichzeitig ausgeführt werden sollen

Page 95: Prototype 1.7

Scriptaculous: Effekt Queues

Erstellen von Queues

// Menu anzeigen, ans Ende des 'sc_menu' Scopenew Effect.SlideDown('menu',

{ queue: { position: 'end', scope: 'sc_menu' } });// Banner anzeigen, ans Ende des 'sc_banner' Scopenew Effect.Appear('bannerbig',

{ queue: { position: 'end', scope: 'sc_banner' } });// Menu pulsieren lassen, nach SlideDown Effektnew Effect.Pulsate('menu',

{ queue: { position: 'end', scope: 'sc_menu' } });

Page 96: Prototype 1.7

Scriptaculous: Effekt Queues

Steuern der Scopes

// z.B. die Menu Queue holenvar queue = Effect.Queues.get('sc_menu');// 'queue' ist eine Prototype Enumeration, daher...queue.each(function(effect) { effect.cancel(); });// ... um alles abzubrechen oder ...queue.invoke('cancel');// …Wartezeit zwischen Effekten beeinflussenqueue.interval = 100;

Page 97: Prototype 1.7

Scriptaculous: Combination / Toggle

Combinations toggeln und mergelnSlideUp()/Down(), Appear()/Fade() und BlindDown()/Up() lassen sich mit toggle() einfach kombinieren bzw. ein- und ausblenden

Sinn dahinterSpart einiges an Code, da ein-/ausblenden mit einerZeile Code realisiert werden kann

Page 98: Prototype 1.7

Questions

Aufwachen!Ihr habt‘s hinter euch.