Startseite / Vorlagenentwicklung / Formulare / Eingabekomponenten / Migrationsleitfaden für FS_LIST / FS_LIST, Typ DATABASE → FS_INDEX

FS_LIST, Typ DATABASE → FS_INDEX

Inhaltsverzeichnis

Bei der Umstellung der Eingabekomponente FS_LIST auf FS_INDEX ist Folgendes zu beachten.

Wenn Daten mit FS_INDEX gespeichert wurden, können diese bei einer evtl. späteren Rückkehr zu FS_LIST (aufgrund eines abweichenden Datenformats) nicht mehr von FS_LIST gelesen und interpretiert werden.

Aktionen und Regeln

In FS_LIST-Komponenten wird auf dem Formular-Register über das <ACTIONS>/<ACTION>-Tag definiert, welche Bearbeitungsmöglichkeiten (z. B. „Neu“, „Bearbeiten“, „Löschen“) zur Verfügung stehen sollen. Für FS_INDEX-Komponenten wird dies über das Regel-Register definiert.

Hierbei ist zu Beachten, dass die Einblende-Logik der verfügbaren ACTIONs umgekehrt ist. Wenn eine der ACTIONs für die FS_LIST definiert wurde, braucht für die FS_INDEX nichts getan zu werden. Fehlt in der FS_LIST eine ACTION, so muss diese für die FS_INDEX Eingabekomponente explizit ausgeblendet werden.

Folgende ACTIONs für die FS_LIST stehen in der FS_INDEX Eingabekomponente automatisch zur Verfügung, können aber explizit ausgeblendet werden:
ADD / NEW / REMOVE / EDIT

Folgende ACTIONs stehen automatisch zur Verfügung und können nicht deaktiviert werden:
VIEW / UP / DOWN

Folgende ACTIONs werden von FS_INDEX nicht unterstützt:
DELETE / COPY / GOTO

Formularbeispiel

Formulardefinition der Eingabekomponente FS_LIST:

<FS_LIST name="BEZEICHNER" rows="5">
<DATASOURCE type="database" useLanguages="no">
<ACTIONS>
<ACTION name="ADD"/>
<ACTION name="REMOVE"/>
<ACTION name="UP"/>
<ACTION name="DOWN"/>
<ACTION name="GOTO"/>
<ACTION name="EDIT"/>
</ACTIONS>
<COLUMNS>
<COLUMN show="no">#identifier</COLUMN>
</COLUMNS>
<LAYOUT>
<ADD component="toolbar" constraint="top"/>
<ADD component="overview" constraint="center"/>
<ADD component="stackedview" constraint="bottom"/>
</LAYOUT>
<table>TABELLENVORLAGE</table>
</DATASOURCE>
<LANGINFOS>
<LANGINFO lang="*" label="Datensatzauswahl"/>
</LANGINFOS>
</FS_LIST>

In diesem Beispiel werden für die FS_LIST alle Buttons bis auf „NEW“ erlaubt, d.h. für FS_INDEX muss über eine Regel der „NEW“ Button ausgeblendet werden.

Formulardefinition der Eingabekomponente FS_INDEX:

 <FS_INDEX name="BEZEICHNER">
<LANGINFOS>
<LANGINFO lang="*" label="Datensatzauswahl"/>
</LANGINFOS>
<SOURCE name="DatasetDataAccessPlugin">
<TEMPLATE uid="schema.table"/>
</SOURCE>
</FS_INDEX>

Regeldefinition der Eingabekomponente FS_INDEX:

<RULES>
<RULE when="ONLOCK">
<WITH>
<FALSE/>
</WITH>
<DO>
<PROPERTY name="NEW" source="BEZEICHNER"/>
</DO>
</RULE>
</RULES>

Beschriftungen

Die Beschriftung von Einträgen einer FS_LIST-Eingabekomponente wird mithilfe von #item.BEZEICHNER innerhalb des LABELS/LABEL-Tags modelliert. Die Beschriftung von Einträgen einer FS_INDEX-Eingabekomponente wird nicht innerhalb der Formulardefinition sondern über eine entsprechende Schnipseldefinition vorgenommen. Hierzu wird die Schnipsel-Definition der gewählten Tabellenvorlagen verwendet.

Höhe der Eingabekomponente

Der Parameter height bezieht sich im Falle von FS_LIST-Komponenten auf die Höhe in Pixeln, bei FS_INDEX auf die Anzahl der Zeilen.

