- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
RULES: Zugriff auf Datensatz aus FS_DATASET
Hallo,
ich habe folgendes Problem:
In einem Formular kann ich einen Datensatz aus einer Mitarbeitertabelle auswรคhlen (FS_DATASET). Mit Regeln mรถchte ich erreichen, dass die ID des ausgewรคhlten Mitarbeiters automatisch in ein anderes Feld des Formulars geschrieben wird (vom Typ CMS_INPUT_NUMBER).
Hintergrund: Das Formular gehรถrt zu einer Tabellenvorlage ("Mitarbeiterdokumente") und auf der Mitarbeiter-Detailseite (Content Projection) brauche ich ein ContentSelect, das mir die richtige Zeile aus der Tabelle "Mitarbeiterdokumente" liefert. Beide Tabellen sind in unterschiedlichen Datenbankschemata (eine sogar extern), so dass ich beim ContentSelect nicht รผber richtige "FirstSpirit-Relationen" gehen kann.
Meine Regel funktioniert aber nicht und loggt eine Warning:
WARN 12.01.2022 15:33:57.834 (de.espirit.firstspirit.forms.rules.Rule): There is no fact 'VALUE' for item 'tt_employee.id'!
Hier das Formular der Tabellenvorlage:
<CMS_MODULE>
<FS_DATASET
name="tt_employee"
allowDelete="no"
allowEdit="no"
allowEmpty="no"
allowNew="no"
hFill="yes"
mode="sheet"
useLanguages="no">
<LANGINFOS>
<LANGINFO lang="*" label="Employee"/>
</LANGINFOS>
<SOURCES>
<CONTENT name="vwintranettflemployees"/>
</SOURCES>
</FS_DATASET>
<CMS_INPUT_NUMBER name="tt_employee_id" hFill="yes" singleLine="no" useLanguages="no">
<LANGINFOS>
<LANGINFO lang="*" label="Employee ID" description=""/>
</LANGINFOS>
</CMS_INPUT_NUMBER>
</CMS_MODULE>
Zugehรถrige Regel:
<RULES>
<RULE>
<WITH>
<PROPERTY name="VALUE" source="tt_employee.id"/>
</WITH>
<DO>
<PROPERTY name="VALUE" source="tt_employee_id"/>
</DO>
</RULE>
</RULES>
Ein รคhnlicher Fall (sehr alt) wurde bereits hier https://community.crownpeak.com/t5/Questions-Answers/Externe-und-interne-Datenquelle-verkn%C3%BCpfen... beschrieben, aber nicht die Lรถsung mit Regeln behandelt.
Muss ich รผber einen ValueService gehen? In der Doku steht aber, dass der ValueService Werte aus FS_DATASET nicht verabeiten kann.
Oder ein Skript, das ich einen FS_BUTTON hรคnge? Ich hรคtte es halt gern automatisch..
Danke fรผr Euren Rat!
Gruร,
Benny
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hallo Benny,
ja, jetzt versteh ich das eigentliche Problem.
Lรถsungsansรคtze kรถnnten sein:
Anstelle einer FS_DATASET Eingabekomponente eine CMS_INPUT_COMBOBOX (mit CMS_INLUDE_OPTIONS) nehmen. Deren VALUE mรผsste eine Zahl (Long oder Integer, abhรคngig von Spaltenkonfiguration in der Datenbank) sein, die man dann einfach per Regel auf eine CMS_INPUT_NUMBER umbiegen kann. Nachteile: bereits gepflegte Daten sind nicht kompatibel, Eingabekomponente ist schlechter zu handhaben fรผr die Nutzer.
In der contentSelect Funktion mittels LIKE die Persistenz der FS_DATASET Eingabekomponente abfragen. Da diese auf eine externe Tabelle zeigt, mรผsste da so etwas wie <KEY><ITEM>#ID</ITEM></KEY> drin stehen, wobei #ID die ID des Datensatzes aus der externen Tabelle ist. Da mรผsstest Du dann mal probieren, wie man den CMS_VALUE_PARAM sauber zusammensetzen muss. Entweder "> + #row.Id + <" oder "\> + #row.Id + \<" oder evtl. auch den String erst im Template zusammensetzen und dann die contentSelect Funktion in einer Formatvorlage nutzen (Konfiguration und Ausgabe), der der zusammengesetzte Parameter รผbergeben wird. {einfacher wรคre es, wenn die ID eindeutig ist - also alle IDs dieselbe Anzahl an Stellen haben. Also ausgeschlossen ist, dass eine ID eine Teilmenge einer anderen ID ist. Halte ich aber fรผr nicht realistisch} Nachteile: Ziemliches "Gefummel" um die Daten sauber abfragen zu kรถnnen, LIKE Statements sind weniger performant
Einen eigenen VALUE Service schreiben, der die FS_DATASET Eingabekomponente ausliest, daraus die ID extrahiert und diese in die andere Eingabekomponente schreibt. Wenn man den an den Focus der FS_DATASET Eingabekomponente knรผpft und den Wert der anderen Eingabekomponente nur รคndert, wenn diese den Wert noch nicht hat, sollte das sauber funktionieren.
Ein Skript/Modul schreiben, welches den Identifier in eine versteckte Eingabekomponente schreibt. Dieses vor jeder Generierung ausfรผhren. Wenn man sich fรผr diese Lรถsung entscheidet, sollte sichergestellt werden, dass die versteckte Eingabekomponente nicht jedes mal neu geschrieben wird. Beispielsweise kann diese per Regel bei jedem manuellen Bearbeiten (onlock) geleert werden. Dann braucht sie nur neu gesetzt zu werden, wenn sie nicht gesetzt ist. Nachteile: wieder "Gefummel", um das sauber und performant hinzubekommen. Funktioniert in der Vorschau der externen Datensรคtze erst nach der nรคchsten Generierung (warum, weiร in zwei Monaten niemand mehr ๐
Ich hoffe, dass hilft irgendwie weiter ๐
Holger
- Tags:
- Hallo Benny
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hallo Benny,
ich antworte einfach mal mit einer Gegenfrage - wozu brauchst Du die CMS_INPUT_NUMBER Eingabekomponente, wenn der Datensatz doch in der FS_DATASET Eingabekomponente ausgewรคhlt ist?
Hol Dir doch einfach von dort die ID und verwende die in der contentSelect Funktion: tt_employee.entity.fs_id mรผsste hier funktionieren.
Viele Grรผรe
Holger
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hallo Holger,
ich verstehe nicht ganz wie Du das meinst - die Content Projektion fรผr die Mitarbeiterdetailseiten geht ja auf eine andere Tabelle (externe Datenbank - die im FS_DATASET referenziert wird) und von dort muss ich mir ja genau die Datensรคtze aus der Tabelle fรผr "Mitarbeiterdokumente" holen, in denen der betreffende Mitarbeiter ausgewรคhlt ist.
Ich wollte das so machen:
<CMS_FUNCTION name="contentSelect" resultname="fr_employeeDocuments">
<CMS_PARAM name="schema" value="tfl" />
<CMS_VALUE_PARAM name="employee_id" value="#row.Id" />
<QUERY entityType="employee_documents">
<FILTERPARAM parameter="employee_id" datatype="java.lang.Long"/>
<EQ attribute="employee_id" datatype="java.lang.Long" parameter="employee_id"/>
</QUERY>
</CMS_FUNCTION>
Oder meinst Du ich soll bei dem contentSelect gar keinen Filter angeben und dann einfach in einer Schleife die employee ID abfragen?
Danke und Gruร,
Benny
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hallo Benny,
ich habe es so verstanden:
Du hast eine Tabellenvorlage mit der FS_DATASET Eingabekomponente und der contentSelect Funktion.
In der ContentSelect Funktion willst Du Datensรคtze aus einem anderen Schema ausgeben. Dafรผr musst Du als Filterparameter die ID des in der FS_DATASET ausgewรคhlten Datensatzes nutzen.
Die contentSelect Funktion kรถnnte dann beispielsweise so aussehen.
Hinweis: als Wert fรผr den CMS_VALUE_PARAM kannst Du eine beliebige Variable nutzen, die zum Ausfรผhrungszeitpunkt der Funktion im Kontext ist. Wenn Du die Variable im Template mittels $CMS_SET(...)$ erzeugst, wรผrde es so nicht funktionieren. Dann mรผsste die contentSelect Funktion (inkl. deren Ausgabe) in ein Formatemplate รผberfรผhrt werden, was nach dem Setzen der Variable per CMS_RENDER aufgerufen wird.
<CMS_FUNCTION name="contentSelect" resultname="fr_employeeDocuments">
<CMS_PARAM name="schema" value="tfl" />
<CMS_VALUE_PARAM name="employee_id" value="tt_employee.entity.fs_id" />
<QUERY entityType="employee_documents">
<FILTERPARAM parameter="employee_id" datatype="java.lang.Long"/>
<EQ attribute="employee_id" datatype="java.lang.Long" parameter="employee_id"/>
</QUERY>
</CMS_FUNCTION>
Voraussetzung ist allerdings, dass die FS_DATASET Eingabekomponente in der Tabellenvorlage vorhanden und korrekt gemappt ist. {Ich erwรคhne das, da die Vorlage zum Pflegen ja eine andere Vorlage als die zur Ausgabe verwendet werden kann}.
Oder anders herum ausgedrรผckt - Du kannst die FS_ID des Datensatzes direkt aus der FS_DATASET Eingabekomponente bekommen. Irgendwelche Konstrukte รผber Regeln sind nur notwendig, wenn Du die ID รผber die Regeln prรผfen willst bzw. die ID benรถtigst, um fรผr andere Eingabekomponente (z.B. FS_INDEX) die Auswahlliste per Regel einschrรคnken willst. Das ist aber laut der initialen Beschreibung nicht dein Anwendungsfall.
Viele Grรผรe
Holger
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hallo Holger,
Leider habe ich mich anscheinend nicht klar genug ausgedrรผckt.
Deshalb erklรคre ich die Anforderung noch ein wenig ausfรผhrlicher:
Es gibt zwei Datenquellen, eine externe und eine interne:
- Datenquelle "Mitarbeiter" (extern, read-only, nicht von FirstSpirit gemanaged)
- aus dieser Datenquelle wird per Content Projection fรผr jeden Mitarbeiter eine Mitarbeiter-Detailseite erzeugt
- Tabellenvolage nicht relevant, da nichts gepflegt werden kann
Anforderung war jetzt, die Mitarbeiterdaten anzureichern mit Dokumenten, die in FirstSpirit liegen und diese als Linkliste auf der Seite des jew. Mitarbeiters auszugeben.
Dazu habe ich eine neue Datenquelle "Mitarbeiterdokumente" angelegt: - Datenquelle "Mitarbeiterdokumente" (von FirstSpirit gemanaged)
- in einem Datensatz wird dem per FS_DATASET aus der externen Datenquelle (s.o.) ausgewรคhlten Mitarbeiter ein oder mehrere Dokumente zugeordnet
zugehรถrige Tabellenvorlage "Mitarbeiterdokumente":
<CMS_MODULE>
<FS_DATASET
name="tt_employee"
allowDelete="no"
allowEdit="no"
allowEmpty="no"
allowNew="no"
hFill="yes"
mode="sheet"
useLanguages="no">
<LANGINFOS>
<LANGINFO lang="*" label="Employee"/>
</LANGINFOS>
<SOURCES>
<CONTENT name="vwintranettflemployees"/>
</SOURCES>
</FS_DATASET>
<CMS_INPUT_NUMBER name="tt_employee_id" hFill="yes" singleLine="no" useLanguages="no">
<LANGINFOS>
<LANGINFO lang="*" label="Employee ID" description=""/>
</LANGINFOS>
</CMS_INPUT_NUMBER>
<FS_CATALOG name="tt_linklist" useLanguages="no">
<LANGINFOS>
<LANGINFO lang="*" label="Document Link List" description=""/>
</LANGINFOS>
<TEMPLATES type="link">
<TEMPLATE uid="file_link"/>
</TEMPLATES>
</FS_CATALOG>
</CMS_MODULE>
Zugehรถrige Regel:
<RULES>
<RULE>
<WITH>
<PROPERTY name="VALUE" source="tt_employee.id"/>
</WITH>
<DO>
<PROPERTY name="VALUE" source="tt_employee_id"/>
</DO>
</RULE>
</RULES>
Jetzt wieder zurรผck zur Datenquelle "Mitarbeiter" (extern), Ausgabe:
Hier will ich jetzt ja auf den Mitarbeiterdetailseiten die fรผr den jew. Mitarbeiter gepflegten Dokumente als Link ausgeben - die ja, von der Content Projection aus gesehen, in einer anderen Tabelle liegen (nรคmlich in der Mitarbeiterdokumente-Datenquelle).
Deshalb wollte ich dieses Contentselect machen, wo ich die aktuelle #row.Id (fs_id gibt's nicht, da nicht von FirstSpirit gemanaged) als Filter nutzen will, um den richtigen Datensatz aus der Mitarbeiterdokumente-Tabelle rauszuholen - damit das funktioniert, muss ich aber die ID in der Mitarbeiterdokumente-Tabelle in einer eigenen Spalte haben (eben der Spalte "employee_id", die ich per obiger Regel setzen will):
<CMS_FUNCTION name="contentSelect" resultname="fr_employeeDocuments">
<CMS_PARAM name="schema" value="tfl" />
<CMS_VALUE_PARAM name="employee_id" value="#row.Id" />
<QUERY entityType="employee_documents">
<FILTERPARAM parameter="employee_id" datatype="java.lang.Long"/>
<EQ attribute="employee_id" datatype="java.lang.Long" parameter="employee_id"/>
</QUERY>
</CMS_FUNCTION>
Ich hoffe Du verstehst jetzt?
Danke und Gruร,
Benny
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hallo Benny,
ja, jetzt versteh ich das eigentliche Problem.
Lรถsungsansรคtze kรถnnten sein:
Anstelle einer FS_DATASET Eingabekomponente eine CMS_INPUT_COMBOBOX (mit CMS_INLUDE_OPTIONS) nehmen. Deren VALUE mรผsste eine Zahl (Long oder Integer, abhรคngig von Spaltenkonfiguration in der Datenbank) sein, die man dann einfach per Regel auf eine CMS_INPUT_NUMBER umbiegen kann. Nachteile: bereits gepflegte Daten sind nicht kompatibel, Eingabekomponente ist schlechter zu handhaben fรผr die Nutzer.
In der contentSelect Funktion mittels LIKE die Persistenz der FS_DATASET Eingabekomponente abfragen. Da diese auf eine externe Tabelle zeigt, mรผsste da so etwas wie <KEY><ITEM>#ID</ITEM></KEY> drin stehen, wobei #ID die ID des Datensatzes aus der externen Tabelle ist. Da mรผsstest Du dann mal probieren, wie man den CMS_VALUE_PARAM sauber zusammensetzen muss. Entweder "> + #row.Id + <" oder "\> + #row.Id + \<" oder evtl. auch den String erst im Template zusammensetzen und dann die contentSelect Funktion in einer Formatvorlage nutzen (Konfiguration und Ausgabe), der der zusammengesetzte Parameter รผbergeben wird. {einfacher wรคre es, wenn die ID eindeutig ist - also alle IDs dieselbe Anzahl an Stellen haben. Also ausgeschlossen ist, dass eine ID eine Teilmenge einer anderen ID ist. Halte ich aber fรผr nicht realistisch} Nachteile: Ziemliches "Gefummel" um die Daten sauber abfragen zu kรถnnen, LIKE Statements sind weniger performant
Einen eigenen VALUE Service schreiben, der die FS_DATASET Eingabekomponente ausliest, daraus die ID extrahiert und diese in die andere Eingabekomponente schreibt. Wenn man den an den Focus der FS_DATASET Eingabekomponente knรผpft und den Wert der anderen Eingabekomponente nur รคndert, wenn diese den Wert noch nicht hat, sollte das sauber funktionieren.
Ein Skript/Modul schreiben, welches den Identifier in eine versteckte Eingabekomponente schreibt. Dieses vor jeder Generierung ausfรผhren. Wenn man sich fรผr diese Lรถsung entscheidet, sollte sichergestellt werden, dass die versteckte Eingabekomponente nicht jedes mal neu geschrieben wird. Beispielsweise kann diese per Regel bei jedem manuellen Bearbeiten (onlock) geleert werden. Dann braucht sie nur neu gesetzt zu werden, wenn sie nicht gesetzt ist. Nachteile: wieder "Gefummel", um das sauber und performant hinzubekommen. Funktioniert in der Vorschau der externen Datensรคtze erst nach der nรคchsten Generierung (warum, weiร in zwei Monaten niemand mehr ๐
Ich hoffe, dass hilft irgendwie weiter ๐
Holger
- Tags:
- Hallo Benny
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vielen Dank Holger fรผr die Erlรคuterung der Optionen...
die ohne Gefummel werde ich mal ausproberen!
Gruร,
Benny

