Archiv für die Kategorie ‘Javascript’

Javascript Datum

Montag, 25. Oktober 2010

Ich entwickelte an einer Web-Anwendung mit dem Javascript Framework Ext JS, welches für alle gängigen Browser funtkionieren soll. Wie bei vielen anderen Entwicklern ist auch bei mir der Firefox mit dem Firebug Plugin die erste Wahl, was den Browser betrifft. Neben Firefox lief auch in Googles Chrome die Anwendung wie erwartet. Ein Test im Internet Explorer führte aber dazu, dass einige Dialoge sich nicht öffnen ließen und der Browser sich aufhängte. Mein erster Verdacht war: “Hmm, da unterstützt Ext JS wohl doch nicht alle Browser gleichermaßen gut.” Ein wenig Javascript Debugging sollte Aufschluß über diese Problematik geben. Die Verabarbeitung kam bis zu einer Stelle, an der ein Datum geparst wurde.

new Date('2100-01-01')

Nach dem Auskommentieren lief auch im IE alles problemlos – was war nun falsch an diesem Ausdruck, der im Firefox und im Chrome funktionierte?

Es kam heraus, dass der IE mit dem String nichts anfangen kann und NaN (Not a Number) zurückgibt. Das Problem wäre sofort ersichtlich gewesen, würde nicht die Methode clearTime() aufgerufen werden, welche auf NaN angewendet, anscheinend eine Endlosschleife auslöst. Die Lösung war letztendlich die Javascript-Doku unter Selfhtml zu lesen und das Datum korrekt anzugeben.

Date(2100, 0, 1)

Hierbei ist zu beachten, dass der Monat mit 0 beginnt!

Es lag also nicht am Ext JS, sondern an der falschen Notation des Datums.


Andreas Siepert


Universeller Feldupdater mit Rails

Dienstag, 24. August 2010

Ich erstelle momentan ein kleines, sehr spezielles CMS mit Ruby on Rails, mein erstes komplettes Rails Projekt. Der Umstieg von Java in die Rails-Welt war zwar gewöhnungsbedürftig und hatte einige Hürden, aber es hat sich gelohnt. Hier ein kleines, schönes Beispiel wie man mit wenigen Zeilen Ruby ziemlich universellen Code erzeugen kann.

Die Anforderung war, alle Eingabefelder im CMS, z.B. die Beschriftung der Bilder oder Überschriften und Artikel, einzeln editierbar zu machen. D.h. man klickt bzw. doppelklickt das Feld an, editiert es und die Änderung wird beim Verlassen des Feldes gespeichert.
Undenkbar hier für jedes Feld eigene Methoden im Controller oder JavaScript anzulegen.

Die Lösung besteht aus drei Teilen wobei ich hier nur den Controller näher erläutern möchte.
Teil 1 ist eine Helpermethode die ein entspr. Eingabefeld erzeugt.
Teil 2 ist eine kleine JavaScript Funktion die den Wert des Feldes per Ajax an den Controller sendet.
Teil 3 ist der Controller der den neuen Wert speichern soll.

Idee war es dem Controller folgende Werte zu liefern:
- Name der Model Klasse
- ID des Datensatzes
- Name des Attributes
- Wert des Attributes
Die ersten drei Werte werden durch einen Punkt getrennt als ID des HTML input gesetzt, z.B.: Image.34.caption

Jetzt aber zum Controller, der nur aus einer public Methode besteht:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class FieldsController < ApplicationController
 
  layout nil
 
  def update
    a = params[:key].split('.')
    update_field a[0], a[1], a[2], params[:value]
    head :status => 200
  end
 
  private
  def update_field classname, id, attr, value
    # must be a ActiveRecord::Base
    obj = ActiveRecord::Base.const_get(classname).find(id)
    obj.update_attribute(attr, value)
  end
end

Die als “key” übergebenen Werte werden erstmal zerlegt und der Methode update_field übergeben. Hier wird die Model-Klasse über die Kernel Funktion const_get geladen (Klassennamen sind in Ruby Konstanten). Das machen wir direkt auf ActiveRecord::Base, weil wir dort alle Model Klassen finden werden und somit nicht Kernel.const_get verwenden müssen. Auf der Modelklasse rufen wir direkt ein find mit der ID auf und bekommen die Instanz unseres Datenobjekts. Auf diesem setzen wir den Wert des Attributs mit update_attribute neu. Fertig.
Der Controller liefert dann noch den Status 200 zurück, damit unser AjaxRequest weiß, dass alles ok ist.

