ln -s "/mnt/cifs/$USER@webdev.leipzig.ufz.de:coder" coder
Donnerstag, 27. Mai 2010
COMA/Solaris: Auf das Coderverzeichnis zugreifen
Dienstag, 11. Mai 2010
BioScripter - Script Generator für Pipettierroboter v1
Im Rahmen seiner Doktorarbeit arbeitet Robert Schäwe, Wissenschaftler am UFZ, mit dem Pipettierroboter BioMek 2000.
Der Roboter muß in diesem Zusammenhang große Mengen von Probentöpfchen mit Bakterien verschiedenster Kulturen befüllen. Um ein möglichst genaues Versuchsergebnis zu erhalten, ist es erforderlich, die Proben in einem sehr kurzem Zeitraum zusammenzustellen.
Da die Standardsoftware des Roboters entsprechend optimierte Funktionen nicht bereithält, wurde Fachinformatiker-Azubi Andreas Menge mit der Erstellung eines neuen Programms beauftragt. Mit diesem werden nun die optimerten Pipettierschritte errechnet und an den Roboter gesandt.
Der BioMek beim Abarbeiten der optimierten Pipettierschritte.
Das Pipettierschema, aus dem hervorgeht in welchen Mengen welche Kulturen in die jeweiligen Probentöpfchen kommen, wird dabei als Excel-Arbeitsmappe bereitgestellt. Diese Datei wird vom BioScripter importiert und die Befüllungsmatrix durch einen Algorithmus umgewandelt, der sowohl die gewünschte Geschwindigkeit erzielt wie auch auch Kreuzkontamination verhindert.
Aus Zeitgründen wurde das C#-Programm für diesen speziellen Versuch entwickelt und lässt momentan keine weiteren Anwendungen zu. Deshalb wird das Programm zur Zeit weiterentwickelt. Dabei wird vor allem Punkto Benutzerfreundlichkeit und Flexibilität einiges verbessert werden.
Dienstag, 20. April 2010
SVG: Im <OBJECT>
-Tag anklickbar machen (Teil 2)
Hier noch eine weitere Variante, welche praktikabler bei Funktionsaufrufen ist. Auf die Größenangabe über den DIV-Selektor wurde hier verzichtet, weiterhin wird als Parent-Element der <SPAN>
-Tag verwendet, was ein horizontales Aneinanderreihen der Grafiken erleichtert.
Die hier beschriebene Methode (ohne style
-Attribut) ist von der Struktur her, etwas sauberer.
Beispiel
<span class="svglink" style="width: 167px; height: 77px;"> <a href="javascript:alert('Test')" style="width: 167px; height: 77px;"></a> <object data="logo.svg" type="image/svg+xml" width="167" height="77"> <param name="src" value="logo.svg" /> <param name="wmode" value="transparent" /> <img src="logo.jpg" alt="http://www.ufz.de/" width="167" height="77" /> </object> </span>
Die CSS-Klasse svglink
.svglink { position: relative; } span.svglink { display: inline-block; } /* IE7-Hack, gleicht das Aussehen etwas an */ *+html .svglink { padding: 0 0.25em 0.25em 0; } .svglink a, .svglink object { position: absolute; width: inherit; height: inherit; } .svglink a { /* Die (beiden!) Eigenschaften sind wichtig, da im IE die SVG sonst nicht anklickbar ist. */ background-image: url(1x1transp.gif); background-color: transparent; z-index: 2; } .svglink object { z-index: 1; }
Der Unterschied zu der hier beschriebenen Methode, ist die Zuweisung von display: inline-block;
bei der Verwendung des <SPAN>
-Tags.
Es kann parallel mit dem <DIV>
-Tag gearbeitet werden.
Flash: Audio-Datei in Webseite einbetten
Nachfolgend beschreibe ich Schritt für Schritt das Erzeugen und Einbetten einer Audiodatei als Flash-Objekt in eine Webseite.
- Die Audiodatei am besten im WAV-Format z.B. mit einem Handy aufzeichnen (wenn möglich gleich als MP3 speichern).
- Liegt bereits eine MP3-Datei vor, kann dieser Punkt übersprungen werden. Jetzt sollte ein geeigneter MP3-Encoder gefunden werden, hier kann man z.B. den WAV to MP3 Converter benutzen (Herstellerseite).
Die Bedienung des Tools ist einfach, die gewünschten Dateien über Add hinzufügen und dann Start klicken. - Verringern Sie die Bit- und Samplerate (max.160kbs/44100Hz) wie im Screenshot dargestellt, sonst kann es später Probleme beim Import nach Flash geben.
Erforderliche Einstellungen im MP3-Encoder
- Ist die MP3-Datei erzeugt geht es im Adobe Flash, mit der im unten angehängten Download enthaltenen FLA-Datei, weiter. Öffnen Sie die FLA-Datei und wählen Datei->Importieren->In Bibliothek importieren....
Anschließend sollte Ihre MP3 in der Bibliothek (Bibliothek evtl. mit STRG + L oder Fenster->Bibliothek öffnen) sichtbar sein. Im Kontextmenü (rechte Maustaste) der Datei wählen Sie Eigenschaften und nehmen die im Screenshot dargestellten Einstellungen vor (sind die gezeigten Einstellungen nicht sichtbar klicken Sie auf die Schaltfläche Erweitert).
var soundToLoad:Sound = new Sound(); startSound_btn.onRelease = function() { var song = songName_txt.text; soundToLoad.attachSound("mp3"); soundToLoad.start(0,1); };
In der FLA-Datei integriertes Actionscript, welches die MP3-Datei beim Klick
auf das Symbol abspielt.
und tragen Sie unter Bezeichner "mp3" ein.
- Sollte die endgültige Soundqualität nicht ausreichen, können Sie im oben gezeigten Dialogfeld unter dem Dropdown Komprimierung->MP3 weitere Einstellungen vornehmen.
- Anschließend wird das Projekt mit den Standardeinstellungen über Datei->Veröffentlichen veröffentlicht, dabei sollte am Speicherort der FLA-Datei eine SWF- und eine HTML-Datei entstehen.
- Jetzt muss die SWF-Datei auf den Webserver hochgeladen werden. Am UFZ benutzt man dazu das Bild- und Filearchiv im administrativen Intranetbereich. Man lädt hier die SWF-Datei hoch und erhält eine ID (z.B. 123456).
- Jetzt muss man die hochgeladene Datei noch in der HTML-Datei referenzieren. Entweder die beim Veröffentlichen entstandene HTML-Datei verwenden oder den unten stehenden Quelltext (am UFZ wird für die Dateireferenz das Makro
getfiler
verwendet).
HTML-Quelltext zur Verwendung auf der eigenen Webseite
Achten Sie bitte darauf, dass die SWF-Datei zweimal referenziert werden muss, hier mit Hilfe des Makroaufrufs [§fgetfiler_123456§]
(UFZ-Beispiel, ansonsten ohne das Makro z.B. http://www.foo.com/data/sample123456.swf
).
Symbol anklicken um den Sound zu hören
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="37" height="41" id="erste_sahne" align="middle"> <param name="allowScriptAccess" value="sameDomain" /> <param name="movie" value="[§fgetfiler_123456§]" /> <param name="quality" value="high" /> <param name="bgcolor" value="#ffffff" /> <embed src="[§fgetfiler_123456§]" quality="high" bgcolor="#ffffff" width="37" height="41" name="erste_sahne" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /> </object>komplettes Beispiel
Donnerstag, 15. April 2010
HTML/Javascript: Framegröße an Inhalte anpassen
Das folgende Beispiel kann genutzt werden, wenn man die Framegröße automatisch an wechselnde Inhaltgrößen anpassen möchte. Ein Anwendungsfall wären die UFZ-Adventskalender, welche sich als Popup öffnen und Kalender unterschiedlicher Größe zeigen. Frames sind hier deshalb eingesetzt weil sich das Menü zum Wechseln der Kalender in einem solchen befindet (siehe Screenshots).
komplettes BeispielDienstag, 13. April 2010
PHP: File Upload
<?php $message = ""; if(isset($_FILES["file_name"])) { $upload_dir = "/www/data/"; $file_name = $_FILES['file_name']['name']; $file_temp = $_FILES['file_name']['tmp_name']; move_uploaded_file($file_temp, $upload_dir.$file_name); $message = "$file_name ($file_size Byte) nach $upload_dir hochgeladen!
"; } $html = <<< HTML <form action="{$_SERVER['PHP_SELF']}" enctype="multipart/form-data" method="post"> <input type="file" name="file_name" /> <input type="submit" value="Kopieren" /> </form> HTML; echo $html.$message; ?>
Freitag, 9. April 2010
SVG: Im <OBJECT>
-Tag anklickbar machen (Teil 1)
Wer eine SVG wie im Post beschrieben einbettet, wird feststellen das man die Grafik nicht wie gewohnt verlinken kann (Beispiel 1). Auch die Verwendung eines onklick
-Events führt nicht zum Erfolg (Beispiel 2).
Beispiel 1 (funktioniert nicht)
<a href="javascript:alert('Test')"> <object data="logo.svg" type="image/svg+xml" width="167" height="77"> <param name="src" value="logo.svg" /> <param name="wmode" value="transparent" /> <img src="logo.jpg" alt="http://www.ufz.de/" width="167" height="77" /> </object> </a>
Beispiel 2 (funktioniert nicht)
<object data="logo.svg" onlick="alert('Test')" type="image/svg+xml" width="167" height="77"> <param name="src" value="logo.svg" /> <param name="wmode" value="transparent" /> <img src="logo.jpg" alt="http://www.ufz.de/" width="167" height="77" /> </object>
Abhilfe schafft hier das Schließen des Links (</a>
) vor dem OBJECT
-Tag und etwas CSS.
Beispiel 3 (funktioniert)
<div class="svglink" id="svg1"> <a href="javascript:alert('Test')"></a> <object data="logo.svg" type="image/svg+xml" width="167" height="77"> <param name="src" value="logo.svg" /> <param name="wmode" value="transparent" /> <img src="logo.jpg" alt="http://www.ufz.de/" width="167" height="77" /> </object> </div>
Der Parameter wmode ist hier nicht optional, sonst ist die Grafik im IE nicht anklickbar.
Die CSS-Klasse svglink
.svglink { position: relative; } .svglink a, .svglink object { position: absolute; width: inherit; height: inherit; } .svglink a { /* Die (beiden!) Eigenschaften sind wichtig, da im IE die SVG sonst nicht anklickbar ist. */ background-image: url(1x1transp.gif); background-color: transparent; z-index: 2; } .svglink object { z-index: 1; }
Bei dem als Hintergrund verwendeten Bitmap, handelt es sich um eine 1 Pixel große GIF-Datei mit eingeschalteter Transparenz (sie ist auch Teil des unten angehängten Downloads).
Weitere CSS-Eigenschaften
Die Größe der Grafik sollte in em angegeben werden, um ein korrektes Skalieren zu ermöglichen. Deshalb ist hier ein weiterer DIV-Selektor notwendig, dieser korrigiert gleichzeitig das Fehlen der inherit
CSS-Eigenschaft im IE6 und IE7.
/* IE7 kennt kein inherit, daher der zusätzliche Selektor */ #svg1, #svg1 a { width: 10.4375em; /* 167px / 16 = 10,4375em */ height: 4.8125em; /* 77px / 16 = 4,8125em */ }komplettes Beispiel
Mittwoch, 7. April 2010
SVG: Crossbrowser kompatibel & XHTML valide referenzieren
Alle Standardbrowser können mehr oder weniger mit SVG-Grafiken umgehen. Der IE, im Moment nur über das Adobe SVG-Plugin (Adobe SVG-Viewer 3.03). Ab Version 9 des IE ist hier Besserung in Sicht und damit haben SVG-Grafiken eine gute Chance, sich weiter zu verbreiten.
SVG-Grafik<object data="logo.svg" type="image/svg+xml" width="167" height="77"> <param name="src" value="logo.svg" /> <param name="wmode" value="transparent" /> <img src="logo.jpg" alt="http://www.ufz.de/" width="167" height="77" /> </object>
Der erste eingebettete param
-Tag dient den IE's als Referenz auf die Datei. Der Internet Explorer kann hier keine Dateien per HTTP referenzieren!? Deshalb wird die Beispieldatei hier auch nicht angezeigt. Das sollte aber in der Praxis nicht weiter stören.
Der Parameter wmode ist optional, gleicht aber das Verhalten der SVG's im IE, an dass, der anderen Browser an.
Der eingebettete img
-Tag wird benutzt wenn der Browser keine SVG anzeigen kann.
Dienstag, 6. April 2010
Excel/VBA: Letze Zeile mit Wert ermitteln
MsgBox(ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row)
Freitag, 19. März 2010
Oracle: DROP TABLE OR SEQUENCE IF EXIST als Prozedur
CREATE OR REPLACE PROCEDURE drop_object ( ObjName IN VARCHAR2 ) IS counter NUMBER := 0; to_drp VARCHAR2(200) := UPPER(ObjName); drp_stmt VARCHAR2(200) := NULL; BEGIN SELECT COUNT(*) INTO counter FROM user_tables WHERE table_name = to_drp; IF counter = 1 THEN drp_stmt := 'Drop Table ' || to_drp; EXECUTE IMMEDIATE drp_stmt; END IF; SELECT COUNT(*) INTO counter FROM user_sequences WHERE sequence_name = to_drp; IF counter = 1 THEN drp_stmt := 'DROP SEQUENCE ' || to_drp; EXECUTE IMMEDIATE drp_stmt; END IF; END DROP_OBJECT; /
Der Aufruf der Prozedur könnte z.B. so erfolgen:
CALL drop_object('t_test'); CREATE TABLE t_test ( test_id NUMBER, uid_text VARCHAR2(80) )
Oracle: LDAP ID als Primärschlüssel
CALL drop_object('t_test'); CREATE TABLE t_test (test_id NUMBER, uid_text VARCHAR2(80)); CREATE OR REPLACE TRIGGER insert_lid BEFORE INSERT ON t_test FOR EACH ROW DECLARE l_ldap_host VARCHAR2(256) := 'hera.leipzig.ufz.de'; l_ldap_port VARCHAR2(256) := '389'; l_ldap_base VARCHAR2(256) := 'dc=ufz,dc=de'; l_retval PLS_INTEGER; l_session DBMS_LDAP.session; l_attrs DBMS_LDAP.string_collection; l_message DBMS_LDAP.message; l_entry DBMS_LDAP.message; l_vals DBMS_LDAP.string_collection; BEGIN l_session := DBMS_LDAP.init ( hostname => l_ldap_host, portnum => l_ldap_port ); l_retval := DBMS_LDAP.simple_bind_s ( ld => l_session, dn => NULL, passwd => NULL ); l_attrs(0) := 'uidNumber'; l_retval := DBMS_LDAP.search_s ( ld => l_session, base => l_ldap_base, scope => DBMS_LDAP.SCOPE_SUBTREE, filter => '(& (nsrole=*roleself*) (objectClass=ufzperson) (uid=' || :new.uid_text || ') )', attrs => l_attrs, attronly => 0, res => l_message ); IF DBMS_LDAP.count_entries ( ld => l_session, msg => l_message ) = 1 THEN l_entry := DBMS_LDAP.first_entry ( ld => l_session, msg => l_message ); l_vals := DBMS_LDAP.get_values ( ld => l_session, ldapentry => l_entry, attr => l_attrs(0) ); END IF; DBMS_OUTPUT.PUT_LINE ( l_attrs(0) || ' = ' || l_vals(0) ); l_retval := DBMS_LDAP.unbind_s ( ld => l_session ); :new.test_id := l_vals(0); END; /
Der Trigger könnte z.B. so ausgelöst werden:
INSERT INTO t_test (uid_text) VALUES ('dutzend');
Oracle: Per Trigger Website in CLOB einlesen
Die Tabelle für das Beispiel
CREATE TABLE t_pages ( pages_id NUMBER, url VARCHAR2(80), page CLOB ); -- Sequenz für das Increment der ID CREATE SEQUENCE t_pages_autoinc_seq START WITH 1 INCREMENT BY 1 NOCACHE NOMAXVALUE; -- Trigger zum Aufruf der Sequenz CREATE OR REPLACE TRIGGER t_pages_autoinc_trigger BEFORE INSERT ON t_pages FOR EACH ROW BEGIN SELECT t_pages_autoinc_seq.NEXTVAL INTO :NEW.pages_id FROM DUAL; END; /
Der Trigger löst folgendes aus:
Wird ein Datensatz mit einer gültigen URL eingefügt, wird die Seite aufgerufen und der HTML-Code der Seite in den CLOB geschrieben.
CREATE OR REPLACE TRIGGER insert_page BEFORE INSERT ON t_pages FOR EACH ROW DECLARE req UTL_HTTP.req; resp UTL_HTTP.resp; page CLOB; BEGIN -- Verbindung aufbauen req := UTL_HTTP.begin_request(:new.url); -- Als Mozilla ausgeben UTL_HTTP.set_header(req, 'User-Agent', 'Mozilla/4.0'); resp := UTL_HTTP.get_response(req); UTL_HTTP.read_text(resp, page, 50000); UTL_HTTP.end_response(resp); :new.page := page; EXCEPTION WHEN UTL_HTTP.end_of_body THEN UTL_HTTP.end_response(resp); END; /
Beispiel zum Aufrufen des Ganzen
INSERT INTO t_pages (url) VALUES ('http://www.ufz.de/');
Oracle: LDAP Connection mi dem DBMS_LDAP Package
Im folgenden wird das DBMS_LDAP-Package genutzt um auf einen LDAP-Server anonym zuzugreifen und den Wert eines bestimmten Attributes zu lesen.
Konkret ist das hier die LDAP-ID (uidNumber) einer bestimmten Person (ufzperson).
Die ID der Person soll später als Primärschlüssel in einer Oracle-Tabelle genutzt werden.
DECLARE l_ldap_host VARCHAR2(256) := 'hera.leipzig.ufz.de'; l_ldap_port VARCHAR2(256) := '389'; -- varchar? l_ldap_base VARCHAR2(256) := 'dc=ufz,dc=de'; l_retval PLS_INTEGER; l_session DBMS_LDAP.session; l_attrs DBMS_LDAP.string_collection; l_message DBMS_LDAP.message; l_entry DBMS_LDAP.message; l_vals DBMS_LDAP.string_collection; BEGIN l_session := DBMS_LDAP.init ( hostname => l_ldap_host, portnum => l_ldap_port ); -- anonym anmelden l_retval := DBMS_LDAP.simple_bind_s ( ld => l_session, dn => NULL, passwd => NULL ); -- Attribut welches gesucht wird l_attrs(0) := 'uidNumber'; -- Suche ausführen l_retval := DBMS_LDAP.search_s ( ld => l_session, base => l_ldap_base, scope => DBMS_LDAP.SCOPE_SUBTREE, filter => '(&(nsrole=*roleself*)(objectClass=ufzperson)(uid=dutzend))', attrs => l_attrs, attronly => 0, res => l_message); -- Wenn genau ein Eintrag gefunden wurde IF DBMS_LDAP.count_entries(ld => l_session, msg => l_message) = 1 THEN -- ersten Eintrag festlegen l_entry := DBMS_LDAP.first_entry ( ld => l_session, msg => l_message ); -- Wert des Eintrages holen l_vals := DBMS_LDAP.get_values ( ld => l_session, ldapentry => l_entry, attr => l_attrs(0) ); END IF; -- Attribut und Wert ausgeben DBMS_OUTPUT.PUT_LINE(l_attrs(0) || ' = ' || l_vals(0)); -- Verbindung beenden l_retval := DBMS_LDAP.unbind_s(ld => l_session); END; /
Dienstag, 16. März 2010
Linux/Solaris: Dateiname in Textdateien einfügen
Um den jeweiligen Dateinamen in die 2. Zeile aller Textdateien einzufügen, die in einem Verzeichnis liegen, kann man folgende Befehlszeile im verwenden:
for i in *.*; do sed -i "2i\\$i" $i; done
Freitag, 12. März 2010
Linux/Solaris: Text in Dateien einfügen
- Terminal öffnen
- in den Ordner mit den Dateien wechseln (cd)
sed -i "1i\Text in Zeile 1" *.mop
sed -i "2i\Text in Zeile 2" *.mop
Donnerstag, 11. März 2010
Windows 7: Test auf Unterstützung des TRIM-Befehls
Die Meldung DisableDeleteNotify = 0 bedeutet in diesem Fall die Aktierung von Trim, eine DisableDeleteNotify = 1 würde seine Deaktivierung signalisieren.
Dienstag, 9. März 2010
COMA: Linkicons und Glossarlinks setzen
$html = "HTML mit Glossarbegriffen und Hyperlinks"; $root_pid = 28; $html = linkicon_glossar_parser($html, $root_pid);Der Parameter $root_pid entscheidet über das Setzen der Glossarlinks (Knoten 1 JA, Knoten 9 NEIN ?).
Zu ersetzende Linkicons müssen in einem DIV mit der ID content stehen (nicht valide da ID dann doppelt)!
COMA: Makroparser aufrufen
$html = "HTML mit einem Makro (§fgetpic_9908§)"; $html = ersetze_funktionstemplates ( $conn, $sprache, $code, $html, $baum, $adm, $su, $pub );
Montag, 8. März 2010
USB Stick ohne Floppy bootfähig machen
- ZIP-Datei an beliebiger Stelle entpacken
- VFDWIN.EXE als Administrator starten
- unter Driver auf Start klicken
- bei Drive 0 oder Drive 1 mittels Change den Laufwerksbuchstaben auf A setzen
- Open und dann Create klicken (Image File bleibt leer)
- im Explorer den Arbeitsplatz öffnen
- Rechtsklick auf 3½-Diskette A - Formatieren - MS-DOS Startdiskette erstellen
Systemdateien auf den Stick übertragen
- HP USB Disk Storage Format Tool installieren
- USB Stick einstecken
- HP Tool starten
- Bei Device den Stick wählen
- Häkchen bei Create DOS Startup Diskusing DOS System Files located at A:\ machen
Mittwoch, 3. März 2010
COMA: Cron-Job einrichten
Als erstes erstellt man das Makro, welches per Cron aufgerufen werden soll.
Danach sucht man sich in der Datenbank die Tabelle W_CJ.
In die Spalte CJ_FKT trägt man den Namen des Makros ein.
Der Eintrag in die Spalte CJ_EXE besteht aus 4 Ziffern, die ersten beiden geben die volle Stunde an, in der das Makro gestartet wird (00 - 23).
Die beiden letzten stehen für den Tag im Monat an dem man das Makro ausführen möchte (01 - 31), 00 steht dabei für täglich.
In der Spalte CJ_LAST_EXE wird das Datum gesetzt an dem der Job zum letzten Mal ausgeführt wurde.
Sonntag, 28. Februar 2010
Oracle: Autoincrement Workarounds
Tabelle für die Beispiele
create table teach_clients ( id_clients number not null, vorname varchar2(255), zuname varchar2(255) not null, geburtsdatum date, constraint teach_clients_pk primary key ( id_clients ) enable )
Unterabfrage mit Aggregatfunktion
insert into teach_clients values ( ( select case when max(id_clients) >= 1 then to_char(max(id_clients) + 1) else to_char(1) end from teach_clients ), 'René', 'Tuchscherer', '10.02.1963' )
Trigger und Sequenz
Man erzeugt zwei zusätzliche Datenbankobjekte, eine Sequence und einen Trigger. Die Sequenz erzeugt die einzusetzenden Werte, der before-insert Trigger sorgt dafür, dass der neue Wert als erstes in der neuen Zeile landet.-- die Sequenz erzeugen create sequence id_clients_seq start with 1 increment by 1 nomaxvalue; -- den Trigger erzeugen create trigger id_clients_trigger before insert on teach_clients for each row begin select id_clients_seq.nextval into :new.id_client from dual; end;Man kann statt start with 1 auch eine andere Zahl einsetzen, mit der begonnen werden soll. Das increment by 1 kann man eigentlich weglassen, weil es die Default-Einstellung ist. Der Parameter nomaxvalue sagt der Sequence, das sie für immer und ewig zu inkrementieren hat und nicht an irgendeinem Wert ein Reset machen soll.
Es kann übrigens durchaus sein, dass Zahlen "übersprungen" werden, weil sie von Oracle im Cache gehalten werden, um die Eindeutigkeit zu sichern. Wenn man also lückenlos aufsteigende Nummern haben muss, wäre dieser Ansatz nicht ausreichend.
Mittwoch, 20. Januar 2010
COMA: Angemeldeten User ermitteln
SELECT a.lid, b.login_name FROM web.wsess a, web.wlogin b WHERE sid = $sess_id AND a.lid = b.lid
COMA: Bild dynamisch erzeugen
Hier als Makro umgesetzt, welches so aufgerufen wird:
[§fcreatePic§]
function createPic() { if(isset($_REQUEST['getpic']) && Header("Content-type: image/jpeg"); $width = "300"; $height = "50"; // neues Bild erzeugen $image = ImageCreateTrueColor($width, $height); // Farben definieren $col1 = ImageColorAllocate($image, 255, 255, 200); $col2 = ImageColorAllocate($image, 0, 0, 0); // Hintergrund mit Farbe füllen ImageFill($image, 0, 0, $col1); // Text dazu ImageString ($image, 5, 20, 20, "Coded bei FIAE", $col2); // Grafik ausgeben ImageJPEG($image); // Speicher wieder frei geben ImageDestroy($image); } else { return "<img src=\"{$_SERVER["REQUEST_URI"]}&getpic\">"; } }
Dienstag, 19. Januar 2010
COMA: Oracle-Blob als Image-Stream
Hier als Makro umgesetzt, welches z.B. so aufgerufen wird:
[§fpicStream_13404§]
Als Parameter wird die gewünschte Bild-ID übergeben.
function picStream($conn, $param) { if(isset($_REQUEST['getpic']) && is_numeric($param)) { $sql = "select pics_blob from web.wpics where pics_id=$param"; $stmt = OCIparse($conn, $sql) ; OCIExecute($stmt,OCI_DEFAULT) ; $check = OCIFetchInto($stmt, $row, OCI_ASSOC); if($check == 1) echo $row["PICS_BLOB"]->load(); } else { return "<img src=\"{$_SERVER["REQUEST_URI"]}&getpic\">"; } }
Donnerstag, 14. Januar 2010
COMA: LDAP per PHP durchsuchen
function search_user_ldap($string) { $filter = "(& // aktiviert, deaktiviert, alle (nsrole=*roleself*) (objectclass=ufzperson) // Attribut nach dem wir suchen (sn=Surname) (sn=".$string."*) )"; // Attribute die geliefert werden sollen $attr = array("sn"); // Menge der Suchergebnisse (0=unbegrenzt) $count = 0; // Ergebnisarray $search = array(); if(cldap_Search("", &$search, $filter, $attr, $count)) { $search = cldap_DeleteCount($search, 1); foreach($search as $val) { $ret[] = $val[$attr[0]][0]; } } return $ret; }
COMA: Oracle-Tabellen zwischen Instanzen kopieren
Beispiel 1: von SERVICE nach INTERNET
create table WEB.WTR_UFZ as select * from WEB.WTR_UFZ@testsystem
Beispiel 2: von INTERNET nach SERVICE
create table WEB.WTR_UFZ as select * from WEB.WTR_UFZ@internet
Dienstag, 12. Januar 2010
Javascript: Objektorientierung und Drag and Drop (Teil 2)
Vererbung
Im zweiten Teil geht es um die Vererbung, ich habe u.a. in den Kommentaren den Begriff Klassen verwendet (natürlich gibt es in Javascript keine Klassen in dem Sinne), da ich aber versucht habe Strukturen nachzubilden, wie sie aus Java bzw. C# bekannt sind, erklärt sich das Ganze so besser.
Ob eine Verkettung der drei definierten Klassen möglich ist, gilt es noch auszutesten!
Javascript im HEAD (u.a. Objektinstanzierung):window.onload = Init; function Init() { // neues Objekt der Subklasse instanzieren var dragObj = new DragById("dragable_1"); // weiterere moegliche Instanzierung //var dragObj = new DragInFrame(316, 92); // Events öffentlichen Methoden aus // dem instanziertem Objekt zuweisen document.getElementById("dragpanel").onmousedown = dragObj.startDrag; document.getElementById("dragpanel").onmousemove = dragObj.Drag; document.getElementById("dragpanel").onmouseup = dragObj.endDrag; }Javascript im HEAD (die Basisklasse):
function DragObj() { // Variable zur Rückgabe // von öffentlichen Methoden (Pattern) var that = {}; // Objektvariablen this.movie = null; this.startX = 0; this.startY = 0; this.start_drag = false; // öffentliche Methoden that.startDrag = function(e) { // Browserweiche if(!e) { // IE e = window.event; this.movie = e.srcElement; } else this.movie = e.target; this.startY = e.screenY - parseInt(this.movie.style.top); this.startX = e.screenX - parseInt(this.movie.style.left); this.start_drag = true; } that.Drag = function(e) { if(this.start_drag) { if(!e) e = window.event; var newX = e.screenX - this.startX; var newY = e.screenY - this.startY; this.movie.style.left = newX + "px"; this.movie.style.top = newY + "px"; document.title = "X: " + newX + " Y: " + newY; } } that.endDrag = function() { this.start_drag = false; } return that; }Javascript im HEAD (die Subklassen):
function DragById(objId) { // Konstruktor der Basisklasse aufrufen this.constructor(); // öffentliche Methode der Basisklasse überschreiben this.startDrag = function(e) { if(document.getElementById(objId)) { this.movie = document.getElementById(objId); this.startY = e.screenY - parseInt(this.movie.style.top); this.startX = e.screenX - parseInt(this.movie.style.left); this.start_drag = true; } } } // Initialisierung der Vererbung DragById.prototype = new DragObj(); // weitere abgeleitete Klasse definieren function DragInFrame(frameWidth, frameHeight) { // Konstruktor der Basisklasse aufrufen this.constructor(); // öffentliche Methode der Basisklasse überschreiben this.Drag = function(e) { if(this.start_drag) { if(!e) e = window.event; var newX = e.screenX - this.startX; var newY = e.screenY - this.startY; if(newX > 0 && newX < frameWidth) this.movie.style.left = newX + "px"; if(newY > 0 && newY < frameHeight) this.movie.style.top = newY + "px"; document.title = "X: " + newX + " Y: " + newY; } } } // Initialisierung der Vererbung DragInFrame.prototype = new DragObj();HTML im BODY:
<img src="html.gif" style="position:absolute; top:0; left:0;" onmousedown="return false;" onmousemove="return false;" width="129" height="108" id="dragable_1" />
Freitag, 8. Januar 2010
AJAX: HTML-Element für Autovervollständigung
Nachdem ich nach einigem Suchen kein stabiles Element für eine AJAX-Autocomplete Funktion gefunden habe, hier mein Mix aus einem Text- und Listenfeld.
Zum Test einfach etwas eingeben (ohne Datenanbindung).
var charCode = 0; // Tastencode aus beiden Steuerelementen var optText = null; // Textfeld var optList = null; // Listenfeld var topOpt = false; // Hilfsvariable zum Steuern des Uebergangs var oldText = ""; // Vorwert aus Textbox merken function Init(obj) { if(optList) // Falls noch andere Liste offen //CloseList(false); // IE hängt sich auf optList.style.display = 'none'; optText = obj; optList = GetSelect(optText); // SELECT-Element ermitteln // geerbte Breite des Eingabefeldes an SELECT-Element weitergebn optList.style.width = optText.offsetWidth + "px"; // Variable charCode setzen document.onkeydown = GetKeyCode; } function OpenList() { oldText = optText.value; // Wert für Abbruch merken if(charCode == 27) { // ESC optList.style.display = 'none'; // Liste wieder zu machen return; } if(charCode == 13) { // ESC optList.style.display = 'none'; // Liste wieder zu machen // Event valuefixed auslösen return; } if(optText.value.length > 0) { // ist etwas im Textfeld topOpt = true; // Pfeiltaste nach oben soll Textfeld aktivieren with(optList) { // bei diesen Tasten Liste anzeigen if( charCode == 8 || // Backspace charCode == 40 || // Pfeil nach unten charCode == 46 || // Delete (charCode >= 48 && charCode <= 57) || // 0-9 (charCode >= 65 && charCode <= 90) || // a-z charCode == 109 || // - charCode == 190 || // . charCode == 59 || // ü charCode == 192 || // ö charCode == 219 || // ß charCode == 222 // ä ) { style.display = 'block'; // Liste anzeigen selectedIndex = -1; // nichts auswaehlen } } } else CloseList(false); // wurde z.B. alles geloescht, Liste schliessen // Übergang zur Liste bei... if(charCode == 40 && // ... Pfeiltaste nach unten optList.style.display == 'block') { // und Liste offen optText.value = optList.options[0].value; // Textbox aktualisieren optList.focus(); // Liste aktivieren optList.selectedIndex = 0; // ersten Eintrag auswählen } } function CloseList(setOpt) { if(setOpt && (optList.options.length != optList.selectedIndex + 1)) { optText.value = optList.value; // Listenwert ins Textfeld // Event valuefixed auslösen } else { optText.value = oldText; oldText = null; } optText.focus(); // Textfeld aktivieren optList.style.display = 'none'; // Liste ausschalten } function CancelSelect() { optList.style.display = 'none'; // Liste ausschalten optText.value = oldText; // gemerkten Text einsetzen optText.focus(); // Textfeld aktivieren } function CtrlList() { if(charCode == 13) // Enter CloseList(true); if(charCode == 27) // ESC CancelSelect(); if((charCode == 38 || charCode == 40) && // Pfeiltaste oben unten optList.options.length != optList.selectedIndex + 1) // nicht letzte Option optText.value = optList.value; if(charCode != 38) // nicht Pfeiltaste nach oben topOpt = false; // Pfeiltaste nach oben und oberster Eintrag ausgewaehlt if(charCode == 38 && optList.selectedIndex == 0) { if(topOpt) { // beim ersten Mal noch nichts machen optList.style.display = 'none'; // Liste ausschalten optText.focus(); // Textfeld aktivieren } else topOpt = true; // um beim zweiten Pfeiltaste nach oben } // Steuerelement zu wechseln } function GetKeyCode(e) { if (!e) e = window.event; charCode = e.keyCode; } function GetSelect(obj) { var count = 0; do { var elem = obj.nextSibling; obj = elem; count++; if(count > 3) break; } while(elem.type != "select-one") return elem; } function FixValue() { // TODO: Event valuefixed auslösen // aktives Element oder Tastencodes prüfen }CSS im HEAD:
input.autocomplete { width: inherit; } input.autocomplete { display: block; } select.autocomplete { display: none; position: absolute; } #autocomplete1 { float: left; width: 200px; } #autocomplete2 { float: left; width: 200px; } .lastopt { background-color: lightgray; }HTML im BODY:
<div id="autocomplete1"> <input type="text" name="autocomplete2" class="autocomplete" onclick="this.focus();" onfocus="Init(this)" onkeyup="OpenList();" onblur="FixValue();" tabindex="2" /> <select size="4" class="autocomplete" onclick="CloseList(true);" onkeyup="CtrlList();"> <option value="Peter">Peter</option> <option value="Peters">Peters</option> <option value="Petersen">Petersen</option> <option value="Petersohn">Petersohn</option> <option class="lastopt" title="Schließen">⇑</option> </select> </div>komplettes Beispiel
COMA: AJAX-Response ohne Content
if(isset($_GET['ajax'])) { echo utf8_encode("Hallo AJAX!"); die(); // ohne die() wird der komplette Kontent } // mit zurückgegeben