Liste der Leads anzeigen (kalte Kontakte)Da wir bereits begonnen haben, kann ich endlich über ein geheimes Projekt sprechen, an dem ich in den letzten zwei Jahren gearbeitet habe. Eine der interessanten Funktionen von
Teamwork CRM ist eine Listenansicht.
Dies ist eine leistungsstarke Komponente, die in der Anwendung sieben Mal vorkommt. In der Tat eine Tabelle über Steroide. Ich könnte viel erzählen, aber ich möchte dich nicht langweilen. Ich werde mich darauf konzentrieren, wie wir diese Flexibilität mit nur wenigen Zeilen CSS (Grid) implementiert haben. Das heißt, wie wir umfangreiche Datentabellen erstellen, wie wir die Größenänderung von Spalten unterstützen und vieles mehr.
Zunächst muss der Kontext erläutert werden, beginnend mit dem Zweck und den Entwurfsaufgaben dieser Tabellen. Wenn dies nicht von Interesse ist, zögern Sie nicht, sofort mit der
technischen Implementierung fortzufahren.
Mit unserer Lösung können Kunden zunächst schnell Listen anzeigen, z. B. Leads oder Kontakte, und wichtige Details erkennen. Es sieht nicht wie eine Excel-Tabelle aus - wir sollten uns besser mit dem Datenlayout befassen, wenn es viele davon gibt.
Absolut alles funktioniert in einem adaptiven flexiblen Design. Wir beginnen mit der engsten Option und passen das Layout basierend auf Inhalt, Design und Anwendungsfällen an (wir haben keine geräteorientierten Haltepunkte).
Bei der minimalen Bildschirmbreite werden Spalten vertikal gestapelt und nehmen die gesamte Bildschirmbreite ein.
Wie die Liste auf einem schmalen Bildschirm aussiehtFlexible Tische sind nicht einfach zu machen. Sie können aus
mehreren vorhandenen Vorlagen auswählen. Überlegen Sie, nach welchen Informationen Benutzer suchen, und wählen Sie sie mit Bedacht aus.
Sobald wir genug Pixel auf dem Bildschirm haben, wechseln wir zu einem typischeren Layout, sodass die Spalten ... nun, zu Spalten werden. Dann gibt es keine wesentlichen Änderungen im Layout, aber wir möchten die Spalten dennoch so bequem wie möglich für den Kunden anzeigen.
Angenommen, wir haben viele Spalten (später werden wir uns ansehen, wie der Benutzer sie anpassen kann). Zunächst sollte die Tabelle mindestens die Breite des Bildschirms ausfüllen. Zweitens sollte die Breite der Spalten durch ihren Inhalt und die Art der Werte bestimmt werden. Zum Beispiel Kurz- / Langtext, Datum, Nummer, URL usw. Spalten mit einem Datum sollten weniger Platz einnehmen als Spalten mit Langtext.
Spalten müssen eine Mindestbreite haben. Das Ergebnis ist häufig eine Tabelle, die sowohl vertikal als auch horizontal scrollt.
Wie das Layout hängt, hängt von der Breite des Fensters ab. Entschuldigung für das zuckende GIF, ich werde Ihnen später einige interaktive Beispiele geben.Zunächst verwenden wir maximal das reguläre CSS der alten Schule für die Tabelle. Dann verbessern wir es mit CSS Grid. Dann werde ich zeigen, wie Benutzer die Größe von Spalten mithilfe von Grid-Tools ändern können, was mit normalem CSS viel unpraktischer war.
Nun zeige schon CSS Grid
Ich bin kein CSS Grid-Experte, aber es gefällt mir. Dies ist ein äußerst leistungsfähiges und einfaches Tool, das komplexe Layouts mit minimalem Code implementiert. Hier werde ich die Einführung in die Technologie überspringen. Sie können
die neuen CSS-Layouts von Rachel Andrew oder
The Complete Grid Guide lesen. Wenn Sie darüber nachgedacht haben, wo dieses Werkzeug Ihr ganzes Leben lang war, kommen Sie zu mir zurück.
Wenden Sie zunächst
display:grid
auf
<table>
an, um die Tabelle in ein Raster umzuwandeln. Dies wird nichts kaputt machen: Wenn der Browser Grid nicht unterstützt, verwendet er
display:table
. Die
<thead>
Elemente
<thead>
und
<tbody>
werden zu
<tbody>
. Wir müssen nicht an
<thead>
,
<tbody>
oder sogar
<tr>
denken. Wir möchten unser
<th>
und
<td>
in diesem Raster anordnen, indem wir auf jedes von ihnen
display:grid
anwenden (d. H. Gitter innerhalb der Gitter), aber dies ist nicht ideal. Jedes
<tr>
-Raster ist unabhängig von den anderen, und dies ist nicht gut (Sie werden später feststellen, dass das gleiche Problem mit Flexbox auftritt).
Die Problemumgehung besteht darin,
display:contents
<thead>
auf
<thead>
,
<tbody>
und
<tr>
. Dadurch werden sie im Grunde genommen aus dem Raster entfernt und die untergeordneten Elemente (
<th>
und
<td>
) nach vorne
<td>
.
Dann verwenden wir die magische Regel
grid-template-columns
, um die Gitterelemente zu steuern. Ja, nur eine Zeile CSS. Wenn wir beispielsweise eine Datumsspalte und eine URL-Spalte haben, sieht diese ungefähr so aus:
grid-template-columns: minmax(150px, 1.33fr) minmax(150px, 2.33fr);
Wir verwenden für alle Spalten dieselbe Mindestgröße, aber der Maximalwert (
fr
) wird durch den Datentyp der Spalte bestimmt. Ich habe
auto
und
max-content
ausprobiert, aber wir haben eine bessere Option gefunden. Hier ist ein vereinfachtes Beispiel:
eine interaktive Tabelle mit Code . Versuchen Sie, die Fenstergröße zu ändern.
Ändern der Spaltenbreite mit Raster
Außerdem können Sie in unseren Tabellen tauschen, die Breite ändern und die Spalten ausblenden. Letzteres ist wichtig, da viele Spalten mit unterschiedlichen Datentypen unterstützt werden: Dies sind die Eigenschaften des Elements selbst (z. B. Leads), die Eigenschaften verwandter Elemente (z. B. eines mit einem Lead verknüpften Unternehmens) und benutzerdefinierte Felder.
Beispielsweise kann ein Benutzer ein benutzerdefiniertes Feld (Datum) für Kontakte mit dem Namen "Geburtsdatum" erstellen, das für jeden Kontakt im System verfolgt wird.
Da beim Erstellen eines benutzerdefinierten Felds der Typ "Datum" ausgewählt ist, verarbeitet das System dieses Feld unter Berücksichtigung dieses Typs. Zunächst werde ich erklären, wie sich die Breite ändert.
- Wenn der Benutzer den Cursor über die Spaltenüberschrift bewegt, wird rechts eine Größenänderungsmarkierung angezeigt. Wir hören uns das
mousedown
Ereignis auf dem Größenänderungsregler an.
- Wenn der Benutzer auf den Schieberegler klickt, binden wir einige weitere Methoden, um auf die Ereignisse zum
mousedown
der mousemove
und zum mousedown
der mousemove
(im window
) zu mousedown
. In dieser Phase fügen wir auch einige Klassen für die Dekoration hinzu.
- Wenn der Benutzer die Maus bewegt, berechnen wir die neue Spaltenbreite unter Berücksichtigung der Cursorposition, der Bildlaufposition der Tabelle und des festgelegten Minimums. Dann setzen wir die
grid-template-columns
Regel für <table>
(über das Stilattribut) zurück und ersetzen diesmal den Maximalwert ( fr
) durch einen Pixelwert. Beispiel grid-template-columns: minmax(150px, 1.33fr) 296px;
. Dies geschieht mit requestAnimationFrame
, um eine möglichst reibungslose Animation zu gewährleisten.
- Wenn
mouseup
eintrifft, mouseup
wir die Ereignis-Listener ab und löschen die Klassen.
Probieren Sie
dieses vereinfachte Beispiel aus .
Bemerkenswerterweise reicht es aus, nur ein Element im DOM und nicht jede Zelle zu aktualisieren.
Wir entwickeln immer eine Benutzeroberfläche, die auf Berührungseingaben basiert. In diesem Fall ist es jedoch normal, diese nicht zu unterstützen. Dies ist eine zu genaue Aktion. Selbst wenn ich die Größe der Spalte auf dem Touchscreen ändern wollte, würde ich wahrscheinlich eine weitere Interaktion erwarten, beispielsweise durch eine Multi-Touch-Geste.
Spalten mit fester Breite
Sie haben vielleicht bemerkt, dass Sie über etwas geschwiegen haben. Tatsächlich ändert sich nicht nur die Breite einer Spalte, sondern aller Spalten. Vielleicht haben Sie das gar nicht bemerkt, denn so sollte es funktionieren.
Anfangs dachte ich, Benutzer würden es mögen: Wenn sie Spalten dehnen oder zusammendrücken, passen sich auch andere an. Wenn die Spalten die Breite des Bildschirms gut ausfüllen und Sie eine davon einschränken, können die anderen erweitert werden, wenn Inhalte vorhanden sind, die nicht in eine Zeile passen. Probieren Sie
dieses Beispiel aus .
Nach einigen Benutzertests stellte sich jedoch heraus, dass dies für Menschen ein unerwartetes Verhalten ist. Der Benutzer verspürt einen gewissen Kontrollverlust, wenn seine Handlungen unvorhersehbare Nebenwirkungen verursachen.
Wir sollten keine Annahmen treffen, die darauf beruhen, welche Spalten interagierten und welche nicht. Bei der Größenänderung einer Spalte kann der Benutzer bereits implizit entscheiden, dass die Breite des Rests perfekt ist.
Wenn Sie die Anwendung zum ersten Mal öffnen, werden die Spalten daher optimal angeordnet. Wenn Sie die Bildschirmgröße ändern, ändern sich auch die Spalten nach demselben Prinzip. Sobald Sie den Schieberegler berühren, um die Größe einer Spalte zu ändern, wird die Breite aller sichtbaren Spalten festgelegt.
Vor, während und nach dem Ändern der Spaltenbreite. Wieder tut es mir leid, dass das GIF ein bisschen zucktJedes Mal, wenn die Größe einer Spalte geändert oder festgelegt wird, erstellen wir einen unabhängigen localStorage-Datensatz, der der Spaltenkennung mit einem Pixelwert entspricht, um die Benutzereinstellungen beizubehalten.
Ich kann mich nicht genau erinnern, warum wir beschlossen haben, einen festen Wert in Pixel festzulegen, keine adaptive Option. Vielleicht der Einfachheit halber. Oder weil ohne Unterstützung für Grid und
display:contents
ein Rollback zu einem archaischeren Ansatz zum Anpassen der Breite der Spalten erfolgt.
Wahrscheinlich entspricht die adaptive Option in keinem Fall den Absichten des Benutzers. Wir können nicht davon ausgehen, dass es für ihn am wichtigsten ist, alle Spalten kleiner zu machen, damit sie alle auf dem Bildschirm bleiben. Wenn eine Person die Breite der Spalte geändert hat, möchte sie eine bestimmte Menge an Inhalten in dieser Spalte sehen. Wenn wir einen adaptiven Block haben und dieser dann in einem kleineren Fenster enger wird, ignorieren wir die Wahl der Person. Er muss die Spaltenbreite erneut ändern, um den gleichen Inhalt zu sehen. Es ist unwahrscheinlich, dass der Benutzer denkt: "Hmm, ich möchte, dass diese Spalte 20% des Fensters einnimmt, auch wenn ich sie ändere." Ich gehe jedoch zu tief in die Grenzsituation ein: Tatsächlich ändern Benutzer die Größe von Fenstern selten.
Spalten verschieben und löschen
Schnittstelle zum Anpassen der angezeigten SpaltenStellen Sie sich vor, ein Benutzer hat über diese Schnittstelle eine Reihe von Spalten geändert. Wenn keine der ausgewählten Spalten zuvor geändert wurde, werden sie je nach Datentyp mit den Standardwerten
grid-template-column
angezeigt. Zum Beispiel
minmax(150px, 3.33fr)
.
Wenn die Breite einer Spalte in localStorage festgelegt ist, legen wir die Breite
aller ausgewählten Spalten fest und speichern diese Werte auch in localStorage.
Im Laufe der Zeit behalten immer mehr Spalten eine feste Breite. Für Benutzer besteht die einzige Möglichkeit, zum reaktionsschnellen Design zurückzukehren, darin, die Spalten zurückzusetzen.
Wir speichern auch ein Array von Spaltenkennungen in localStorage, getrennt von den Breiteneinträgen.
"Warum hast du nicht einfach {{libraryName}} verwendet?"
Mit der JavaScript-Bibliothek ist die Lösung schwer, nervös, bietet keine Interaktivität und unterstützt möglicherweise <table> überhaupt nicht. Ich wollte so etwas auch nicht schreiben. Ich dachte: "Es muss einen besseren Weg geben."
"Warum haben Sie nicht einfach Flexbox verwendet?"
Jede Zeile wird unabhängig voneinander ausgewertet / angezeigt. Die Spalte ist aufgrund des unterschiedlichen Inhaltsvolumens möglicherweise nicht an der obigen Spalte ausgerichtet.
Ich könnte für Spalten mit vertikal gruppierten Zellen zu <div> wechseln. Wollte das aber nicht. Ich wollte <table> verwenden. Darüber hinaus können leicht andere Probleme auftreten: beispielsweise eine Nichtübereinstimmung der Zellen in der Höhe zwischen den Spalten.
"Warum hast du nicht einfach <colgroup>
?"
In der Tat ist
<colgroup> ein bequemes altes Element. Nach dem Definieren von Spalten mit <col> werden auf eine angewendete Stile effektiv auf alle Zellen in dieser Spalte angewendet.
Dies stellte sich jedoch als zu begrenzte Lösung heraus. Wir haben es versucht, aber sehr schnell abgelehnt. So schnell, dass ich mich nicht genau an die Probleme erinnern kann. Ich bin mir fast sicher, dass es unmöglich war, das gewünschte Maß an Anpassungsfähigkeit zu erreichen, und es hat mit Flexbox und Grid nicht funktioniert.
"Warum hast du nicht einfach das Tabellenlayout verwendet: behoben?"
Ich könnte das
table-layout: fixed
Regel auf die
<table>
anwenden und die Spaltenbreite als Prozentsatz festlegen. Aber als ich mir die Beispiele ansah und mit dieser Regel spielte, hatte ich den Eindruck, dass sie nur an 100% breiten Tischen funktioniert. Durch Ändern der Größe einer Spalte wird außerdem die Größe der anderen Spalten geändert, um eine Gesamtbreite von 100% zu erreichen.
"Aber Sie könnten mit einfachen Tischen auskommen!"
Ja, die sofort einsatzbereiten Tabellen sind zu vielen intelligenten Dingen fähig, aber sie können nicht alles effektiv unterstützen, was ich implementieren wollte. Nicht einverstanden? Okay Zauberer, lehre mich.
Gehen Sie mit display: content nicht zu weit
Der Wert
display: contents
darf das Tabellenlayout speichern. Verwenden Sie es nur, wenn Sie es wirklich brauchen. Einige Browser haben oder hatten zumindest Probleme mit der Barrierefreiheit und den Bildschirmleseprogrammen.
Wir haben eine
seltsame display: contents
Inhaltsfehler mit nativem Drag & Drop in Firefox.
Glücklicherweise wird in Kürze eine Subgrid-Funktion veröffentlicht, mit der untergeordnete Elemente korrekt in Grids integriert werden können. In unserer Anwendung möchten wir nur das Markup vereinfachen, aber die Subnetze öffnen die Türen zu wilden mehrdimensionalen Gitterorgien. Siehe
„Warum anzeigen: Inhalt ist kein CSS-Rasterlayout“ .
Ich habe wohl etwas vergessen
Es scheint, dass beim Ändern der Spaltengröße immer noch ein Problem mit dem Textüberlauf aufgetreten ist, aber ich erinnere mich nicht genau.
Um die Tabellenüberschriften beim Scrollen nach unten zu speichern, verwenden wir
position: sticky
. Dies ist eine großartige Verbesserung und wird in älteren Browsern sehr gut beeinträchtigt. Für IE11-Benutzer haben wir jedoch Backup-JavaScript. In der Tat würde ich
position: sticky
nicht empfehlen
position: sticky
aufgrund von Schwierigkeiten beim horizontalen Scrollen.
Ich habe einige Funktionen unserer Listenansichten nicht einmal erwähnt. Beispielsweise können Benutzer benutzerdefinierte Filter anwenden, speichern und austauschen (z. B. Leads über 500 US-Dollar bei potenziellen Kunden in Europa anzeigen). In diesen Filtern können Sie sich eine Reihe von Spalten merken, um immer bestimmte Spalten für einen bestimmten Workflow anzuzeigen.
In Kürze werden wir die Massenbearbeitung in der Listenansicht implementieren und benutzerdefinierte Ansichten in CSV exportieren.
Trotzdem danke fürs Lesen.