Auf ActiveRecord::Base gibt es noch weitere update Methoden, so könnte man z.B. auch mehrere Attribute updaten.


Christof Aenderl


Javascript im href von HTML-Links

Donnerstag, 22. Juli 2010

Wer Probleme damit hat, browserkompatibel auf clicks bei Links zu reagieren, kann dies mit Hilfe des Schlüsselwortes ‘javascript:’ zu Beginn des href-Attributwertes verwirklichen.

Bsp:

<a href="javascript:myFunction();">Ein Link</a>

Angenommen, die Funktion myFunction() sieht nun beispielsweise so aus:

function myFunction() {
alert("Hallo!");
return false;
}

Dann wird die Seite, die den Link beinhaltet, gelöscht und eine neue Seite angezeigt, auf der lediglich das Wort ‘false’ steht. Das liegt daran, dass das Ergebnis des Javascripts in eine neue Seite gerendert wird.

Wichtig ist also, dass der Rückgabewert von myFunction undefined ist, wenn man möchte, dass die ursprüngliche Seite erhalten bleibt.


Christian Borkowski


JavaScript: Tastatureingaben mit prototype auswerten

Montag, 15. März 2010

Im folgenden Abschnitt möchte ich anhand des Beispiels einer Mehrfachauswahl von Eingabefeldern erläutern, wie einfach es ist, in JavaScript einen Tastendruck auszuwerten.
Ich verwende hier die prototype Bibliothek. Für alle, die prototype nicht kennen, ganz kurz:
$(‘name’) entspricht der Methode getElementById(‘name’)

var KeyEvent = {
   ctrl: false,
   keyCode: 0,
   element: null,
 
   /**
    * Am uebergebenen Element z.B. einem div Container oder document selbst
    * werden die Methoden fuer die Events keydown und keyup registriert.
    *
    * element: HTML-Element, an dem die Events registriert werden sollen
    * z.B. Tabelle oder Div.
    */
   init: function(element) {
      KeyEvent.element = element;
      // Taste gedrueckt
      Event.observe(KeyEvent.element, 'keydown', KeyEvent.registerDown);
      // Taste wieder losgelassen
      Event.observe(KeyEvent.element, 'keyup', KeyEvent.registerUp);
   },
 
   /**
    * Function, die auf den keydown event reagiert
    */	
   registerDown: function(event) {
      // falls die Taste gedrueckt bleibt, sollen keine weiteren 
      // keydown events verarbeitet werden
      KeyEvent.element.stopObserving('keydown');
      KeyEvent.keyCode = event.keyCode;
      if (event.ctrlKey) {
         KeyEvent.ctrl = true;
      }
   },
 
    /**
     * Function, die auf den keyup event reagiert
     */
   registerUp: function(event) {
      KeyEvent.ctrl = false;
      // wird die Taste losgelassen, starten wir den Observer fuer keydown wieder
      Event.observe(KeyEvent.element, 'keydown', KeyEvent.registerDown);
   }
};
 
/**
 * Wird beim onfocus des Eingabefeldes aufgerufen
 */
function selectField(element) {
   if (KeyEvent.ctrl) {
      // multiselect ... z.B. könnte man hier das Feld mit einer CSS class markieren.
   }
}

Im HTML könnte das dann wie folgt verwendet werden:

<body onload="KeyEvent.init($('content'))">
 
   <div id="content">
      <form ....>
         <input type="text" name="f1" onfocus="selectField(this)" />
         <input type="text" name="f2" onfocus="selectField(this)" />
         ...
      </form>
   </div>
</body>

Das obige Beispiel verwendet jetzt nur den speziellen event.ctrlKey. Eine denkbare Erweiterung wäre z.B. die Shift-Taste auzuwerten um die Felder von – bis zu markieren. Natürlich könnte man auch beliebige andere Tasten auswerten, dafür muss aber dann der numerische keyCode verwendet werden.

Mehr Infos zur Verwendung von Prototype finden sie unter http://prototypejs.org


Christof Aenderl