Anzahl der Einträge

In FS_LIST-Komponenten wird mithilfe des Parameters maxEntries festgelegt, wie viele Einträge hinzugefügt werden dürfen. In FS_INDEX wird dies über eine Regel mit der Eigenschaft SIZE erreicht.

FS_LIST

<FS_LIST name="BEZEICHNER" rows="5">
<DATASOURCE type="database" useLanguages="no" maxEntries="4">
<ACTIONS>
<ACTION name="ADD"/>
<ACTION name="REMOVE"/>
<ACTION name="UP"/>
<ACTION name="DOWN"/>
<ACTION name="GOTO"/>
<ACTION name="EDIT"/>
</ACTIONS>
<COLUMNS>
<COLUMN show="no">#identifier</COLUMN>
</COLUMNS>
<LAYOUT>
<ADD component="toolbar" constraint="top"/>
<ADD component="overview" constraint="center"/>
<ADD component="stackedview" constraint="bottom"/>
</LAYOUT>
<table>TABELLENVORLAGE</table>
</DATASOURCE>
<LANGINFOS>
<LANGINFO lang="*" label="Datensatzauswahl"/>
</LANGINFOS>
</FS_LIST>

FS_INDEX

<RULE>
<WITH>
<LESS_THAN>
<PROPERTY name="SIZE" source="BEZEICHNER"/>
<NUMBER>4</NUMBER>
</LESS_THAN>
</WITH>
<DO>
<PROPERTY name="ADD" source="BEZEICHNER"/>
</DO>
</RULE>

Ausgabe

Werden Einträge mittels $CMS_FOR(...)$ ausgegeben, muss im Falle von FS_INDEX der Methodenaufruf .getValues (oder in Bean-Syntax .values) ergänzt werden:

FS_INDEX

$CMS_FOR(VARIABLE, LISTENNAME.values)$
$CMS_VALUE(VARIABLE.ELEMENT)$
$CMS_END_FOR$

FS_LIST

$CMS_FOR(VARIABLE, LISTENNAME)$
$CMS_VALUE(VARIABLE.ELEMENT)$
$CMS_END_FOR$

Bei der Verwendung des DatasetDataAccessPlugin muss zusätzlich beim Zugriff auf die Eingabekomponenten des Datensatzes anstelle von var.<Name der inneren Eingabekomponente> nun var.formData.<Name der inneren Eingabekomponente> verwendet werden:

FS_INDEX

$CMS_FOR(VARIABLE, LISTENNAME.values)$
$CMS_VALUE(VARIABLE.formData.ELEMENT)$
$CMS_END_FOR$

FS_LIST

$CMS_FOR(VARIABLE, LISTENNAME)$
$CMS_VALUE(VARIABLE.ELEMENT)$
$CMS_END_FOR$
Wichtig Die Ausgabe einer FS_INDEX-Eingabekomponente mithilfe von $CMS_VALUE(...)$ wird nicht mehr unterstützt und führt zu Generierungswarnungen („use of deprecated value generation method for an index editor“). Die Ausgabe sollte immer über $CMS_FOR(...)$ erfolgen (siehe Beispiel Ausgabe FS_INDEX).

Abfrage im Skript

Werden Einträge in einem Skript ausgelesen, muss dieses folgendermaßen erweitert werden:

FS_INDEX

