Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs

Erstellung eines Intranets in ASP (Teil 3) - Navigation

Geschrieben von: Alexander Zeitler
Kategorie: ASPIntranet.de

This printed page brought to you by AlphaSierraPapa

Hiermit begrüße ich Sie zum dritten Teil der Artikelserie zur Erstellung eines Intranets mit Active Server Pages. Wir werden heute die unten dargestellte Outlook-Leiste sowie die dazugehörige Administration programmieren.

Zielsetzung und Grundlagen

Zunächst noch einmal ein Screenshot dessen, was wir heute erstellen werden:

Um Ihnen den Aufbau der Seiten etwas zu verdeutlichen, nun ein Schema des eingesetzten Framesets:

Wie im Schema zu sehen ist, besteht das Intranet aus 3 (sichtbaren) Frames, welche in der im ersten Kursteil bereits behandelten Datei default.asp (im Hauptverzeichnis des Intranets) erzeugt werden. In dem Frameset wird noch ein vierter Frame definiert, der auf die Datei empty.asp verweist. Wie der Name der Datei bereits vermuten läßt, ist diese leer und dient nur optischen Zwecken in unserem Frameset.

Viel interessanter für uns und aus diesem Grund das nächste Objekt, mit dem wir uns beschäftigen werden, ist die Datei olmenu.asp, welche das Grundgerüst für unsere Outlook-Leiste bereitstellt.

In dieser Datei muß folgendes passieren: Es muß abhängig vom angemeldeten Benutzer und dessen Rechten für das Menü ein Frameset generiert werden. Jeder Hauptmenüpunkt wie z.B. "Verwaltung" besteht aus zwei Frames - ein Frame, der den Titel beinhaltet und ein zweiter, der die Icons und Titel der darin enthaltenen Anwendungen beinhaltet.

Die Umsetzung

Soviel zur Theorie - schreiten wir zur Tat sprich Programmierung. Sicher ist Ihnen die Datei callfunctions.asp und ihre "Folgen" aus dem zweiten Artikel noch bekannt. Auch in der Datei olmenu.asp inkludieren wir diese wieder.

Nach der Dimensionierung diverser Variablen (deren Zweck Sie im Verlauf des Scripts erfahren werden) lesen wir zunächst die Session-Variable "Logged_In_User_ID" in eine lokale Variable ein:

StrLogged_In_User_Id = Session("Logged_In_User_ID")

Zunächst müssen wir die Anzahl der Menüpunkte auslesen, deren Wert im Feld "IstUntermenuevon" "0" ist. "0" steht hierbei für die höchste Ebene des Menüs, d.h. wir wollen die Anzahl der Hauptmenüpunkte ermitteln. Allerdings dürfen nur diese Menüpunkte berücksichtigt werden, für die der aktuell angemeldete Benutzer die Berechtigung besitzt. Den Grund weshalb wir die Anzahl der vorhandenen Hauptmenüpunkte benötigen erfahren Sie später - wichtig ist im Moment nur, daß wir ihn bereits jetzt ermitteln. Somit ergibt sich folgende Abfrage:

StrSQL = "SELECT COUNT(*) AS IntAnzahl FROM OLMenue INNER JOIN OLMenueRechte 
   ON (OLMenue.ID = OLMenueRechte.IDMenuepunkt) WHERE ((OLMenue.Istuntermenuevon=0) 
   AND (int(OLMenueRechte.idbenutzer)=" & CLng(StrLogged_In_User_Id) & "))"
Set rs = Conn.Execute(StrSQL)

Zur Erklärung der Abfrage arbeiten wir uns von innen nach außem im SQL-String vor, beginnend beim JOIN-Statement. Dieses liest aus der Tabelle "OLMenue" alle Einträge, deren ID in der Tabelle "OLMenue" identisch ist mit der ID in der Tabelle "OLMenueRechte". Eingeschränkt wird diese Abfrage (die ja die Einträge aller Benutzer lesen würde) durch die WHERE-Klausel, welche nur die Einträge selektiert welche in der Tabelle "OLMenue" im Feld "IstUntermenuevon" den Wert "0" haben und in der Tabelle "OLMenueRechte" im Feld "IDBenutzer" der ID des aktuell eingeloggten Users entsprechen. Diese Abfrage liefert uns alle Einträge, die den zuvor genannten Kriterien entsprechen - wir wollten jedoch die Anzahl der Datensätze. Auch für dieses Problem liefert uns SQL bereits eine Lösung: COUNT. Mit dem COUNT-Statement liefert uns SQL die Anzahl der ermittelten Datensätze und schreibt diese in einen Datensatz - in diesem Fall "IntAnzahl". Da die Anzahl der ermittelten Datensätze der einzige Wert ist, den die Abfrage zurükliefert, können wir diesen - aus Performancegründen - auch über den Index abfragen. Dieser ist immer 0 - deshalb ergibt sich:

IntAnzahl = rs.Fields(0).Value

Soweit - so gut - doch was passiert, wenn der Wert von IntAnzahl nach der Abfrage "0" ist? Oder besser - was ist der Grund hierfür? Eigentlich gibt es zwei Gründe. Entweder hat der Benutzer für keinen der Menüpunkte entsprechende Rechte, oder es existieren keine Menüpunkte. Letzteres ist allerdings unmöglich, da ja bereits die Menüpunkte "Verwaltung" und "Mitarbeiter" definiert sind (siehe zweiten Artikel - Anlegen des Mitarbeiters durch den Administrator) - somit bleibt als Grund nur nur noch das Fehlen der Rechte. Um herauszufinden, ob nun "IntAnzahl" den Wert "0" hat, verwenden wir folglich eine IF-Abfrage, die uns gegebenenfalls zu unserer Datei error.asp unter Angabe der entsprechenden Fehler-ID leitet:

If IntAnzahl = 0 Then Response.Redirect("/~include/error.asp?id=2 ")

