Autorenarchiv

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


RoR-Migrations und PostgreSQL-Datentypen

Montag, 01. März 2010

Migrationsskripte sind in Ruby on Rails das Konzept, um die Entwicklung von Datenbanken im Verlaufe der Produktentwicklung zu verwalten und zu steuern. Da es sich bei ihnen um Ruby-Skripte handelt, steht einem auch der volle Funktionsumfang von Ruby on Rails zur Verfügung.
Ein Hauptprinzip der Migrationsskripte ist deren Datenbankneutralität. Sie soll es ermöglichen, mit möglichst geringem Aufwand die Datenbank wechseln zu können. Dies geht auf Kosten der Unterstützung spezieller Datenbank-Features.
Arbeitet man nun mit einer PostgreSQL-Datenbank und möchte man seine Spalten auch mit PostgreSQL-spezifischen Datentypen versehen, so kann man das wie folgt bewerkstelligen:

In der Methode “native_database_types” der Klasse “ActiveRecord::ConnectionAdapters::PostgreSQLAdapter” werden die Mappings für die SQL-Datentypen definiert, die von den Migrationsskripten im Zusammenhang mit einer PostgreSQL-Datenbank benutzt werden. Genau diese Methode kann man nun überschreiben, um die Mappings anzupassen.

class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
def native_database_types
{
:primary_key => "bigserial primary key",
:string      => { :name => "character varying", :limit => 255 },
:text        => { :name => "text" },
:integer     => { :name => "integer" },
:float       => { :name => "float" },
:datetime    => { :name => "timestamp" },
:timestamp   => { :name => "timestamp" },
:time        => { :name => "time" },
:date        => { :name => "date" },
:binary      => { :name => "bytea" },
:boolean     => { :name => "boolean" },
:bigint      => { :name => "int8" }
}
end
end

Nun kann man diese Definition beispielsweise in psql_ext.rb im lib-Verzeichnis speichern und sie per require ‘psql_ext’ in die Migrationsskripte einbinden.


Christian Borkowski


Erstellen eines Plugins für den CKEditor 3.0

Dienstag, 27. Oktober 2009

Im Folgenden soll anhand eines kleinen Beispiels gezeigt werden, wie man ein Plugin für den CKEditor schreibt und dieses einbindet. Es soll ein Button in die Toolbar aufgenommen werden. Ein Klick auf diesen Button soll einen Dialog öffnen. In diesem Dialog wird man einen Text eingeben und eine Schriftfarbe für diesen Text auswählen können. Beim Klick auf den Ok-Button des Dialogs, wird dann der entsprechende Text in der gewählten Schriftfarbe in den Editierbereich eingefügt.

Zunächst benötigt man eine eigene Konfigurationsdatei “config.js”, um die Toolbar anzupassen.

CKEDITOR.editorConfig = function( config )
{	
	CKEDITOR.plugins.addExternal( 'insertText', CKEDITOR.basePath + '../ckeditor_customized/plugins/InsertText/' );	
 
	config.extraPlugins = "insertText";	
 
	CKEDITOR.config.toolbar = 'MyToolbar';
 
        config.toolbar_MyToolbar =
          [
            ['NewPage','insertText'],
          ];    
};

MyToolbar enthält lediglich 2 Buttons. Zum einen enthält sie den NewPage-Button, hinter dem sich ein bereits mit dem CKEditor-Source mitgeliefertes Plugin versteckt. Und zum anderen enthält sie den neuen Button. Für diesen legen wir das Verzeichnis “x/ckeditor_customized/plugins/InsertText/” an, wobei x für das Verzeichnis steht, in dem sich auch das CKEditor-Verzeichnis befindet. In das angelegte Verzeichnis fügen wir nun die Datei “plugin.js” ein, die folgenden Code enthält:

CKEDITOR.plugins.add('insertText', {
	init : function( editor )
	{
		editor.addCommand( 'insertTextDlg', new CKEDITOR.dialogCommand( 'insertTextDlg' ) );
 
		editor.ui.addButton( 'insertText',
			{
				label : 'Text einfügen',
				command : 'insertTextDlg',
				icon: <icon path>
			});
 
		CKEDITOR.dialog.add( 'insertTextDlg', CKEDITOR.basePath + '../ckeditor_customized/dialogs/insertTextDlg.js');
 
	}
});

Zunächst fügen wir in dem Plugin der Editor-Instanz ein neues Dialog-Kommando namens insertTextDlg hinzu, welches bei Klick auf den neuen Button ausgeführt werden soll. Anschließend registrieren wir den neuen Dialog, der sich beim Button-Klick öffnen soll. Der Dialog wird in der Datei “insertTextDlg.js” definiert.

