Search the FirstSpirit Knowledge Base
Hallo,
Wir speichern für ein Element in einer Datenquelle über ein Eingabeformular Checkbox-Werte. Dieses Eingabeelement ist über eine CMS_INPUT_CHECKBOX, die 20 Werte aus einer anderen Datenquelle erhält, realisiert:
<CMS_INPUT_CHECKBOX name="cs_countrylist" gridWidth="3" hFill="yes" useLanguages="no">
<CMS_INCLUDE_OPTIONS type="database">
<LABELS>
<LABEL lang="*">#item.name</LABEL>
</LABELS>
<TABLE>xxx.cs_country</TABLE>
</CMS_INCLUDE_OPTIONS>
<LANGINFOS>
<LANGINFO lang="*" label="xxx"/>
</LANGINFOS>
</CMS_INPUT_CHECKBOX>
Der Anwender sieht im FS-Client also 20 Checkboxen, die er an- bzw. abhaken kann. Neben der Initialbefüllung möchten wir aus Convenience-Gründen nun per Script über das Kontextmenü eine Funktion anbieten, um für einen Datenquelleneintrag alle Checkboxen an- bzw. alle abzuhaken. In der Developer-Doku finde ich zwar ein API-Beispiel (CheckboxEditorValueExample), dies bringt mich auf Script-Ebene leider nicht weiter, da ich nicht weiß, wie ich über das Script an das Editor-Objekt gelange. Wahrscheinlich gibt es aber auch eine einfache Möglichkeit, per Script alle Häkchen zu setzen bzw. wegzunehmen, oder?
Vielen Dank im Voraus und viele Grüße aus Hamburg
Reza Nazarian
Puh, so hat es geklappt:
// Retrieve all available countries from the corresponding data source and construct a HashSet of it.
UserService userService = context.getUserService();
ContentStoreRoot contentStore = (ContentStoreRoot) userService.getStore(Store.Type.CONTENTSTORE, false);
Content2 myDataSource = contentStore.getContent2ByName("country");
data = myDataSource.getData();
Set countrySet = new HashSet();
for (int i = 0; i < data.size(); i++) {
String country = data.get(i).getValue("fs_id").toString();
countrySet.add(country);
}
// Lock the selected element and check all available countries using the HashSet.
session = myDataSource.getSession();
storeElement = context.getStoreElement();
row = context.getSelectedRow();
dataSet = storeElement.getDataset(row);
currentEntity = dataSet.getEntity();
storeElement.lock(currentEntity);
storeElement.setLock(true, false);
formData = dataSet.getFormData();
formData.get(null, "cs_countrylist").set(countrySet);
dataSet.setFormData(formData);
// Save and unlock the element, commit the changes.
storeElement.save();
storeElement.unlock(currentEntity);
storeElement.setLock(false, false);
session.commit();
"Leider" nur über das Kontextmenü. Über einen FS-BUTTON wäre es noch schöner, da habe ich aber leider keinen Weg gefunden.
Über ein Kontextemenü-Skript wird das nicht funktionieren (zumindest nicht in 4.2).
Du willst ja nicht (nur) die Werte modifizieren, sondern die Anzeige in der GUI (und zwar nur, wenn das Formular im Bearbeitungszustand ist).
Das funktioniert über FS_BUTTON, was für den Redakteur sogar komfortabler ist, weil dadurch eine Schaltfläche direkt im Formular an der Komponente eingeblendet werden kann.
Zu dem Thema findest du einiges hier in der Community.
Okay, danke. Ich werde dann hier mal weiterschauen.
Aber auch über den FS_BUTTON wird doch ein Script aufgerufen, daher muss ich die gleiche Frage nochmals stellen. 😉
Wie gesagt, dazu gibt es schon Infos hier in der Community. Und auch eine Doku: http://www.e-spirit.com/odfs42/de/vorlagenentwicklung/formular/fs/fs_button/button.html
Community-Diskussion die zu dem Thema passen könnte: Formular nach Klick auf FS_BUTTON aktualisieren
Das Suchfeld für die Community ist übrigens oben rechts
Ah! Danke! Aber da oben übersieht man es ja so leicht!!
So, mit den Beiträgen aus dem Forum und dem folgenden Code hätte ich eigentlich gedacht, dass es funktioniert. Das tut es aber leider nicht. Wenn ich ein leeres Hashset über checkbox.set(countrySet) setze, so werden alle Werte deselektiert. Dies deutet schon mal darauf, dass es grundsätzlich zu funktionieren scheint. Wenn ich aber das Hashset mit Werten der verfügbaren Checkboxen fülle, so tut sich nach dem set() leider nichts.
FS_BUTTON:
<FS_BUTTON
name="cs_select_country_button"
allowEmpty="yes"
hFill="yes"
noBreak="no"
onClick="script:select_all_countries"
style="firstspirit"
useLanguages="no">
<LANGINFOS>
<LANGINFO lang="*" label="Select all countries"/>
</LANGINFOS>
<PARAMS>
<PARAM name="checkbox">#field.cs_countrylist</PARAM>
</PARAMS>
</FS_BUTTON>
Script:
//!Beanshell
if (null != element) {
entity = element.getEntity();
countrySet = new HashSet();
countrySet.add("1");
countrySet.add("0");
checkbox.set(countrySet);
}
Hallo Reza,
Folgendes Skript könnte weiterhelfen um alle Werte einer Checkbox zu selektieren:
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import de.espirit.firstspirit.access.Connection;
import de.espirit.firstspirit.access.ConnectionManager;
import de.espirit.firstspirit.access.UserService;
import de.espirit.firstspirit.access.editor.value.Option;
import de.espirit.firstspirit.access.project.Project;
import de.espirit.firstspirit.access.store.ElementDeletedException;
import de.espirit.firstspirit.access.store.LockException;
import de.espirit.firstspirit.access.store.Store;
import de.espirit.firstspirit.access.store.IDProvider.UidType;
import de.espirit.firstspirit.access.store.contentstore.Content2;
import de.espirit.firstspirit.access.store.contentstore.ContentStoreRoot;
import de.espirit.firstspirit.access.store.pagestore.Body;
import de.espirit.firstspirit.access.store.pagestore.Page;
import de.espirit.firstspirit.access.store.pagestore.PageStoreRoot;
import de.espirit.firstspirit.access.store.pagestore.Section;
import de.espirit.firstspirit.forms.FormData;
import de.espirit.firstspirit.forms.FormField;
import de.espirit.or.schema.Entity;
String DATASOURCE = "pressreleases";
String SECTIONNAME="textbildhomepageteaser";
String CHECKBOXNAME = "cs_countryList";
String PAGE="mithras_home";
UserService us2 = context.getUserService();
PageStoreRoot pageStore = (PageStoreRoot) us2.getStore(
Store.Type.PAGESTORE, false);
ContentStoreRoot contentStore = (ContentStoreRoot) us2.getStore(
Store.Type.CONTENTSTORE, false);
Content2 myDataSource = contentStore.getContent2ByName(DATASOURCE);
data = myDataSource.getData();
opt = new HashSet();
for (int i = 0; i < data.size(); i++) {
opt.add(data.get(i).getValue("fs_id").toString());
}
Page page = (Page) pageStore.getStoreElement(PAGE, UidType.PAGESTORE);
Section mySec=(Section) page.getChildByName(Section.class, SECTIONNAME);
try {
page.setLock(true);
FormData d = mySec.getFormData();
FormField f = d.get(us2.getProject().getMasterLanguage(), CHECKBOXNAME);
eval = f.get();
f.set(opt);
mySec.setFormData(d);
mySec.save();
page.release();
page.setLock(false);
} catch (LockException e) {
e.printStackTrace();
}
und folgendes um alle Werte einer Checkbox zu deselektieren:
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import de.espirit.firstspirit.access.Connection;
import de.espirit.firstspirit.access.ConnectionManager;
import de.espirit.firstspirit.access.UserService;
import de.espirit.firstspirit.access.editor.value.Option;
import de.espirit.firstspirit.access.project.Project;
import de.espirit.firstspirit.access.store.ElementDeletedException;
import de.espirit.firstspirit.access.store.LockException;
import de.espirit.firstspirit.access.store.Store;
import de.espirit.firstspirit.access.store.IDProvider.UidType;
import de.espirit.firstspirit.access.store.contentstore.Content2;
import de.espirit.firstspirit.access.store.contentstore.ContentStoreRoot;
import de.espirit.firstspirit.access.store.pagestore.Body;
import de.espirit.firstspirit.access.store.pagestore.Page;
import de.espirit.firstspirit.access.store.pagestore.PageStoreRoot;
import de.espirit.firstspirit.access.store.pagestore.Section;
import de.espirit.firstspirit.forms.FormData;
import de.espirit.firstspirit.forms.FormField;
import de.espirit.or.schema.Entity;
String CHECKBOXNAME = "cs_countryList";
String SECTIONNAME="textbildhomepageteaser";
String PAGE="mithras_home";
UserService us2 = context.getUserService();
PageStoreRoot pageStore = (PageStoreRoot) us2.getStore(
Store.Type.PAGESTORE, false);
Page page = (Page) pageStore.getStoreElement(PAGE, UidType.PAGESTORE);
Section mySec=(Section) page.getChildByName(Section.class, SECTIONNAME);
try {
page.setLock(true);
FormData d = mySec.getFormData();
FormField f = d.get(us2.getProject().getMasterLanguage(), CHECKBOXNAME);
eval = f.get();
f.set(null);
mySec.setFormData(d);
mySec.save();
page.release();
page.setLock(false);
} catch (LockException e) {
e.printStackTrace();
}
Nach Refresh der Seite sollten je nach aufgerufenem Skript die Items alle selektiert oder deselektiert sein. Die Parameter PAGE, DATASOURCE, SECTIONNAME und CHECKBOXNAME müssten ggfls. angepasst werden.
Anmerkung: Die Methode StoreElement.getChildByName(...) ist deprecated.
Freundliche Grüße
Ismail
Eine einfache Deselektion aller Werte über einen FS_Button ließe sich auch so implementieren:
Template:
<FS_BUTTON
name="button_uncheck"
allowEmpty="yes"
hFill="yes"
noBreak="no"
onClick="script:uncheckall"
useLanguages="no">
<LANGINFOS>
<LANGINFO lang="*" label="Keins auswählen" description="TEXT"/>
</LANGINFOS>
<PARAMS>
<PARAM name="uncheck">#field.cs_countryList</PARAM>
</PARAMS>
</FS_BUTTON>
Skript:
uncheck.set(null);
Hallo Ismail,
Vielen Dank schon mal für die Antworten. Sorry, dass es sich so lange hinzieht.
Das Deselektieren habe ich bereits vor einiger Zeit mit Hilfe eine s FS-BUTTON umgesetzt, genau wie du vorgeschlagen hast. Das war einfach! 🙂 ich habe für das Selektieren zuerst auch den Weg über einen FS-BUTTON gewählt, jedoch hat sich das Formular respektive die Daten nicht verändert (siehe Posting #5).
Beim Selektieren aller Checkboxen verwenden wir eine Datenquelle und haben mit folgendem Code (an deinen Post anlehnend) angefangen:
e = context.getStoreElement();
row = context.getSelectedRow();
dataSet = e.getDataset(row);
currentEntity = dataSet.getEntity();
formData = dataSet.getFormData();
ContentStoreRoot contentStore = (ContentStoreRoot) us2.getStore(Store.Type.CONTENTSTORE, false);
Content2 myDataSource = contentStore.getContent2ByName("country");
data = myDataSource.getData();
opt = new HashSet();
for (int i = 0; i < data.size(); i++) {
opt.add(data.get(i).getValue("fs_id").toString());
}
Bis hierhin funktioniert alles sehr gut. Wenn ich das HashSet dann allerdings wieder der FormData zuweise (formData.set(opt);), so kommt die Exception, dass die Methode "set" für dieses FormData nicht verfügbar ist. Bei einem Eintrag aus der Datenquelle ist dies wahrscheinlich auch der falsche Weg.
:smileyconfused:
Puh, so hat es geklappt:
// Retrieve all available countries from the corresponding data source and construct a HashSet of it.
UserService userService = context.getUserService();
ContentStoreRoot contentStore = (ContentStoreRoot) userService.getStore(Store.Type.CONTENTSTORE, false);
Content2 myDataSource = contentStore.getContent2ByName("country");
data = myDataSource.getData();
Set countrySet = new HashSet();
for (int i = 0; i < data.size(); i++) {
String country = data.get(i).getValue("fs_id").toString();
countrySet.add(country);
}
// Lock the selected element and check all available countries using the HashSet.
session = myDataSource.getSession();
storeElement = context.getStoreElement();
row = context.getSelectedRow();
dataSet = storeElement.getDataset(row);
currentEntity = dataSet.getEntity();
storeElement.lock(currentEntity);
storeElement.setLock(true, false);
formData = dataSet.getFormData();
formData.get(null, "cs_countrylist").set(countrySet);
dataSet.setFormData(formData);
// Save and unlock the element, commit the changes.
storeElement.save();
storeElement.unlock(currentEntity);
storeElement.setLock(false, false);
session.commit();
"Leider" nur über das Kontextmenü. Über einen FS-BUTTON wäre es noch schöner, da habe ich aber leider keinen Weg gefunden.