Sollte der Wert von "IntAnzahl" nicht "0" sein, fahren wir mit dem Aufbau des Framesets fort.

Jetzt benötigen wir tatsächlich die Datensätze, die den bei der vorherigen Abfrage genannten Kriterien entsprechen - also müssen wir unsere letzte Abfrage nur ohne das COUNT-Statement ausführen lassen:

StrSQL = "SELECT * FROM OLMenue INNER JOIN OLMenueRechte ON (OLMenue.ID = OLMenueRechte.IDMenuepunkt) 
(OLMenue.Istuntermenuevon=0) AND (OLMenueRechte.IdBenutzer = " & CLng(StrLogged_In_User_Id) & ")  
ORDER BY OLMenue.Menuepunkt desc"
Set rs = Conn.Execute(StrSQL)

Nun definieren wir den Beginn unseres Framesets:

Response.Write("<frameset rows=""")

Da wir gemäß dem Aussehen der Outlook-Leiste einen Menüpunkt "aufgeklappt" darstellen möchten, müssen wir diesen größer darstellen, als die anderen. Hierzu bietet es sich an, gleich den ersten Datensatz als "aktiven" (also ausgeklappten) Menüpunkt zu definieren:

IntActive=rs("id")

Jetzt können wir die einzelnen Menüpunkte generieren lassen. Verschiedene Tests haben ergeben, daß die Höhe der Titelleiste idealerweise bei 21 Pixeln liegt. Die Titelleisten werden immer angezeigt, auch wenn Menüpunkte nicht ausgeklappt sind - anders verhält es sich bei den Untermenüs, auf denen die Icons und Titel der Anwendungen untergebracht sind. Diese haben entweder den Wert "0" im eingeklappten Zustand oder "*" für maximal verfügbare Höhe (dies rührt von der HTML-Definition von Frames her) im ausgeklappten Zustand. Was wir also tun müssen, ist, alle Datensätze daraufhin zu prüfen, ob sie aktiv (also ausgeklappt) sind und entsprechend jeweils zwei Frames mit den dazugehörigen Höhenangaben zu definieren:

IntPosition = 0

Do While Not rs.Eof
    IntPosition = IntPosition + 1
    Response.Write("21,")
    If Int(rs("id")) = IntActive Then
        Response.Write("*,")
    Else
        Response.Write("0,")
    End If
    rs.MoveNext
    StrFrames = StrFrames & "<frame name="""
    StrFrames = StrFrames & rs("menuepunkt")
    StrFrames = StrFrames & "bar"""
    StrFrames = StrFrames & " src=""olmenutitle.asp?title=" & Server.UrlEncode(rs("menuepunkt"))
    StrFrames = StrFrames & "&id=" & rs("id")
    StrFrames = StrFrames & "&position=" & IntPosition
    StrFrames = StrFrames & "&Anzahl=" & IntAnzahl
    StrFrames = StrFrames & """ scrolling=no marginwidth=0 marginheigt=0 NORESIZE FRAMEBORDER=0>" & vbCrLf
    StrFrames = StrFrames & "<frame name=""" & rs("menuepunkt")
    StrFrames = StrFrames & """ src=""submenu.asp?id=" & rs("id")
    StrFrames = StrFrames & """ marginwidth=""0"" marginheigt=""0"" noresize frameborder=""0"">" & vbCrLf
Loop

Parallel zum Auf bau des Framesets lassen wir auch die Frames generieren.

Zunächst weisen wir dem Zähler "IntPosition" den Wert "0" zu. Dieser wird bei jedem Durchlauf der Do-While-Schleife um den Wert "1" erhöht. Wie der Name bereits vermuten läßt, gibt der Zähler an, an welcher Position sich der Frame befindet. Auch diese Information müssen wir später auswerten und unsere Scripts entsprechend reagieren lassen.

Zunächst wird bei jedem Durchlauf ein neuer Frame definiert, welchem ein Name zugewiesen wird, der zum einen aus dem Menüpunkt aus der Datenbank besteht und zum anderen aus dem Wort "bar". Weiterhin wird als Quelle die Datei olmenutitle.asp angegeben, gefolgt von den Querystring-Parametern "title", "id", "position" und "Anzahl" welche durch entsprechende Variablen gefüllt werden. Dieser Frame definiert die Menüleiste des jeweiligen Menüpunkts.

Analog hierzu definieren wir einen zweiten Frame, welcher nur den Namen des Menüpunkts aus der Datenbank-Tabelle trägt und als Quelldatei auf die Datei submenu.asp verweist. Als Querystring-Parameter wird die ID des Menüpunkts übergeben. Dieser Frame beinhaltet später die Fläche für die Icons und Titel der Anwendungen des Menüpunkts.

Diese Schleife wird solange durchlaufen, bis alle Menüpunkte, auf die der Benutzer Zugriff erhält, in Frames umgewandelt wurden.

Danach schließen wir die Definition des Framesets mit folgenden Angaben ab:

Response.Write """ framespacing=""0"" name=""OLMENU"" frameborder=""0"" cols=""100%"">" & vbCrLf

Wichtig ist hierbei, daß das Frameset mit einem Namen ("OLMENU") definiert wird, da wir hierauf später mittels clientseitigem JavaScript zugreifen müssen.

Nun haben wir allerdings erst das Gerüst des Framesets definiert - nicht aber die Frames. Was noch fehlt, ist die Ausgabe von "StrFrames", welcher die Definitionen der Frames beinhaltet:

Response.Write StrFrames

Somit haben wir unser Frameset-Grundgerüst für die Outlook-Leiste komplett definiert und können dieses mit dem folgenden Befehl abschließen:

Response.Write "</frameset>" & vbCrLf

Nachdem nun das Grundgerüst erstellt worden ist, müssen wir uns um die Generierung der einzelnen Frameseiten kümmern. Wir beginnen mit der Erstellung der Titelleisten für die einzelnen Menüpunkte - diese befinden sich, wie bereits erwähnt, in der Datei olmenutitle.asp.

Die Titelleisten müssen folgende Merkmale aufweisen: Sie müssen den Titel des jeweiligen Menüpunkts anzeigen und, falls der Menüpunkt geschlossen ist, müssen sie diesen bei einem Klick öffnen. Hieraus resultiert eine Kombination aus server- und clientseitigem Code. Zunächst lesen wir die aus der Datei olmenu.asp übergebenen Querystring-Parameter in lokale Variablen ein.

Um den von Outlook bekannten "Aufklappeffekt" zu realisieren, müssen die Frames dynamisch, d.h. ohne erneutes Laden der Seiten "verschoben" (eigentlich ist es eine Größenänderung) werden. Dies setzt allerdings wiederum voraus, daß das verwendete Skript weiß, welcher Frame welche Größe haben muß und um welchen Frame es sich handelt. Da wir diese Informationen bereits eingelesen haben (Querystring-Parameter), ist das Erzeugen der Javascript-Funktion "show()" mittels ASP kein größeres Problem mehr:

Response.Write "<scr" &amp; "ipt language=""javascript"" 
    ""type=txt/javascript"">" & VbCrLf
Response.Write "function show()" & VbCrLf
Response.Write "{" & VbCrLf
Response.Write("parent.OLMENU.rows=""")
For IntCount = 1 To Anzahl
    If Int(IntCount) = Int(Position) Then
        Response.Write("21,*,")
    Else
        Response.Write("21,0,")
    End if