CKEDITOR.dialog.add( 'insertTextDlg', function( editor ) {
	return { 
		title: 'Text einfügen',
 
		minWidth: 200,
		minHeight: 80,
 
 
		contents: [ 
			{
				id: 'tab1',
				label: 'Tab1',
				title: 'Tab1',
				elements : [ 
					{
						id: 'mytext',
						type: 'text',
						label: "Text",
						validate : function() {
							// potentielle Validierungen
							if (this.getValue() == "") {
								alert("Das Feld darf nicht leer sein!");
							}
							return this.getValue() != "";
						}
					},
					{
						id: 'mycolor',
						type: 'select',
						label: "Farbe",
						items: [
						        ['rot'],
						        ['grün'],
						        ['blau']
						       ],
						validate : function() {
							// Validierungen
							return true;
						}
					},
				 ]
			}
		 ],
 
 
		 onOk: function() { 
			var color = this.getContentElement('tab1', 'mycolor').getValue();
			var numColor;
			if (color == 'rot') numColor = '#F00';
			else if (color == 'grün') numColor = '#0F0';
			else if (color == 'blau') numColor = '#00F';
 
			var element = CKEDITOR.dom.element.createFromHtml(
					'<span style="color:' + numColor + ';">' + 
						this.getContentElement('tab1', 'mytext').getValue() + 
					'</span>');
			editor.insertElement(element);
		 }
 
	};
 
} );

Bei einem Klick auf Ok, werden die selektierten und eingegebenen Werte ermittelt. Nun kann der eingegebene Text in der gewünschten Farbe eingefügt werden.


Christian Borkowski


Drucken von PDF-Dateien mit Ghostscript aus Java-Webservices heraus

Freitag, 05. Juni 2009

Problem:

Vorhandene PDF-Dateien sollen mit Ghostscript aus im Tomcat laufenden Java-Webservices heraus gedruckt werden. Das Betriebssystem ist Windows XP.

Lösung:

Nachdem Ghostscript installiert wurde, kann es z.B. mittels eines ProcessBuilders aus Java heraus gestartet werden.

        Process gsProcess = null;
        try {
            ArrayList<String> argList = new ArrayList<String>();
            argList.add("C:\\Programme\\gs\\gs8.64\\bin\\gswin32c.exe");
            argList.add("-sDEVICE#mswinpr2");
            argList.add("-sOutputFile#%printer%" + printerName); // printerName = Name des Druckers
            argList.add("-dBATCH");
            argList.add("-dNOPAUSE");
            argList.add("-dNOPAGEPROMPT");
            argList.add("-dNOPROMPT");
            argList.add("-dPrinted");
            argList.add(fileName); // fileName = Pfad zu der zu druckenden PDF-Datei
 
            ProcessBuilder processBuilder = new ProcessBuilder(
                argList);
            gsProcess = processBuilder.start();
 
            // Konsumieren der Ausgaben von Ghostscript:
            BufferedInputStream inputStream = new BufferedInputStream(gsProcess.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            BufferedInputStream errInputStream = new BufferedInputStream(gsProcess.getErrorStream());
            BufferedReader errReader = new BufferedReader(new InputStreamReader(errInputStream));
 
            String line;
            while ((line = reader.readLine()) != null){
                System.out.println("GHOSTCRIPT> " + line);
            }
 
            while ((line = errReader.readLine()) != null){
                System.err.println("GHOSTSCRIPT [ERROR]> " + line);
            }
 
            int returnValue = gsProcess.waitFor();
            if (returnValue == 0) {
                System.out.println("Returnwert des ghostscript-Aufrufs ist 0");
            }
            else {
                System.err.println("Returnwert des ghostscript-Aufrufs ist " + returnValue);
                ... // Fehlerbehandlung
            }
 
            // Alle Streams schließen
            gsProcess.getInputStream().close();
            gsProcess.getOutputStream().close();
            gsProcess.getErrorStream().close();
 
        } catch (Exception e) {
            ...
        }

Um nun einen reibungslosen Ablauf aus dem Tomcat heraus zu garantieren, sollte der Dienst mit den Rechten eines Admins laufen (kann unter Systemsteuerung->Verwaltung->Dienste eingestellt werden). Hintergrund ist, dass der Webservice Zugriff auf Systemressourcen (z.B. Netzwerkdrucker oder ähnliches) benötigen könnte.


Christian Borkowski