FormData myFormData = this.mySection.getFormData();
if (st_myDatasetListIndex != null) {
Index myFormfield = (Index) myFormData.get(null, "st_myDatasetList").get();
final DataAccessSession st_myDatasetListDataAccessSession = myFormField.createSession(context);
for (Index.Record record : myFormfield) {
Dataset dataset = (Dataset) st_myDatasetListDataAccessSession.getData(record.getIdentifier());
FormData formData = dataset.getFormData();
Integer myNumber = (Integer) formData.get(null, "st_number").get();
...
}

FS_LIST

FormDataList myListFormDataList = (FormDataList) this.mySection.getFormData().get(null, "st_myDatasetList").get();
for (IdProvidingFormData formdata : myListFormDataList) {
Integer myNumber = (Integer) formdata.get(null, "").get();
...
}

Mit FirstSpirit 2019-11 ist eine vereinfachte Abfrage möglich. Vor Version 2019-11 war <FormField>.createSession(<broker>) noch nicht möglich. Stattdessen wurde <GomIndexSource>.createSession(<broker>, boolean) verwendet.

Automatische Sortierung über "sortOrder"

Die Funktionalität in der FS_LIST, Einträge für die Anzeige automatisch anhand der vorhandenen Daten zu sortieren, steht für FS_INDEX nicht zur Verfügung. In FS_INDEX ist jedoch eine manuelle Sortierung möglich.

Das folgende Beispiel zeigt, wie die Schnipsel der FS_INDEX-Eingabekomponente automatisch sortiert ausgegeben werden:

<Eingabekomponente>.values.sort(x->x.formData.<Sortierfeld>).map(x->x.formData.<Ausgabefeld>).toString(",")

Im folgenden Beispielskript ist zu sehen, wie über einen FS_BUTTON eine FS_INDEX-Eingabekomponente entsprechend sortiert wird:

 <FS_BUTTON name="st_sortDatasets"
onClick="script:custom_index_sort"
style="button"
useLanguages="no">
<LANGINFOS>
<LANGINFO lang="*" label="Sortieren"/>
</LANGINFOS>
<PARAMS>
<PARAM name="field">#field.st_datasets</PARAM>
<PARAM name="criteria">Name</PARAM>
</PARAMS>
</FS_BUTTON>

<FS_INDEX name="st_datasets">
<LANGINFOS>
<LANGINFO lang="*" label=""/>
</LANGINFOS>
<SOURCE name="DatasetDataAccessPlugin">
<TEMPLATE uid="MySchema.MyDataset"/>
</SOURCE>
</FS_INDEX>

Sourcecode des entsprechenden Skripts

formData = element.getFormData();
form = formData.getForm();
gomIndex = form.findEditor(field.getName());
gomIndexSource = gomIndex.source();
dataAccessSession = gomIndexSource.createSession(context, false);

index = field.get();

datasets = new ArrayList();
for (record : index.iterator()) {
identifier = record.getIdentifier();
dataset = dataAccessSession.getData(identifier);
datasets.add(dataset);
}

datasets.sort(new Comparator() {
compare(dataset1, dataset2) {
value1 = dataset1.getEntity().getValue(criteria);
value2 = dataset2.getEntity().getValue(criteria);
return value1.compareTo( value2 );
}
});

index.clear();

for (dataset : datasets.iterator()) {
identifier = dataAccessSession.getIdentifier(dataset);
record = index.create(identifier);
index.add(record);
}

field.set(index);

Das Skript kann so umgeschrieben werden, dass es über alle entsprechenden Knoten iteriert und diese wie gewünscht sortiert.

Manuelle Sortierung über "PERSISTENCEINDEX"

Diese Funktionalität steht in der FS_INDEX-Eingabekomponente standardmäßig zur Verfügung, wobei die Reihenfolge nun spezifisch für jede FS_INDEX-EIngabekomponente gespeichert wird. Datensätze können also problemlos sortiert und an unterschiedlichen Stellen referenziert werden. Um die entsprechende Sortierung der FS_LIST Eingabekomponente für die FS_INDEX Eingabekomponente zu übernehmen, ist es notwendig, die Reihenfolge der Datensätze einmalig per Skript zu setzen.
Bei der FS_LIST-Komponente wurde über eine entsprechende Spalte bei jedem verknüpften Datensatz die Reihenfolge gespeichert. Bei der FS_INDEX-Eingabekomponente wird dies nun über die fs_meta_data-Spalte auf der FS_INDEX-Seite gelöst.

Eine Migration ist über das folgende Beispielskript möglich:

dataset = context.getElement();
dataset.setLock(true, false);
formData = dataset.getFormData();
form = formData.getForm();
indexComponent = form.findEditor("bilder");
source = indexComponent.source();
session = source.createSession(context, false);
positions = Collections.synchronizedSortedMap(new TreeMap());
pictures = formData.get(null, "bilder");
index = pictures.get();

for (record : index.iterator()) {
data = session.getData(record.getIdentifier());
formData = data.getFormData();
position = formData.get(null, "position").get();
positions.put(position, record);
}

sorted = positions.entrySet().stream().sorted(Map.Entry.comparingByKey());
index.clear();

for (el : sorted.iterator()) {
index.add(el.getValue());
}

pictures.set(index);
dataset.setFormData(formData);
dataset.save("Re-sort", false);
dataset.setLock(false, false);

© 2005 - 2022 Crownpeak Technology GmbH | Alle Rechte vorbehalten. | FirstSpirit 2023.1 | Datenschutz