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$
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);