Juncus
Returning Observer

Per Script FS_Reference-Feld befüllen

Jump to solution

Hallo Zusammen,

 

Ich möchte per Script ein schon befülltes FS_REFERENCE-Formularfeld in den globalen Inhalten durch eine per UID ermitteltes Pageref neu befüllen.

So schaut das Formularfeld aus:

 

<FS_REFERENCE name="ps_speciallink" hFill="yes" imagePreview="no" sections="no" useLanguages="no">
        <FILTER>
          <ALLOW type="pageref"/>
          <HIDE type="documentgroup"/>
        </FILTER>
        <LANGINFOS>
          <LANGINFO lang="DE" label="Verweis" description="."/>
          <LANGINFO lang="*" label="Link" description=""/>
        </LANGINFOS>
        <PROJECTS>
          <LOCAL name=".">
            <SOURCES>
              <FOLDER name="root" store="sitestore"/>
            </SOURCES>
          </LOCAL>
        </PROJECTS>
      </FS_REFERENCE>

 

 

Auf den entsprechenden Formularbereich in der globalen Seite  kann ich zugreifen:

 

StoreElementAgent storeElementAgent = context.requestSpecialist(StoreElementAgent.TYPE);
 GCAPage gcanewpagests = (GCAPage) storeElementAgent.loadStoreElement(gcaPageSTSuid, GCAPage.UID_TYPE, false);
