Benutzer mit den meisten Antworten
dynamische Tabelle mit Click-Funktion

Frage
-
Hallo,
ich weiß nicht, ob ich mit meiner Lösung auf dem Holzweg bin oder mir einfach das Verständnis dazu fehlt. Daher möchte ich hier einmal nachfragen.Für eine Schulungsübersicht habe ich aus mehreren Views eine Kreuztabelle per HTML zusammengestellt (siehe Anhang).
Diese wird komplett dynamisch erstellt.
Nun soll bei 1 ein Filter aktiviert werden und bei 2 und 3 verschiedene Aktionen ausgeführt werden können. Dafür wurde in die Felder LinkButtons eingefügt.Die Erstellung der Tabelle wurde in das Init-Ereignis der Site ausgelagert, da hier dann die AddHandler-Anweisung den Buttons die Aktion zuweisen kann.
Nun ist aber das Problem, dass ja beim Klick ein PostBack ausgelöst wird und die Seite jedesmal neu geladen wird.
Dafür hab ich eine Prüfung IsPostBack mit rein getan. Jedoch ist nach Klick auf einen der besagten Button dann die Seite leer, weil ja nix mehr dynamisch erstellt wird.
Also irgendwie dreh ich mich da im Kreis und weiß eigentlich gar nicht so recht, was ich eigentlich fragen soll.Ich versuch es trotzdem einmal:
- Ist die ASP-Tabelle prinzipiell eine gute Wahl oder sollte ich hier auf etwas anderes ausweichen, was evtl. die Ereignisse besser behandelt?
- Wie könnte ich denn das Tabellenfeld direkt klickbar machen, sodass hier der VB-Code ausgeführt werden kann? Ich kann zwar per Eigenschaft ein OnClientClick-Ereignis zuweisen, dass muss dann aber in JavaScript hinterlegt sein, welches dann irgendwie den VB-Code aufruft??
- Hat evtl. jemand einen ganz anderen Lösungsansatz?
Ich hoffe, ich konnte mein Anliegen halbwegs verständlich erläutern und hoffe auf etwas Erleuchtung.
Vielen Dank.
...die Seite:
<%@ Page Title="" Language="VB" MasterPageFile="~/Site/PQMS.master" AutoEventWireup="false" CodeFile="Schulung.aspx.vb" Inherits="Site_QS_Schulung" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="cntInhalt" runat="Server"> <div class=" divHeadline"> <h4> <asp:Label ID="lblHeadline" runat="server" Text="Qualifikationsmatrix" meta:resourcekey="lblHeadlineResource1" /> </h4> </div> <asp:UpdatePanel ID="updPnl" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true"> <ContentTemplate> <div style="border: 1px solid #aaa; padding: 5px;"> <asp:Button ID="btnLoad" runat="server" Text="neu laden" /> <asp:PlaceHolder ID="plcSchulung" runat="server"></asp:PlaceHolder> </div> </ContentTemplate> </asp:UpdatePanel> </asp:Content>
... die Routine zum Aufbau der Tabelle
Protected Sub LoadContent(sender As Object, e As EventArgs) Handles btnLoad.Click Dim dbQS As New dbQSEntities Dim strSKTExt As String = "" Dim skCount As Byte = 0 Dim table As New Table Dim th As TableHeaderRow = Nothing Dim tr As TableRow = Nothing Dim td As TableCell = Nothing Dim lbl As Label = Nothing Dim countQKlassen As Short = 0 'Anzahl der BDE-Klassen Dim countTKlassen As Short = 0 'Anzahl der Tätigkeitsklassen plcSchulung.Controls.Clear() table.ID = "tblSchulung" table.CssClass = "table_s" Dim SKGroup = From g In dbQS.vw_SCHULUNG_GRP_SK Order By g.ORDER_ID Ascending Select g For Each rec In SKGroup If Not IsNothing(rec.BDE_KLASSE) Then countQKlassen += 1 End If Next skCount = SKGroup.Count countTKlassen = skCount - countQKlassen 'Tabelle aufbauen 'Zeile - Klassengruppierung th = New TableHeaderRow With th 'eine leere Zelle über zwei Spalten td = New TableCell With td .ColumnSpan = 2 .CssClass = "header-class-group" End With .Cells.Add(td) 'eine Zelle über den Spalten der BDE-Klassen td = New TableCell With td .ColumnSpan = countQKlassen .Text = "Artikelqualifikationsklassen MA" .CssClass = "header-class-group" End With .Cells.Add(td) 'eine Zelle über den Spalten ohne BDE-Klasse td = New TableCell With td .ColumnSpan = countTKlassen .Text = "Tätigkeitsbereiche MA" .CssClass = "header-class-group" End With .Cells.Add(td) End With table.Rows.Add(th) 'Zeile - Anzahl qualifizierte MA/Klasse 'eine leere Zelle tr = New TableRow td = New TableCell With td .ColumnSpan = 2 .Text = "qualif. MA/Klasse" .CssClass = "header-quali-ma header-text-right" End With tr.Cells.Add(td) For Each rec In SKGroup td = New TableCell With td .ID = "BDE_" & rec.SK_ID .CssClass = "header-quali-ma" .Text = "0" End With tr.Cells.Add(td) Next table.Rows.Add(tr) 'Zeile - BDE-Klassen tr = New TableRow td = New TableCell With td .ColumnSpan = 2 .Text = "BDE-Klasse" .CssClass = "header-bde header-text-right" End With tr.Cells.Add(td) For Each SK In SKGroup td = New TableCell With td .CssClass = "header-bde" .Text = SK.BDE_KLASSE tr.Cells.Add(td) End With Next table.Rows.Add(tr) 'Zeile - Requalifizierungsintervall tr = New TableRow td = New TableCell With td .ColumnSpan = 2 .Text = "Requalifizerungsintervall (Monate)" .ToolTip = "Standardintervall der Schulungsklasse" & vbCrLf & "Abweichende Intervalle lt. Stellenbeschreibung und Mitarbeiter möglich!" .CssClass = "header-requali header-text-right" End With tr.Cells.Add(td) For Each rec In SKGroup td = New TableCell With td .Text = rec.SK_INTERVALL .CssClass = "header-requali" End With tr.Cells.Add(td) Next table.Rows.Add(tr) 'Zeile - Schulungsklassen tr = New TableRow td = New TableCell With td .CssClass = "header-default" .Text = "Schicht" End With tr.Cells.Add(td) td = New TableCell With td .CssClass = "header-default" .Text = "Mitarbeiter" End With tr.Cells.Add(td) For Each SK In SKGroup td = New TableCell lbl = New Label lbl.Text = SK.SK_TEXT With td .CssClass = "header-sk td-clickable" If IsNothing(SK.BDE_KLASSE) Then .CssClass = "header-sk header-sk-ma td-clickable" End If .ID = "SK_" & SK.SK_ID td.Controls.Add(lbl) tr.Cells.Add(td) End With lbl.CssClass = "header-sk-label" Next table.Rows.Add(tr) 'jetzt die Mitarbeiterdatensätze 'welche MA haben überhaupt Schulungen (gruppierte Abfrage des Schulungsviews) Dim MAList = From s In dbQS.vw_SCHULUNG_GRP_MA Order By s.SCHICHT_KURZ, s.STELLE_ID, s.MA_NAME Select s If clSession.IS_SF Then MAList = From s In dbQS.vw_SCHULUNG_GRP_MA Where s.SCHICHT_ID = clSession.SCHICHT_ID Order By s.SCHICHT_KURZ, s.STELLE_ID, s.MA_NAME Select s End If 'jeden MA durchlaufen For Each MA In MAList tr = New TableRow 'zuerst die Schicht td = New TableCell With td .CssClass = "td-default td-default-header header-text-right" .Text = MA.SCHICHT_KURZ .ToolTip = MA.SCHICHT_SF End With tr.Cells.Add(td) 'dann der MA-Name td = New TableCell With td .Text = MA.MA_NAME .ToolTip = MA.MASTATUS_TXT .CssClass = "td-default td-default-header header-text-right" If MA.MASTATUS_ID = 2 Then .CssClass = "td-default td-default-header header-text-right td-status-abwesend" End If End With tr.Cells.Add(td) 'dann die Schulungen 'zuerst alle Schulungsklassen durchlaufen For Each SK In SKGroup Dim MA_SCHULUNG = From m In dbQS.vw_SCHULUNG Where m.MA_ID = MA.MA_ID And m.SK_ID = SK.SK_ID Select MA.MA_NAME, SK.SK_TEXT, m.S_STATUS_ID, m.S_STATUS_TXT, m.MA_ID, m.SK_ID, m.LETZTE, m.SKMA_INTERVALL td = New TableCell If MA_SCHULUNG.Count > 0 Then 'wenn Schulung vorhanden dann Status auswerten Dim btn As New LinkButton btn.Text = "." btn.CssClass = "btn-td" btn.Width = "50" 'die ID aus MitarbeiterID und SchulungsklassenID btn.ID = "MASK_" & MA_SCHULUNG.Single.MA_ID & "_" & MA_SCHULUNG.Single.SK_ID Select Case MA_SCHULUNG.Single.S_STATUS_ID Case 10 td.CssClass = "td-default td-status td-status-10" Case 20 td.CssClass = "td-default td-status td-status-20" Case 30 td.CssClass = "td-default td-status td-status-30" Case 40 td.CssClass = "td-default td-status td-status-40" Case 50 td.CssClass = "td-default td-status td-status-50" Case 60 td.CssClass = "td-default td-status td-status-60" Case Else td.CssClass = "td-default td-status td-status-0" End Select If Not IsNothing(MA_SCHULUNG.Single.LETZTE) Then Dim datNaechste As Date = DateAdd(DateInterval.Month, CDbl(MA_SCHULUNG.Single.SKMA_INTERVALL), CDate(MA_SCHULUNG.Single.LETZTE)) td.ToolTip = MA_SCHULUNG.Single.S_STATUS_TXT & vbCrLf & "letzte: " & MA_SCHULUNG.Single.LETZTE & vbCrLf & "nächste: " & datNaechste Else td.ToolTip = MA_SCHULUNG.Single.S_STATUS_TXT End If td.Controls.Add(btn) AddHandler btn.Click, AddressOf FieldClick Else 'wenn keine Schulung, dann leeres Feld anlegen td.CssClass = "td-default td-nothing" td.Text = " " td.ToolTip = "keine Schulung vorhanden" End If tr.Cells.Add(td) Next table.Rows.Add(tr) Next plcSchulung.Controls.Add(table) End Sub
Viele Grüße, Volker
- Ist die ASP-Tabelle prinzipiell eine gute Wahl oder sollte ich hier auf etwas anderes ausweichen, was evtl. die Ereignisse besser behandelt?
Antworten
-
Hallo Volker,
ein Web Service kann dir grundsätzlich alles zurück geben. Meistens nutzt man aber ein Textbasiertes System wie JSON oder XML. Besonders JSON kann mittels JavaScript sehr einfach ausgelesen werden.
Ein WebService ist eigentöich nichts besonderes. Er gibt halt nur etwas für Programme leicht lesbares anstatt HTML zurück.
Je nachdem wie viele Daten du hast kann es womöglich praktisch sein sämtliche Daten von Anfang an herunter zu laden und alles weitere Clientseitig zu verarbeiten. Das erfordert aber einige JavaScript Kenntnisse und ist nur für kleinere Datenmengen geeignet. Clientseitige Änderungen musst du natürlich trotzdem noch an den server zurück senden.
Bei Linq ist die Frage ob du etwas wie das Entity Framework (also ein ORM) einsetzt. Falls ja, dann wird das Linq Statement in SQL übersetzt und an den Datenbankserver gesendet. Das braucht nur geringfügog nehr Zeit als ein klassischer DataReader. Sobald du die Daten aber auf. NET Seite hast und sie dort mittels Linq verarbeitest, wird es spürbar langsamer. Hinweis: auch bei ORMs kann man Queries Clientseitig ausführen. Beispielsweise indem man .ToList aufruft.
Ich kenne eigentlich auch nur die Leute hier aus dem Forum, was Web betrifft. Vielleicht antwortet ja noch jemand.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort markiert Volker S Donnerstag, 16. März 2017 14:15
Alle Antworten
-
Hallo Volker,
ich würde vermutlich eine ganz normale HTML-Tabelle und JavaScript dafür benutzen. Auf diese Art und Weiße müsste die Seite nicht jedes mal komplett neu geladen werden, sondern könnte einfach anhand der im JavaScript erhaltenen Daten die vorhandene Seite anpassen.
Zu dem Click-Handler siehe hier: onclick Event
Wobei du natürlich auch jQuery oder ein größeres Framework wie Angular o.ä. einsetzen könntest.Zu dynamischen Aufrufen an einen Web-Service aus JavaScript heraus, siehe: AJAX Introduction
Serverseitig brauchst du dafür einfach nur einen Service der die Daten zurück liefert.Kennst du dich etwas mit JavaScript aus? Denn das wäre für diese Lösung die Voraussetzung. Mit dem klassischen ASP.NET Teil kann ich dir leider wenig weiter helfen.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
Hallo Tom,
danke für dein Interesse.Also mit JavaScript hab ich derzeit noch nicht viel am Hut.
Und mit WebServices hatte ich bisher auch noch nichts zu tun.Das wäre dann eine ganz neue Herausforderung.
Könnte mir denn ein Webservice gleich so etwas in der Art eines DataSets zurückgeben? Ich hab da echt überhaupt noch keine Ahnung.Aber noch eine andere Frage: Momentan greife ich die Daten per LinqEntities ab. Bevor ich es jetzt zum Testen umschreibe vorab die Frage, ob performancetechnisch sinnvoller wäre mit einem DataSet/DataReader zu arbeiten?
Zuerst hatte ich die Gruppierung direkt im Linq-Statement untergebracht. Das war die reinste Katastrophe. Die Umstellung auf einen gruppierten View vom SQL-Server war dann ein Quantensprung.
Hast du oder jemand anderes, damit Erfahrung?
Vielen Dank.
Viele Grüße, Volker
- Bearbeitet Volker S Donnerstag, 8. Dezember 2016 13:14
-
Hallo Volker,
ein Web Service kann dir grundsätzlich alles zurück geben. Meistens nutzt man aber ein Textbasiertes System wie JSON oder XML. Besonders JSON kann mittels JavaScript sehr einfach ausgelesen werden.
Ein WebService ist eigentöich nichts besonderes. Er gibt halt nur etwas für Programme leicht lesbares anstatt HTML zurück.
Je nachdem wie viele Daten du hast kann es womöglich praktisch sein sämtliche Daten von Anfang an herunter zu laden und alles weitere Clientseitig zu verarbeiten. Das erfordert aber einige JavaScript Kenntnisse und ist nur für kleinere Datenmengen geeignet. Clientseitige Änderungen musst du natürlich trotzdem noch an den server zurück senden.
Bei Linq ist die Frage ob du etwas wie das Entity Framework (also ein ORM) einsetzt. Falls ja, dann wird das Linq Statement in SQL übersetzt und an den Datenbankserver gesendet. Das braucht nur geringfügog nehr Zeit als ein klassischer DataReader. Sobald du die Daten aber auf. NET Seite hast und sie dort mittels Linq verarbeitest, wird es spürbar langsamer. Hinweis: auch bei ORMs kann man Queries Clientseitig ausführen. Beispielsweise indem man .ToList aufruft.
Ich kenne eigentlich auch nur die Leute hier aus dem Forum, was Web betrifft. Vielleicht antwortet ja noch jemand.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort markiert Volker S Donnerstag, 16. März 2017 14:15
-
Hallo Tom,
Das Problem sind nicht die Datenmengen. Die halten sich in Grenzen. Es sind die verschachtelten Schleifen, um die Kreuztabelle aufzubauen, die am längsten dauern.Also ich hab es jetzt doch mal mit DataSets versucht und diese gegen gespeicherte Prozeduren losgelassen. Das ist nochmals ein enormer Gewinn an Verarbeitungsgeschwindigkeit.
Das ist zwar jetzt etwas mehr Frickelei aber funktioniert für diese Zwecke ganz gut.
Um mich darin jetzt in JavaScript einzuarbeiten, spüre ich schon zu sehr die Zeit, wie sie mir mit ihren kalten Händen um den Hals fasst.
;)Viele Grüße und ein schönes Wochenende.
Viele Grüße, Volker