Referenz
Alle Aufrufe des Grid-Builders und der Spalten auf einen Blick. Wie sie zusammenspielen, zeigen die Beispiele in der Navigation.
Alle Aufrufe des Grid-Builders und der Spalten auf einen Blick. Wie sie zusammenspielen, zeigen die Beispiele — hier steht, was es gibt.
Der Builder
| Methode | Wirkung |
|---|---|
.BindTo(daten) |
Die Zeilen. Eine leere Liste ist zulässig. |
.Id(id) |
Eindeutige Id des Grids. Bei mehreren Tabellen auf einer Seite Pflicht. |
.Columns(spalten => …) |
Die Spaltendefinition, siehe unten. |
.EnableSorting(spalte, richtung) |
Anfangssortierung. SortDirection.Ascending / .Descending. |
.EnableSearchBox() |
Suchfeld über der Tabelle. Nur mit AjaxDataUrl — siehe «Grundfall». |
.PageSizeMenu(10, 25, 50) |
Auswahl der Seitengrösse. Nur mit AjaxDataUrl. |
.DefaultPageSize(25) |
Vorgewählte Seitengrösse. Nur mit AjaxDataUrl. |
.HidePaginationIfSinglePage() |
Blätterleiste ausblenden, wenn alles auf eine Seite passt. Nur mit AjaxDataUrl. |
.NoRecordsText(text) |
Text für die leere Tabelle. .NoResultsText(text) setzt denselben Wert — siehe «Ohne Daten». |
.EmptyColumnChar("–") |
Zeichen für leere Zellen; alternativ ein IconType — siehe «Zellen auszeichnen». |
.DisableResponsiveMode(minWidth) |
Schaltet das Zusammenklappen schmaler Spalten ab. |
.EnableRowClick() |
Zeile anklickbar machen — siehe «Zeilenklick». |
.DisableRow(bedingung, einstellungen) |
Zeilen fachlich sperren. Die Einstellungen sind Pflicht (FmhGrid.RowSettings()). |
.DisableRowClientExpression(ausdruck, tooltip) |
Dasselbe, aber im Browser entschieden. |
.EnableRowDragAndDrop() |
Zeilen umsortierbar machen — siehe «Zeilen umsortieren (gridrowmoved)». |
.ClientDataKey(name) |
Feldname der Auswahlkästchen, wenn die Zeilen aus einer Ajax-Datenquelle stammen. Bei BindTo liefert BulkEditCheckbox den Namen. |
.DeleteConfirmMessage(text) |
Rückfrage vor dem Entfernen. Der Text darf Markup enthalten. |
.NestedForm() |
Für Grids, die in einem umschliessenden Formular stehen — siehe «Mehrfachauswahl (bulkeditchange)». |
.IsInAsyncAction() |
Für Aktionen, die per Ajax laufen. |
.EnableRowClickNavigation() gibt es zwar, hat aber keine Wirkung: Der Wert wird gesetzt und
nirgends gelesen. Für den Zeilenklick genügt .EnableRowClick().
Die Spalten
| Methode | Wirkung |
|---|---|
spalten.For(x => x.Feld) |
Wertspalte aus einer Eigenschaft. |
spalten.Custom(x => …, "Titel") |
Freie Spalte; der Ausdruck liefert den Inhalt, auch HTML. Auch für berechnete Werte. |
spalten.Button(x => FmhGrid.…) |
Aktionsspalte, siehe «Aktionen je Zeile». |
spalten.BulkEditCheckbox(x => x.Id) |
Auswahlkästchen für Mehrfachaktionen. |
spalten.ChildFor(icon, x => x.Feld, x => …) |
Aufklappbare Unterzeile, Inhalt steht beim Rendern fest. |
spalten.ChildForAsync(icon, x => x.Anzahl, url) |
Unterzeile, deren Inhalt erst beim Aufklappen geholt wird — siehe «Unterzeilen nachladen». |
Am Spaltenobjekt weiter:
| Methode | Wirkung |
|---|---|
.Named(titel) |
Spaltenüberschrift. Ohne Angabe der Eigenschaftsname. |
.Format("{0:dd.MM.yyyy}") |
Formatzeichenkette für den Wert. |
.Format(GridValueFormat.YesNo) |
Wandelt einen bool in «Ja»/«Nein». |
.Format(GridValueFormat.DataSize) |
Wandelt Bytes in eine lesbare Grösse. Der Wert muss ein int sein. |
.IsSortable() |
Spalte sortierbar machen. |
.SortByKey(x => x.Feld) |
Nach einem anderen Wert sortieren als angezeigt wird. |
.Visible(false) |
Spalte vorhanden, aber ausgeblendet. |
.WidthInPixel(120) |
Feste Breite. |
.ResponsivePriority(n) |
Reihenfolge beim Zusammenklappen; kleiner bleibt länger sichtbar. |
.Tooltip(x => x.Feld) |
Kurzinfo an der Zelle bzw. an der Aufklapp-Schaltfläche. |
.ColumnIcon(IconType.…) |
Symbol der Aufklapp-Schaltfläche; identisch mit dem ersten Parameter von ChildFor. |
.ChildRowColumnText(x => x.Feld, stil) |
Wert neben dem Symbol der Aufklapp-Spalte — siehe «Unterzeilen-Spalte darstellen». |
.CellAttributes(new { … }) / .CellAttributes(x => …) |
Attribute an der Zelle — fest oder je Zeile. |
.ToggleStatus(x => x.Feld) |
Zustand für eine Umschalt-Schaltfläche. |
.OpenFirstChildRowWithContent() |
Erste Unterzeile mit Inhalt beim Laden öffnen. |
.ExpandOpenChildRows(false) |
Geöffnete Unterzeilen offen lassen. |
.IsHtmlEncoded(false) |
Rohes HTML zulassen. Nur für Werte aus vertrauenswürdiger Quelle. |
Die Ereignisse
Das Grid meldet im Browser, was es tut. Alle Ereignisse steigen bis zum document auf — ein
Listener dort genügt also auch für Zeilen, die erst beim Blättern entstehen.
| Ereignis | Wann | Wichtige Felder in detail |
Beispiel |
|---|---|---|---|
griddataloaded |
Die Antwort des Endpunkts ist da. | id, data, totalRecords, totalDisplayRecords |
«Auf geladene Daten reagieren (griddataloaded)» |
gridRowCreated |
Eine Zeile ist gebaut, aber noch nicht sichtbar. | rowIndex, row, element (das <tr>), tableId |
«Zeilen auszeichnen (gridRowCreated)» |
gridCellCreated |
Eine Zelle ist gebaut. | rowIndex, colIndex, row, cell (der gebundene Wert), element (das <td>), tableId |
«Zellen auszeichnen (gridCellCreated)» |
gridButtonClick |
Eine Aktion wurde geklickt, vor der Ausführung. | rowIndex, row, element (die Schaltfläche), tableId |
«Aktion vor dem Ausführen abfangen (gridButtonClick)» |
gridAsyncButtonClicked |
Ein Postback im Hintergrund ist durch und die Tabelle neu geladen. | rowIndex, row, tableId |
«Nach einer Aktion nachziehen (gridAsyncButtonClicked)» |
bulkeditchange |
Eine Auswahl hat sich geändert. | name, id, checked, totalChecked |
«Mehrfachauswahl (bulkeditchange)» |
gridrowmoved |
Eine Zeile wurde verschoben. | rowIndex, rowIndexBefore, row, element, order |
«Zeilen umsortieren (gridrowmoved)» |
childrowclick |
Eine Unterzeile wurde auf- oder zugeklappt. | id (mit #), childTableId, rowIndex, row |
«Unterzeilen» |
Dazu zwei globale Funktionen, die die Komponente im Browser mitbringt — beide erwarten die Id
mit vorangestelltem # und nur bei einer Ajax-Datenquelle:
| Funktion | Wirkung |
|---|---|
gridReload('#id') |
Lädt die Zeilen neu und springt auf die erste Seite — nach einer Änderung am eigenen Filterformular (siehe «Suchformular über der Tabelle»). |
gridReloadFromUrl('#id', adresse) |
Tauscht die Adresse des Endpunkts aus und lädt neu — für Filterwerte, die in der Adresse stehen. |
detail.cell ist nicht der angezeigte Text. Es ist der Wert, an den die Spalte gebunden ist —
und das ist bei einem SortByKey(x => x.Feld) das Sortierfeld, nicht die angezeigte Eigenschaft.
Wer auf den Inhalt einer Zelle reagieren will, liest ihn über detail.row.
detail.buttonId sagt nicht, welche Aktion es war. Bei gridButtonClick und
gridAsyncButtonClicked steht dort die technische Id der Schaltfläche (btn + UUID), die bei jedem
Aufbau der Tabelle wechselt. Auseinanderhalten lassen sich die Aktionen bei gridButtonClick über
detail.element — data-actionbar-btn nennt die Art der Schaltfläche (View, Delete, Custom),
href das Ziel. Bei gridAsyncButtonClicked zeigt detail.element nicht auf die Schaltfläche;
dort bleibt nur detail.row.
Die Id der Tabelle steht nicht überall gleich im detail. Beim Filtern auf die eigene Tabelle
darauf achten:
| Ereignis | Feld | Schreibweise |
|---|---|---|
griddataloaded |
detail.id |
mit # |
gridButtonClick |
detail.tableId |
mit # |
gridRowCreated, gridCellCreated, gridAsyncButtonClicked |
detail.tableId |
ohne # |
Die fünf Ereignisse der Ajax-Tabelle sind der Ersatz für alles, was serverseitig je Zeile lief:
| Serverseitig | Auf dem Ajax-Weg |
|---|---|
| Zeile abhängig von ihren Daten auszeichnen | gridRowCreated — detail.element.classList.add(…) |
.CellAttributes(x => …) |
gridCellCreated |
.EmptyColumnChar(zeichen) |
gridCellCreated — Platzhalter in die leere Zelle schreiben |
Route-Werte je Zeile ausser id |
gridButtonClick — Adresse vor der Ausführung ergänzen |
| Nach einer Aktion die Seite neu aufbauen | gridAsyncButtonClicked |
Server oder Ajax: was wo wirkt
Die Datenquelle entscheidet, wo eine Zeile entsteht — und damit, welche Angabe überhaupt eine
Wirkung hat. Mit BindTo rendert der Server jede Zelle fertig. Mit AjaxDataUrl baut der Browser
sie aus dem JSON des Endpunkts; die Razor-Ausdrücke laufen dann trotzdem, aber nur einmal beim
Aufbau der Seite und mit einer leeren Zeileninstanz. Sie sehen nie einen echten Wert und wirken
deshalb nicht je Zeile.
Daraus folgt die Faustregel: Was wie x => … aussieht und mehr tut, als die Spalte zu beschreiben,
gilt nur mit BindTo. Der Ersatz ist immer einer von zweien — den fertigen Wert aus dem Endpunkt
liefern oder einen JavaScript-Ausdruck über row. angeben.
Builder
| Aufruf | BindTo |
AjaxDataUrl |
Ersatz bzw. Hinweis |
|---|---|---|---|
.BindTo(daten) |
✔ | – | Beides zusammen bringt nichts: Die gerenderten Zeilen ersetzt das Grid beim ersten Laden. |
.AjaxDataUrl(url, methode) |
– | ✔ | Ohne Angabe der Methode POST. Zusatzwerte für den Endpunkt stehen entweder in der Adresse oder in einem Formular der Seite — siehe Rubrik «Filtern». |
.ClientDataKey(name) |
nur Feldname der Kästchen | ✔ | Auf dem Ajax-Weg füllt er zusätzlich die Adressen der Zeilen-Aktionen. |
.EnableSearchBox() |
– | ✔ | Gesucht wird im Endpunkt; er bekommt den Begriff in Search. |
.PageSizeMenu(…) / .DefaultPageSize(n) / .HidePaginationIfSinglePage() |
– | ✔ | Mit BindTo steht paging fest auf false. |
.EnableSorting(spalte, richtung) |
✔ | ✔ | Auf dem Ajax-Weg sortiert der Endpunkt (SortColumnName, SortDirection). |
.DisableRow(bedingung, einstellungen) |
✔ | – | .DisableRowClientExpression(ausdruck, tooltip) |
.DisableRowClientExpression(ausdruck, tooltip) |
– | ✔ | Sperrt alle Aktionen der Zeile, auch Ansehen. |
.EmptyColumnChar(zeichen) |
✔ | – | Kein Ersatz im Builder: Platzhalter in die Datenquelle legen oder über gridCellCreated setzen. |
.NoRecordsText(text) |
✔ | ✔ | Auf dem Ajax-Weg gilt derselbe Text auch für die erfolglose Suche. |
.Id() / .NestedForm() / .DeleteConfirmMessage() / .EnableRowClick() / .EnableRowDragAndDrop() / .DisableResponsiveMode() / .IsInAsyncAction() |
✔ | ✔ |
Spalten
| Aufruf | BindTo |
AjaxDataUrl |
Ersatz bzw. Hinweis |
|---|---|---|---|
spalten.For(x => x.Feld) |
✔ | ✔ | Auf dem Ajax-Weg bindet die Spalte an den Eigenschaftsnamen im JSON. |
spalten.Custom(x => …, "Titel") |
✔ | – | Wert im Endpunkt aufbereiten und mit For binden. Sonst zeigt die Spalte den Wert aus ClientDataKey. |
spalten.BulkEditCheckbox(x => x.Id) |
✔ | ✔ | Auf dem Ajax-Weg ist der Feldname ClientDataKey, nicht der Spaltenname. |
spalten.ChildFor(icon, x => x.Liste, x => …) |
✔ | – | ChildForAsync |
spalten.ChildForAsync(icon, x => x.Anzahl, url) |
✔ | ✔ | Auf dem Ajax-Weg hängt das Grid die Zeilen-Id an die Adresse. Beim serverseitigen Rendern tut es das nicht — dort die Überladung mit x => … verwenden, die je Zeile eine Adresse liefert. |
.Format(…) |
✔ | – | Fertigen Text aus dem Endpunkt liefern. Ausnahme: Datumsspalten stellt der Browser selbst dar (dd.MM.yyyy). |
.IsHtmlEncoded(false) |
✔ | – | Auf dem Ajax-Weg landet der Wert ohnehin als Markup in der Zelle; mit SortByKey läuft er vorher durch den Sanitizer. |
.CellAttributes(new { … }) / .CellAttributes(x => …) |
✔ | – | gridCellCreated |
.Tooltip(x => …) |
✔ | – | Siehe «Zwei Fallen» unten. |
.ChildRowColumnText(x => …, stil) |
✔ | – | .ChildRowColumnTextClientProperty(name, stil) |
.OpenFirstChildRowWithContent() / .ExpandOpenChildRows(false) |
✔ | – | Gehört zu ChildFor und damit zum serverseitigen Weg. |
.Named() / .IsSortable() / .SortByKey() / .Visible() / .WidthInPixel() / .ResponsivePriority() / .ToggleStatus() |
✔ | ✔ |
Zeilen-Aktionen
| Aufruf | BindTo |
AjaxDataUrl |
Ersatz bzw. Hinweis |
|---|---|---|---|
.Disabled(bedingung, tooltip) |
✔ | – | .DisabledClientExpression(ausdruck, tooltip) |
.Visible(bedingung) |
✔ | – | .VisibleClientExpression(ausdruck, stil) |
Route-Werte je Zeile (new { id = x.Id, filter = x.Feld }) |
✔ | nur id |
Alle übrigen Werte werden einmal mit der leeren Zeile berechnet. Zeilenwerte über gridButtonClick anhängen. |
.ClientDataKey("row.Feld") |
– | ✔ | Setzt einen anderen Wert als die Id in die Adresse. |
.DialogMessage(text) |
✔ | ✔ | Auf dem Ajax-Weg entweder ein fester Text oder ein JavaScript-Ausdruck, der row. enthält. |
.RenderAsFormAction() |
✔ | – | Auf dem Ajax-Weg läuft die Aktion ohnehin als Postback. |
.Attributes(new { data_asyncactiondisabled = "true" }) |
– | ✔ | Schaltet den Postback für diese Aktion ab; der Endpunkt muss dann selbst zurückleiten. |
.Property(name) / .Tooltip(text) / .Attributes(…) |
✔ | ✔ |
Die Ausdrücke haben nicht dieselbe Polarität
| Aufruf | Ausdruck trifft zu → |
|---|---|
.VisibleClientExpression(ausdruck) |
Aktion ist sichtbar |
.DisabledClientExpression(ausdruck) |
Aktion ist bedienbar |
.DisableRowClientExpression(ausdruck, tooltip) |
Zeile ist gesperrt |
Die mittlere Zeile überrascht am ehesten: DisabledClientExpression beschreibt trotz seines Namens
den bedienbaren Zustand — gesperrt wird, wenn der Ausdruck nicht zutrifft.
Zwei Fallen
Tooltip(x => …),CellAttributes(x => …)undChildRowColumnText(x => …)setzen intern denselben Sortierschlüssel wieSortByKey. MitAjaxDataUrlbindet die Spalte damit an die Eigenschaft aus diesem Ausdruck: Angezeigt wird zwar weiterhin der richtige Wert, sortiert und gesucht aber über die falsche Spalte. Auf dem Ajax-Weg deshalb nicht verwenden.- Die Antwort des Endpunkts muss in Pascal Case kommen. Das Grid liest
Datasource,TotalRecords,TotalDisplayRecordsundDraw; der Json-Serializer schreibt ohne Zutun Camel Case, und die Tabelle bliebe leer — siehe «Grundfall» der Gruppe «Datasource (Ajax)».