Next
Response.Write(""";") & VbCrLf
Response.Write "}" & VbCrLf
Response.Write "</scr" & "ipt>" & vbCrlf

Zunächst wird das Frameset "OLMENU" angesprochen - oder genauer: dessen Frames, die untereinander liegen. Danach wird in einer Schleife, die bis zur Anzahl der vorhandenen Menüpunkte zählt, überprüft, ob die Position des aktuellen Frames mit der übergebenen Position übereinstimmt. Ist dies der Fall, so wird definiert, daß beim Aufruf der Funktion "Show()" dieser Frame auf die maximal verfügbare Höhe vergrößert wird. Andernfalls wird an der Größendefinition des Frames nichts geändert.

Sicher Fragen Sie sich, weshalb die &%lt;script> Blöcke so zerlegt werden. Die Lösung des Rätsels finden Sie hier.

Danach folgen zwei clientseitige Skripte "OLBarMout()" und " OLBarMdow()", welche der Optik dienen, d.h. sie simulieren den Button-Effekt der Titelleiste.

Schließlich erfolgt noch die Ausgabe des Titels des Menüpunkts, auf dessen OnClick-Event auch der Aufruf der Funktion "Show()" erfolgt.

Was uns jetzt noch fehlt, damit die Outlook-Leiste komplett dargestellt wird, ist die Datei submenu.asp, welche die Icons und Anwendungstitel des Intranets darstellt.

Auch hier möchte ich Ihnen kurz die theoretischen Grundlagen der Seite näherbringen. Auf dieser Seite sollen alle Icons und Titel der Anwendungen dargestellt werden, welche sich unterhalb des aktiven Menüpunktes befinden und für die der aktuell angemeldetete Benutzer Zugriffsrechte besitzt. Wie Sie sicher sofort festgestellt haben, hatten wir sehr ähnliche Anforderungen bereits in einer der vorangegangenen Dateien. Entsprechend sieht auch die hierfür benötigte Abfrage fast genauso aus:

StrSQL = "SELECT * FROM OLMenue INNER JOIN OLMenueRechte ON (OLMenue.ID = OLMenueRechte.IDMenuepunkt) 
    WHERE (int(OLMenue.istuntermenuevon) <> 0) AND (OLMenueRechte.idbenutzer = " & 
    CLng(Logged_In_User_Id) & ")  ORDER BY OLMenue.menuepunkt"

Der einzige Unterschied besteht in dem Kriterium für die ID der auszuwählenden Menüpunkte. In der vorangegangenen Abfrage hatten wir alle Menüpunkte selektiert, deren Wert im Feld "IstUntermenuevon" "0" war. Jetzt hingegen wählen wir alle Einträge, die der via Querystring-Parameter übergebenen ID entsprechen, aus.

Danach wird das Icon aus der Datenbank für die Anwendung angezeigt - zumindest teilweise:

Response.Write "<img class=""OLMenu"" SRC=""images/ico_"
Response.Write rs("icon") & ".gif """
Response.Write "width=""40"" height=""40"" border=""0"" alt="""
Response.Write rs("menuepunkt") & """"

Der darauffolgende Code bedarf zunächst einiger theoretischer Erklärungen. Zu Beginn des ersten Teils hatten wir definiert, daß unser Intranet in der Lage sein soll, ohne Speicherung der Daten, zwischen den Intranet-Anwendungen wechseln zu können. Um dies zu erreichen verwenden wir für das Umschalten zwischen den Anwendungen den gleichen Ansatz bzw. die gleichen Befehle wie für das Umschalten bzw. Ausklappen der Frames in der Outlook-Leiste - allerdings diesmal in der horizontalen Richtung, d.h. wir generieren exakt die gleiche Anzahl an Frames, wie es Anwendungen gibt und ändern nur die Größe der Frames. Dies geschieht in der Datei content.asp, welcher wir uns später widmen werden. Wichtig für uns zu wissen ist im Moment nur, daß das dort definierte Frameset den Namen "frameinhalt" trägt, um es via JavaScript aus unserer Datei submenu.asp ansprechen zu können. Hiermit sind wir auch am Ende der Theorie angekommen und wenden uns nun der technischen Umsetzung zu:

StrSQL1 = "SELECT * FROM OLMenue INNER JOIN OLMenueRechte ON (OLMenue.ID = OLMenueRechte.IDMenuepunkt) 
    WHERE (int(OLMenue.istuntermenuevon) <> 0) AND (OLMenueRechte.idbenutzer = " 
    & CLng(Logged_In_User_Id) & ") ORDER BY OLMenue.menuepunkt"
Set rs1 = Conn.Execute(StrSQL1)	
Do While Not rs1.Eof
    If rs1("id") = rs("id") Then
        Response.Write "100%,"
    Else
        Response.Write "0,"
End If
rs1.MoveNext

Wir erzeugen eine zweite, mit der ersten identischen Abfrage und vergleichen die beiden ID's der Abfragen miteinander - auch hier müßte Ihnen eine Analogie zur Generierung der Titelleiste auffallen - und tatsächlich ist auch hier die weitere Vorgehensweise identisch: sind die ID's gleich, so wird beim OnClick-Event des Bildes der betroffene Frame von der Größe "0" (also unsichtbar) auf die Größe "100%" (voll sichtbar) verändert. Sobald die beiden Do-While-Schleifen komplett durchlaufen sind, ist zu jedem Icon der entsprechende OnClick-Event für den dazugehörigen Frame definiert. Außerdem wird zur besseren Übersicht zu jedem Icon der Titel der Anwendung ausgegeben und wir gelangen zum nächsten Schritt auf dem Weg zu unserem Intranet-Grundgerüst.

Aufbau des Framesets für die Intranet-Anwendungen

Hierbei handelt es sich um die Datei content.asp, von der wir bereits wissen, welchem Zweck sie dient. Deshalb schreiten wir auch sofort zur Tat. Wie nicht anders zu erwarten war, bilden auch hier zwei JOIN-Abfragen die zentralen Elemente unseres Codes. Allerdings kommt hier eine dritte Variante für die Abfrage des Feldes "IstUntermenuevon" zum Einsatz: wir möchten die Anzahl aller Datensätze und die Datensätze selbst, bei denen der Wert des Feldes "IstUntermenuevon" nicht "0" ist:

StrSQL = "SELECT COUNT(*) FROM OLMenue INNER JOIN OLMenueRechte ON 
    (OLMenue.ID = OLMenueRechte.IDMenuepunkt) WHERE ((int(OLMenue.Istuntermenuevon) 
    <> 0) AND (OLMenueRechte.idbenutzer = " & CLng(Logged_In_User_Id) & "))"

sowie

StrSQL = "SELECT * FROM OLMenue INNER JOIN OLMenueRechte ON 
    (OLMenue.ID = OLMenueRechte.IDMenuepunkt) WHERE ((int(OLMenue.Istuntermenuevon) 
    <> 0) AND (OLMenueRechte.idbenutzer = " & CLng(Logged_In_User_Id) & ")) 
    ORDER BY OLMenue.menuepunkt"

liefern uns die gewünschten Ergebnisse und erzeugen mit dieser Schleife

For IntCount = 1 To Anzahl
    Response.Write "<frame name=""frame"
    Response.Write rs("id")
    Response.Write """ src=""/"
    Response.Write rs("link")
    Response.Write "?menutitle="
    Response.Write rs("menuepunkt")
    Response.Write """ marginwidth=""0"" marginheight=""0"" scrolling=""yes"" frameborder=""0"">"
    rs.MoveNext
Next

die Frames, in denen die Anwendungen untergebracht sind.

Gemäß unserer Definition, wie die Tabelle "OLMenue" aufgebaut ist, erhalten wir somit die ID's aller Anwendungen. Wir sind also am Ziel angelegt: das Grundgerüst für unsere Intranet-Anwendung ist fertig!

Administration

Unser Grundgerüst sieht nun zwar unseren Wünschen entsprechend aus, allerdings dürfte sich die Pflege über das manuelle Eintragen, Ändern und Löschen von Menüpunkten und Anwendungen schnell als umständlich und vor allem fehlerträchtig erweisen. Was liegt also näher, ein Tool zu programmieren, das uns diese Arbeit erleichtert?

Am besten wäre es natürlich, wenn man das gewünschte Ergebnis, sprich das Anlegen eines Menüpunktes oder das Löschen einer Anwendung oder auch eines Rechtes für einen Mitarbeiter sofort als Outlook-Leiste angezeigt bekäme. Verfolgt man diesen Gedankengang weiter, ergibt sich früher oder später folgendes Ergebnis:

Die Administration ist so aufgebaut, daß man alle Menüpunkte und Anwendungen innerhalb der Menüpunkte sieht. Die Basis hierfür liefert die bereits besprochene Outlook-Leiste. Diese wurde erweitert, so daß bei allen Menüpunkten und Anwendungen die Möglichkeit besteht, die Rechte der Benutzer zu bearbeiten und den Menüpunkt bzw. die Anwendung zu bearbeiten oder zu löschen. Außerdem wurde ein weiterer fest integrierter Menüpunkt eingebaut, der jederzeit das Anlegen neuer Menüpunkte erlaubt. Ebenso wurde in jeden Menüpunkt ein Anwendungssymbol integriert, welches das Anlegen neuer Verknüpfungen für Anwendungen innerhalb der Menüpunkte erlaubt.

Die technische Umsetzung möchte ich Ihnen nicht länger vorenthalten und wir beginnen mit der Erweiterung unserer Verzeichnisstruktur. Diese sollte jetzt wie folgt aussehen

Die erste Datei, deren Inhalt für uns relevant ist, ist die Datei default.asp im Verzeichnis "/~admin/olmenu". Sie beinhaltet den Grundaufbau der Administrations-Seite. Bevor dieser Aufbau jedoch stattfinden darf, müssen wir überprüfen, ob es sich bei dem angemeldeten Benutzer um einen Administrator handelt, der das Menü administrieren darf. Sie erinnern sich bestimmt daran, daß wir im zweiten Teil der Artikelserie bereits einen sehr ähnlichen Fall hatten (Setup). Wir hatten uns damals die Funktion "Check_Admin" erstellt, auf die wir jetzt ohne Veränderungen wieder zugreifen können. Hierzu inkludieren wir wieder unsere functions.asp, stellen eine Verbindung zur Datenbank her und rufen unsere Prüffunktion auf. Einzig die Fehlerbehandlung (error.asp) bekommt eine andere Fehler-ID übergeben, die sich auf die Menü-Verwaltung bezieht und nicht auf das Intranet-Setup.

Der übrige Teil der Datei "default.asp" besteht aus einfachen HTML-Befehlen, welche mittels Iframes die Seite in zwei Teile spalten und somit das Grundgerüst der Seite definieren. Hierbei wird im linken Iframe auf die Datei welcome.asp verwiesen, welche nur aus HTML-Code besteht und deshalb nicht weiter behandelt wird. Im rechten Frame wird die Datei olmenu.asp aufgerufen, welche das Frameset für die Outlook-Leiste darstellt. Da hier im Vergleich zur Datei olmenu.asp, welche im "normalen" Intranet verwendet wird einige Modifikationen vorgenommen wurden, werden wir uns diese nun genauer betrachten.

Die erste und wohl auffälligste Veränderung ist die Vereinfachung der SQL-Abfragen:

StrSQL = "SELECT COUNT(*) AS IntAnzahl FROM OLMenue WHERE (OLMenue.Istuntermenuevon=0)"

bzw.:

StrSQL = "SELECT * FROM OLMenue WHERE (OLMenue.Istuntermenuevon=0) ORDER BY OLMenue.Menuepunkt desc"

Der Grund hierfür ist, daß wir ja jetzt nicht mehr nur die Menüpunkte und Anwendungen anzeigen möchten, für die der angemeldete Benutzer Berechtigungen besitzt, sondern es sollen alle Menüpunkte und Anwendungen angezeigt werden, um diese bearbeiten zu können.

Eine weitere Veränderung, die notwendig wurde, ist die Definition des Framesets. Bisher wurden alle Frames dynamisch aus der Tabelle "OLMenue" erzeugt. Die Änderung besteht hierin, daß nun ein Frame immer angezeigt wird, welcher unseren bereits angesprochenen Frame zur Definition neuer Menüpunkte beinhaltet:

Response.Write("<frameset rows=""21,")

Erst nach dessen Definition werden die dynamisch generierten Frames angezeigt:

IntActive=rs("id")
Do While Not rs.Eof
    Response.Write("21,")
    If Int(rs("id")) = IntActive Then
        Response.Write("*,")
    Else
        Response.Write("0,")
    End If
    rs.MoveNext
Loop
Response.Write """ framespacing=""0"" name=""OLMENU"" frameborder=""0"" cols=""100%"">" & vbCrLf

Eine weitere Änderung, die mit dieser einhergeht, ist die Definition des Frames, den wir soeben im Frameset definiert haben:

Response.Write "<frame src=""olmenutitleneu.asp?title=" & Server.URLEncode("neuer Menüpunkt") & 
    """ name=""new"" id=""new"" frameborder=""0"" scrolling=""No"" noresize marginwidth=""0"" 
    marginheight=""0"">" & VbCrLf

Dieser verweist auf die Datei olmenutitleneu.asp, welche nur eine minimale Veränderung beim Onclick-Event erfahren hat. Diese sorgt nun nicht mehr für das Verschieben der Frames ("Aufklappen"), sondern für den Aufruf der Datei new.asp, welche uns das Anlegen neuer Menüpunkte und Verknüpfungen von Anwendungen erlaubt.

Wie Sie bei näherer Betrachtung des Onclick-Events der olmenutitleneu.asp sehen können, wird beim Aufruf der Datei new.asp der Querystring-Parameter "typ" übergeben:

onclick="top.control.location.href='new.asp?typ=Menuepunkt'">

Der Grund hierfür ist, daß wir so nur eine Datei für das Anlegen von Menüpunkten und Verknüpfungen für Anwendungen benötigen.

Hierzu werten wir in der Seite "new.asp" den Querystring-Parameter "typ" mittels einer Select-Case-Abfrage aus. Die Abfrage des Namens für den neuen Menüpunkts erfolgt mittels einfachen HTML-Befehlen und einer anschließenden Prüfung durch JavaScript, welche wir bereits im zweiten Artikel ausführlich behandelt haben.

Bevor wir uns dem Anlegen neuer Verknüpfungen für Anwendungen zuwenden, betrachten wir die Datei submenu.asp, welche das neu hinzugekommene Icon für den Aufruf eben dieser Funktion beinhaltet.

Wie Sie bereits vermutet haben, wurden auch hier die SQL-Abfragen geschrumpft:

StrSQL = "SELECT * FROM OLMenue WHERE (OLMenue.istuntermenuevon= " & Id & ") ORDER BY OLMenue.menuepunkt"

Die zweite SQL-Abfrage wurde komplett gelöscht, da der Aufruf des Framesets wie er im Normalbetrieb des Intranets verwendet wird, nicht notwendig ist.

Hinzugekommen hingegen ist die Definition des immer eingeblendeten Icons für die Definition neuer Anwendungen:

Response.Write "<tr>"
Response.Write "<td class=""OLMenu"" align=""center"">"
Response.Write "<br>"
Response.Write "<img class=""OLMenu"""" SRC=""/~olmenu/images/ico_anwendung_neu.gif"" 
    onMouseOver=""OLMove()"" OnMousedown=""OLMdow()"" OnMouseUp=""OLMove()"" 
    OnMouseOut=""OLMout()"" style=""cursor: hand;"""" width=""40"" height=""40"" 
    border=""0"" alt="""" OnClick=""top.control.location.href='new.asp?typ=Anwendung'"">"
Response.Write "<br>"
Response.Write "Neue Anwendung definieren"
Response.Write "</td>"
Response.Write "</tr>"

Auch hier befindet sich der Aufruf der Datei "new.asp", jedoch mit dem Querystring-Paramenter "typ" für Anwendungen.

Eine weitere offensichtliche Erweiterung ist, daß Icons für das Anzeigen der Rechte Löschen und Bearbeiten hinzugekommen sind, welche auf die entsprechenden Dateien verweisen - dies gilt übrigens auch für die Menüpunkte - hier die Icons im einzelnen:

Anzeigen der Rechte

Bearbeiten

Löschen

Doch zunächst kehren wir nochmals zur Datei new.asp zurück, um die Parameter für neue Verknüpfungen für Anwendungen abzufragen. Auch hier besteht der wesentliche Teil aus HTML-Befehlen und JavaScript-Prüfungen. Die Auswahl des Menüpunkts, in dem die neue Anwendung angelegt werden soll, geschieht über eine Selectbox. Die angezeigte Werte bezieht die Selectbox aus der Tabelle "OLMenue":

StrSQL = "SELECT * FROM OLMenue WHERE IstUntermenuevon = 0 ORDER BY Menuepunkt"
Set rs = Conn.Execute(StrSQL)
Response.Write "<select name=""menuepunkt"" id=""menuepunkt"">"
Response.Write "<option value="""">" & VbCrLf
Do While Not rs.Eof
    Response.Write "<option value=""" & rs("ID") & """>" & rs("Menuepunkt") & VbCrLf
    rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Conn.Close
Response.Write "</select>" & VbCrLf

Nach dem Klick auf den "anlegen"-Button gelangen wir auf die Seite logik.asp. Zunächst werten wir das versteckte Formularfeld "action" mittels einer Select-Case-Abfrage aus, sodaß wir nur eine Datei für Funktionen (Bearbeiten, Löschen, Anlegen, Rechte) benötigen. Durch die bereits besprochene Datei new.asp wird hierfür entweder der Wert "new_menuepunkt" oder "new_anwendung" übergeben.

Da das Anlegen neuer Menüpunkte und Anwendungen fast identisch ist, erkläre ich Ihnen das Speichern nur anhand der Anwendungen:

Dim StrAnwendung
Dim IntMenuepunkt
Dim StrLink
Dim StrIcon
StrAnwendung = Request.Form("anwendung")
IntMenuepunkt = Request.Form("menuepunkt")
StrLink = Request.Form("link")
StrIcon = Request.Form("icon")
Set rs = Server.CreateObject ("ADODB.Recordset")
rs.Cursortype = 1 'adOpenKeyset
rs.Locktype = 3 'adLockOptimistic
rs.Open "SELECT * FROM OLMenue", Conn
rs.AddNew
    rs.Fields("Menuepunkt") = StrAnwendung
    rs.Fields("IstUntermenuevon") = IntMenuepunkt
    rs.Fields("Link") = StrLink
    rs.Fields("Icon") = StrIcon
rs.Update
rs.Close
set rs = Nothing
Conn.Close
Response.Write "<script language=""JavaScript"">" & VbCrLf
Response.Write "<!--" & VbCrLf
Response.Write "    {" & VbCrLf
Response.Write "    top.OLMENU.location.reload();" & VbCrLf
Response.Write "    self.location.href=""welcome.asp"";" & VbCrLf
Response.Write "    }" & VbCrLf
Response.Write "//-->" & VbCrLf
Response.Write "</script>" & VbCrLf

Nach dem Auslesen der übergebenen Formulardaten werden diese in die Tabelle "OLMenue" geschrieben. Nach dem Schreibvorgang werden die Seiten olmenu.asp und welcome.asp neu geladen.

Nachdem nun neue Menüpunkte oder Anwendungen definiert sind, müssen diesen für die einzelnen Benutzer Rechte zugewiesen werden. Dies geschieht über die Datei rights.asp, welcher via Querystring-Parameter die ID des Menüpunkts oder der Anwendung übergeben wird.

Nach den bereits üblichen Includes, dimensionieren der Variablen und der Verbindung zur Datenbank, wird zunächst der Name des Menüpunkts oder der Anwendung aus der Tabelle "OLMenue" gelesen und angezeigt. Hierbei ist keine Unterscheidung zwischen Menüpunkten und Anwendungen notwendig, da sich die Rechtevergabe bei beiden identisch gestaltet.

In der darauf folgenden SQL-Abfrage:

StrSQL = "SELECT Mitarbeiter.Vorname, Mitarbeiter.Nachname, NetzwerkUser.ID FROM Mitarbeiter 
INNER JOIN NetzwerkUser ON  Mitarbeiter.NetzwerkUser = NetzwerkUser.ID WHERE NetzwerkUser.ID IN 
(SELECT IDBenutzer FROM OLMenueRechte WHERE (IDMenuepunkt =  " & ID & ") AND (IstLoeschbar = TRUE)) 
ORDER BY Mitarbeiter.Nachname, Mitarbeiter.Vorname"

werden alle Mitarbeiter ausgelesen, deren zugeordneter Netzwerkbenutzername Berechtigungen zum Öffnen bzw. Anzeigen des Menüpunkts oder der Anwendungen besitzt. Hierbei verwenden wir eine JOIN-Abfrage, die mittels des SQL-Operators "IN" mit einer SELECT-Abfrage verknüpft wird. Hierdurch werden zunächst alle Benutzer-Ids aus der Tabelle "OLMenueRechte" gelesen, die bereits löschbare Rechte für den aktuellen Menüpunkt (bzw. die Anwendung) besitzen. Durch den IN-Operator werden aus der Tabelle "Mitarbeiter" in der JOIN-Abfrage nur diese Mitarbeiter ausgewählt, deren Netzwerkuser (deshalb die JOIN-Abfrage) in der vorher genannten SELECT-Abfrage enthalten sind.

Diese werden, wie weiter oben in diesem Artikel bereits besprochen, in einer Selectbox dargestellt, welche wiederum mittels JavaScript beim Klick auf den Button "Rechte entziehen" überprüft wird (auch diese Funktion haben wir heute bereits besprochen - Anlegen neuer Anwendungen).

Auf der gleichen Seite befindet sich auch die Funktion zum Anlegen der Rechte für die Mitarbeiter. Diese unterscheidet sich nur in der SQL-Abfrage und den JavaScriptbezeichnern. Hier die SQL-Abfrage:

StrSQL = "SELECT Mitarbeiter.Vorname, Mitarbeiter.Nachname, NetzwerkUser.ID FROM Mitarbeiter 
INNER JOIN NetzwerkUser ON  Mitarbeiter.NetzwerkUser = NetzwerkUser.ID WHERE NetzwerkUser.ID NOT 
IN (SELECT IDBenutzer FROM OLMenueRechte WHERE IDMenuepunkt =  " & ID & ") ORDER BY 
Mitarbeiter.Nachname, Mitarbeiter.Vorname"

Der Unterschied der SQL-Abfrage liegt in dem Schlüsselwort "NOT", welche die vorhergehende Abfrage "umdreht", d.h. es werden alle Mitarbeiter ausgewählt, deren Netzwerkbenutzer keine Berechtigungen für den Menüpunkt oder die Anwendung besitzen.

Nach Auswahl eines der Mitarbeiter in einer der beiden Boxen und dem Klick auf den entsprechenden Button gelangen wird wieder auf die Seite logik.asp. Da die Funktion für das Anlegen neuer Rechte sehr ähnlich mit dem Anlegen der Anwendungen bzw. Menüpunkte ist, möchte ich hierauf nicht mehr näher eingehen. Stattdessen betrachten wir die Funktion zum Löschen der Rechte des jeweiligen Benutzers. Allerdings stellt auch diese keine großen Probleme dar:

Case "del_right"
    Dim IntMenuepunktID
    Dim IntBenutzerID
    IntMenuepunktID = Request.Form("menuepunkt")
    IntBenutzerID = Request.Form("ma_allowed")
    If (IntBenutzerID <> "") AND (IsNumeric(IntBenutzerID) = True) AND (IntMenuepunktID 
            <> "") AND (IsNumeric(IntMenuepunktID) = True) Then
        StrSQL = "DELETE * FROM OLMenueRechte WHERE (IDMenuepunkt = " & IntMenuepunktID 
            & ") AND (IDBenutzer = " & IntBenutzerID & ")"
        Set rs = Conn.Execute(StrSQL)
        Set rs = Nothing
        Conn.Close
        Response.Write "<script language=""JavaScript"">" & vbCrLf
        Response.Write "<!--" & VbCrLf
        Response.Write "    {" & VbCrLf
        Response.Write "    top.OLMENU.location.reload();" & VbCrLf
        Response.Write "    self.location.href=""rights.asp?id=" & IntMenuepunktID & """;" & VbCrLf
        Response.Write "    }" & VbCrLf
        Response.Write "//-->" & VbCrLf
        Response.Write "</script>" & VbCrLf
    Else
        Response.Write "Schwerwiegender Fehler. Bitte starten Sie die Verwaltung neu."
    End If

Entsprechend des Case-Falls "del_right" (definiert über das Hidden-Formularfeld auf der vorhergehenden Seite) werden mittels der SQL-DELETE-Anweisung alle Einträge aus der Tabelle "OLMenueRechte" gelöscht, deren Benutzer-ID und Menüpunkt-ID mit den via Querystring übergebenen Werten übereinstimmen. Nach diesem Vorgang werden, wie bei allen anderen Funktionen auch, die Frame-Inhalt neu geladen, wobei im linken Frame wieder auf die Datei rights.asp (unter erneuter Angabe des Menüpunkts) verwiesen wird. Allerdings wird diese Funktion nur dann ausgeführt, wenn sichergestellt ist, daß die Eingaben nicht manipuliert wurden, sprich die übergebenen Werte weder gelöscht noch verfälscht wurden. Der Sinn dieser Überprüfung ist Ihnen sicher noch bekannt aus dem ersten Teil (error.asp).

Das Löschen der Anwendungen bzw. Menüpunkte möchte ich nur kurz ansprechen, da es sich hierbei um eine simple ja/nein-Abfrage handelt, welche sich aus den bisher behandelten Themen ergibt. Die hierzu verwendete Datei ist die delete.asp, welcher wieder via Querystring die ID des Menüpunkts bzw. der Anwendung, die gelöscht werden soll, mitgeteilt wird. Die DELETE-Statements entsprechen im wesentlichen denen, die wir soeben für das Löschen der Benutzerrechte angewendet haben - einzig die Namen der Tabellen bzw. Felder haben sich geändert.

Was uns jetzt zur Vollständigkeit unserer Menü-Verwaltung noch fehlt, ist das Bearbeiten bestehender Menüpunkte bzw. Anwendungen. In der Datei change.asp befinden sich die entsprechenden Anweisungen. Der Aufbau des HTML-Gerüsts ist nahezu identisch mit dem für das Anlegen neuer Anwendungen bzw. Menüpunkte. Die Änderungen liegen im ASP-Code, welcher anhand der Menüpunkt- bzw. Anwendungs-ID aus der Tabelle "OLMenue" die bereits eingetragenen Werte liest und diese in den HTML-Formularfeldern anzeigt.

Das Anzeigen des Menüpunkts, welchem die Anwendung zugeordnet ist, geschieht in einer Selectbox. Der hierfür benötigt Code sieht wie folgt aus:

Response.Write "<td>" & VbCrLf
StrSQL1 = "SELECT * FROM OLMenue WHERE IstUntermenuevon = 0 ORDER BY Menuepunkt"
Set rs1 = Conn.Execute(StrSQL1)
Response.Write "<select name=""menuepunkt"" id=""menuepunkt"">"
Response.Write "<option value="""">" & VbCrLf
Do While Not rs1.Eof
    Response.Write "<option value=""" & rs1("ID")
    If rs1("id") = rs("istuntermenuevon") Then 
        Response.Write """ SELECTED>"
    Else
        Response.Write """>"
    End If
    Response.Write rs1("Menuepunkt") & VbCrLf
    rs1.MoveNext
Loop
Response.Write "</select>" & VbCrLf
Response.Write "</td>" & VbCrLf

Zusätzlich zur ersten Abfrage starten wir eine zweite SQL-Abfrage, welche nur die Menüpunkte anzeigt. Diese werden dann in der Selectbox dargestellt - allerdings nicht ohne vorher eine If-Abfrage zu durchlaufen, welche überprüft, ob die ID des Menüpunkts aus der zweiten Abfrage identisch ist mit dem Eintrag von "IstUntermenuevon" aus der ersten Abfrage, also dem Menüeintrag, welchem die Anwendung untergeordnet ist. Ist dies der Fall, so wird unter Verwendung des Schlüsselworts "SELECTED" diese Option der Selectbox als bereits voreingestellter Wert beim Laden der Seite angezeigt.

Auch von dieser Seite aus gelangen wir durch einen Klick auf den "Ja"-Button auf die Seite logik.asp und entsprechend der auszuführenden Aktion in den Bereich "change_menuepunkt" bzw. "change_anwendung". Da "change_anwendung" die größere der beiden Funktionen ist und "change_menuepunkt" somit auch ohne Erklärung zu verstehen ist, erkläre ich diese:

Case "change_anwendung"
    ID = Request.Form("ID")
    If (ID <> "") AND (isNumeric(ID) = True) Then
        StrAnwendung = Request.Form("anwendung")
        IntMenuepunkt = Request.Form("menuepunkt")
        StrLink = Request.Form("link")
        StrIcon = Request.Form("icon")
        Set rs = Server.CreateObject ("ADODB.Recordset")
        rs.Cursortype = 1 'adOpenKeyset
        rs.Locktype = 3 'adLockOptimistic
        rs.Open "SELECT * FROM OLMenue where ID = " & ID & "", Conn
        If rs.Eof AND rs.Bof Then
            Response.Write "Schwerwiegender Fehler. Bitte starten Sie die Verwaltung neu."
        Else
            rs.Fields("Menuepunkt") = StrAnwendung
            rs.Fields("IstUntermenuevon") = IntMenuepunkt
            rs.Fields("Link") = StrLink
            rs.Fields("Icon") = StrIcon
        rs.Update
        rs.Close
        set rs = Nothing
        Conn.Close
        Response.Write "<scr" & "ipt language=""JavaScript"">" & VbCrLf
        Response.Write "<!--" & VbCrLf
        Response.Write "	{" & VbCrLf
        Response.Write "	top.OLMENU.location.reload();" & VbCrLf
        Response.Write "	self.location.href=""welcome.asp"";" & VbCrLf
        Response.Write "	}" & VbCrLf
        Response.Write "//-->" & VbCrLf
        Response.Write "</scr" & "ipt>" & VbCrLf
        End If
    Else
        Response.Write "Schwerwiegender Fehler. Bitte starten Sie die Verwaltung neu."
	End If

Nach den bereits bekannten Aktionen, wie dem Auslesen der übergebenen Formularfelder und dem Prüfen der ID auf Manipulation, rufen wir eine SQL-Anweisung auf, welche uns den zu verändernden Datensatz aus der Tabelle "OLMenue" liefert. Sofern ein Datensatz zurückgeliefert wird, überschreiben wir dessen Werte mit den neuen Eingaben. Anschließend speichern wir diese Änderungen mittels rs.Update in die Tabelle zurück. Der nachfolgende JavaScript-Teil erledigt den Reload der Frames.

Schlußbemerkung

Somit sind wir am Ende des dritten Artikels zur Erstellung eines Intranet mit ASP angelangt.

Die volle Funktionalität des heute erarbeiteten Codes werden Sie morgen einsetzen können, denn dann werden wir den aus dem zweiten Teil bekannten Mitarbeiter-Assistenten für weitere Mitarbeiter zugänglich machen und das Grundgerüst des Intranets weiter vervollständigen. Außerdem werden wir zur Verwaltung der Mitarbeiter ein Treeview einführen und eine Navigationsleiste erstellen.

Redaktioneller Hinweis

Aufgrund des Umfanges des Intranets - und der damit möglichen Fehlerquellen bei der Umsetzung auf den unterschiedlichen Serverkonfigurationen der Leser - bittet der Autor, die Anfragen über öffentliche Foren (so zum Beispiel aspGerman) oder die ASPIntranet Mailingliste abzuwickeln. Fehler in ASPIntranet können Sie auf der Bugreport-Seite von ASPIntranet melden.

This printed page brought to you by AlphaSierraPapa

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20010919.zip

Verwandte Artikel

Erstellung eines Intranets in ASP - Grundlagen
http:/www.aspheute.com/artikel/20010917.htm
Erstellung eines Intranets in ASP (Teil 2) - Setup
http:/www.aspheute.com/artikel/20010918.htm
Erstellung eines Intranets in ASP (Teil 4) - Mitarbeiter
http:/www.aspheute.com/artikel/20010920.htm
Erstellung eines Intranets in ASP (Teil 5) - Application Day
http:/www.aspheute.com/artikel/20010921.htm
Redirects mit Frame-Targets
http:/www.aspheute.com/artikel/20010530.htm

Links zu anderen Sites

ASPIntranet.de
http://www.aspintranet.de/
IN Operator
http://sqlcourse2.com/setoper.html
selfhtml: Iframe
http://www.teamone.de/selfhtml/tcid.htm

 

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.