if (gcanewpagests instanceof GCAPage) {               		
        // ### Formdata der GCAPAge holen
	FormData formdatagcanewpage = gcanewpagests.getFormData();
	try {
	        gcanewpagests.setLock(true);
		try {
			formElement = formdatagcanewpage.get(null, "ps_speciallink“);
			 	 		
// ###############
/*
Hier sind mir die Schritte zum Befüllen des FS_REFERENCE-Formularfeldes nicht klar.
Ich habe eine PageRef schon mir über ein Script geholt und will diese jetzt dem schon belegten
FS_REFERENCE-Formularfeldes zuweisen.
formElement.getClass() liefert mir folgendes: class de.espirit.firstspirit.store.access.DataWrappingFormData$EditorValueWrappingFormField
Wie geht es hier weiter?
ReferenceEditorValue? , TargetReference? 
*/
// ###############
               gcanewpagests.setFormData(formdatagcanewpage);
               gcanewpagests.save();
					         
			         
	}
	catch (Exception e) {
		// catch handling		                   
	} finally {
		gcanewpagests.setLock(false);
	}
} catch (LockException e) {
	// catch handling
}
}

 

 

Könnt ihr mir hier weiterhelfen?

Viele Grüße v.
Ralf

0 Kudos
1 Solution

Accepted Solutions
Juncus
Returning Observer

Hallo Michael,

danke für deine ausführliche Erklärung.
Jetzt ist es mir klar. Perfekt.

Hier dann also die Lösung, für alle die es interessiert, die funktioniert:

 

 

StoreElementAgent storeElementAgent = context.requestSpecialist(StoreElementAgent.TYPE);
 GCAPage gcanewpagests = (GCAPage) storeElementAgent.loadStoreElement(gcaPageSTSuid, GCAPage.UID_TYPE, false);
                		if (gcanewpagests instanceof GCAPage) {
                		
                		
                		
                		
                		
                			// ### Formdata der GCAPAge holen
				FormData formdatagcanewpage = gcanewpagests.getFormData();


				
				try {
	         			gcanewpagests.setLock(true);
		         		try {

						

TargetReference targetReferenceNew = TargetReferences.newInstance(null, pageRefTmp, "");
formdatagcanewpage.get(null, "ps_speciallink").set(targetReferenceNew);
			 			gcanewpagests.setFormData(formdatagcanewpage);
					         gcanewpagests.save();
					         
					         
		         		}
		         		catch (Exception e) {
			                    // catch handling
			                   
			                 } finally {
			                     gcanewpagests.setLock(false);
			                 }
		         	} catch (LockException e) {
		         		 // catch handling
				}


}

 

 

View solution in original post

0 Kudos
9 Replies
hoebbel
Crownpeak employee

Hallo Ralf,

ist hier die entsprechende Doku nicht ausreichend?

https://docs.e-spirit.com/odfs/access/de/espirit/firstspirit/access/editor/ReferenceEditorValue.html

Wenn etwas fehlt oder unverständlich ist, sag bitte kurz Bescheid, wie wir die Doku dort verbessern können 🙂

Viele Grüße
Holger

0 Kudos
Juncus
Returning Observer

Hallo Holger,

danke für deine schnelle Antwort.
Mir ist leider nicht klar wie ich das Objekt vom Typ 'de.espirit.firstspirit.store.access.DataWrappingFormData$EditorValueWrappingFormField'  siehe oben weiter behandle um daraus mit der Klasse / Objekt .ReferenceEditorValue weiterarbeiten zu können.

 

ReferenceEditorValue refSearch = formdatagcanewpage.get(null, "ps_searchresult_link");

 

 erzeugt folgenden Fehler:

 

java.lang.ClassCastException: Cannot cast de.espirit.firstspirit.store.access.DataWrappingFormData$EditorValueWrappingFormField to de.espirit.firstspirit.access.editor.ReferenceEditorValue

 


Wäre klasse, wenn mir da jemand einen Tip geben könnte.

0 Kudos
hoebbel
Crownpeak employee

Hallo Ralf,

habs gerade mal ausprobiert. Für mich klappt es (in einer Beanshell Konsole) so:

import de.espirit.firstspirit.agency.StoreElementAgent;
import de.espirit.firstspirit.access.store.mediastore.Media;
import de.espirit.firstspirit.access.editor.value.TargetReference;
import de.espirit.firstspirit.access.editor.value.TargetReference.TargetReferences;

storeElementAgent  = context.requestSpecialist(StoreElementAgent.TYPE);
myMedia = storeElementAgent.loadStoreElement(<mediaUid>,Media.UID_TYPE,false);
targetReference = TargetReferences.newInstance(null, myMedia, "");


<section>.page.setLock(true,true);
fd = <section>.getFormData();
ff = fd.get(null,<FS_REFERENCE name>);
ff.set(targetReference);
<section>.setFormData(fd);
<section>.page.save(true);
<section>.page.setLock(false,true);

ich gehe hierbei von einem Absatz (<section>) aus. Ich versuche dabei, in die FS_REFERENCE Eingabekomponente mit dem name <FS_REFERENCE name> das Medium mit der UID <mediaUID> zu setzen. Die Eingabekomponente ist sprachunabhängig, sonst müsste ich mit aus dem formData die sprachabhängige Variante holen, statt dort einfach "null" zu verwenden.

Und ja, das Beispiel ist unbrauchbar 😞
Sorry, das hatte ich mir vor dem Antworten nicht angesehen.

Ich hoffe, dass das Beispiel weiterhilft.

Viele Grüße
Holger

0 Kudos
Juncus
Returning Observer

Hallo Holger,
danke für deine Antwort.

Mit der ging es deutlich besser.
Ich habe zwar keine Medien sondern Referenzen auf PageRefs, aber ich denke das Verhalten ist ähnlich.
Ich habe jetzt eine Lösung gefunden, die zumindest die Reference wie gewünscht tauscht.
Ich gehe über TargetReference. 

 

 

 

 

 

 

StoreElementAgent storeElementAgent = context.requestSpecialist(StoreElementAgent.TYPE);
 GCAPage gcanewpagests = (GCAPage) storeElementAgent.loadStoreElement(gcaPageSTSuid, GCAPage.UID_TYPE, false);
                		if (gcanewpagests instanceof GCAPage) {
                		
                		
                		
                		
                		
                			// ### Formdata der GCAPAge holen
				FormData formdatagcanewpage = gcanewpagests.getFormData();


				
				try {
	         			gcanewpagests.setLock(true);
		         		try {

						TargetReference targetReferenceTmp = (TargetReference) formdatagcanewpage.get(null, "ps_speciallink").get();
targetReferenceTmp.set(pageRefVariable);
			 	 		
						


			 			gcanewpagests.setFormData(formdatagcanewpage);
					         gcanewpagests.save();
					         
					         
		         		}
		         		catch (Exception e) {
			                    // catch handling
			                   
			                 } finally {
			                     gcanewpagests.setLock(false);
			                 }
		         	} catch (LockException e) {
		         		 // catch handling
				}


}

 

 

 

Hoffe diese Lösung geht auch?!

Viele Grüße v.
Ralf

 

0 Kudos
mbergmann
Crownpeak employee

Hallo Ralf,

im Unterschied zu Holgers Vorschlag „manipulierst“ du die vorhandene TargetReference anstatt eine neue Instanz zu erzeugen. Ich meine mich daran zu erinnern, dass das so nicht immer funktioniert, weiß aber nicht mehr was da der Hintergrund oder das konkrete Problem war…

Von daher würde ich „aus dem Bauch heraus“ eher die Nutzung von TargetReferences.newInstance(…) empfehlen. So groß ist der Unterschied ja nicht.

Viele Grüße
Michael

0 Kudos
Juncus
Returning Observer

Hallo Michael,

danke für deinen Tip.
Dann bau ich es mal um.

Viele Grüße v.
Ralf

0 Kudos
Juncus
Returning Observer

Hallo Michael,

also irgendwie stehe ich auf dem Schlauch.
Jetzt bin ich wieder bei der selben Problematik vom Anfang.
Wenn ich über den von dir vorgeschlagenen Weg gehe müsste ich ja folgendes machen:

 

 

 

 

 

 

 

 

 

StoreElementAgent storeElementAgent = context.requestSpecialist(StoreElementAgent.TYPE);
 GCAPage gcanewpagests = (GCAPage) storeElementAgent.loadStoreElement(gcaPageSTSuid, GCAPage.UID_TYPE, false);
                		if (gcanewpagests instanceof GCAPage) {
                		
                		
                		
                		
                		
                			// ### Formdata der GCAPAge holen
				FormData formdatagcanewpage = gcanewpagests.getFormData();


				
				try {
	         			gcanewpagests.setLock(true);
		         		try {

						

TargetReference targetReferenceNew = TargetReferences.newInstance(null, pageRefTmp, "");
// ### Diese müsste ich ja dann einer Klasse vom Typ ReferenceEditorValue mit set zuweisen? Oder? An die komme ich aber nicht ran. Abgesehen, dass die Methode set() auf die Klasse EditorValue deprecated ist, ist mir nicht klar wie ich aus dem Aufruf formdatagcanewpage.get(null, "ps_speciallink") eine Klasse erhalte die korrekt per set und einer neuen Istance von TargetReference gefüllt werden kann.

?? = formdatagcanewpage.get(null, "ps_speciallink");
// Liefert die Klasse : de.espirit.firstspirit.store.access.DataWrappingFormData$EditorValueWrappingFormField

??.set(targetReferenceNew);
			 	 		
						


			 			gcanewpagests.setFormData(formdatagcanewpage);
					         gcanewpagests.save();
					         
					         
		         		}
		         		catch (Exception e) {
			                    // catch handling
			                   
			                 } finally {
			                     gcanewpagests.setLock(false);
			                 }
		         	} catch (LockException e) {
		         		 // catch handling
				}


}

 

 

 

 

Das klappt auch in Beanshell bei der Ausführung.

In meinem Java-Editor allerdings kann er die Zuweisung nicht machen. Da sagt er die Klassen passen nicht zusammen und wenn ich davon ausgehe, dass Beanshell über die Klasse EditorValue geht verwende ich ja eine deprecated Funktion mit set() auf ReferenceEditorValue? Oder bezieht sich das 'Set()' hier auf eine andere Klasse?

 

 

 

 

0 Kudos
mbergmann
Crownpeak employee

Hallo Ralf,

du kannst die TargetReference direkt in das Formfield.set(...) werfen. 

Also 

formdatagcanewpage.get(null, "ps_speciallink“).set(targetReferenceNew);

Relevant ist hier nicht das ReferenceEditorValue (das ist quasi nur die "Kapsel" bzw. ein Tagging interface). Das (komplette) Beispiel in der Doku beruht hier tatsächlich auch noch auf dem "alten" Weg, über die "Editoren" zu gehen. Ich glaube aber, es ging Holger hier lediglich um den Weg (bzw. die eine Zeile), wie man sich eine TargetReference-Instanz erzeugt.

Allgemein (kleiner Exkurs zum Thema "Datentypen bei Eingabekomponenten")

Man kann in ein FormField (genau das bekommst du ja, wenn du xyz.getFormData().get(lang, name) aufrufst) immer mit .set(...) den Typ rein werfen, der im ODFS bei der entsprechenden Eingabekomponente (hier: FS_REFERENCE) oben in der grauen Box bei "zu den Methoden" steht. 

PrtScr capture_49.png

Das ist sozusagen der "Eingebekomponenten-Inhalts-Datentyp". In einigen Fällen müssen dann auch noch weitere Voraussetzungen erfüllt sein (der Inhalt der Daten muss insbesondere "zur Konfiguration der Eingabekomponente passen" - man kann also z.B. in eine INPUT_COMBOBOX, die auf Datensätzen basiert keine Option werfen, die auf festen Werten basiert.

Es gibt dann noch einige "Spezialfälle", wo man sogar noch andere Typen benutzen kann, die dann automatisch passend "umgewandelt" werden. Zwar nicht im Fall einer FS_REFERENCE, aber z.B. bei den sog. "Option-basierten" EKs (INPUT_COMBOBOX, INPUT_LIST, INPUT_CHECKBOX, INPUT_RADIOBUTTON). Dort muss man nicht zwingend eine Option benutzen (auch weil es da keinen "schönen" Weg gibt, die zu erzeugen), sondern kann den Typ nutzen, auf dem wiederum die "Option" basieren würde. Das hängt dann vom benutzten INCLUDE_TYPE ab. Ist der z.B. "database", darf man auch ein Dataset oder eine Entity benutzen (bzw. bei den mehrwertigen dann ein Set<Dataset> oder Set<Entity>). 

Das ist übrigens auch der Grund, warum in der API zum FormField-Interface (das eben genau mit dem "Inhalts-Datentyp" (T) typisiert ist), zwar beim .get() ein T zurück geliefert wird (in deinem Fall eine TargetReference), die .set(...)-Methode aber nicht auf einem T "besteht" sondern ein Object bekommen kann.

Ich hoffe, das macht es etwas klarer.

Viele Grüße

Michael

 

 

 

0 Kudos
Juncus
Returning Observer

Hallo Michael,

danke für deine ausführliche Erklärung.
Jetzt ist es mir klar. Perfekt.

Hier dann also die Lösung, für alle die es interessiert, die funktioniert:

 

 

StoreElementAgent storeElementAgent = context.requestSpecialist(StoreElementAgent.TYPE);
 GCAPage gcanewpagests = (GCAPage) storeElementAgent.loadStoreElement(gcaPageSTSuid, GCAPage.UID_TYPE, false);
                		if (gcanewpagests instanceof GCAPage) {
                		
                		
                		
                		
                		
                			// ### Formdata der GCAPAge holen
				FormData formdatagcanewpage = gcanewpagests.getFormData();


				
				try {
	         			gcanewpagests.setLock(true);
		         		try {

						

TargetReference targetReferenceNew = TargetReferences.newInstance(null, pageRefTmp, "");
formdatagcanewpage.get(null, "ps_speciallink").set(targetReferenceNew);
			 			gcanewpagests.setFormData(formdatagcanewpage);
					         gcanewpagests.save();
					         
					         
		         		}
		         		catch (Exception e) {
			                    // catch handling
			                   
			                 } finally {
			                     gcanewpagests.setLock(false);
			                 }
		         	} catch (LockException e) {
		         		 // catch handling
				}


}

 

 

0 Kudos