Neuer Tab im ItemSearchWidget: Zeigt eine flache Liste aller Items (eines bestimmten Typs) an. Erlaubt das Filtern der Liste

nach Name/Titel. Außerdem Veränderung Erscheinungsbild: Das Feld für die ID des ausgewählten Items ist jetzt nicht mehr 
sichtbar, statt dessen wird ein Text-Feld anzeigt in dem der Titel des ausgewählten Items angezeigt wird. Was noch fehlt ist 
Übernahme eines in diesem Feld eingegebenen Strings in das ItemSearch-Widget.



git-svn-id: https://svn.libreccm.org/ccm/trunk@1700 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2012-06-08 16:56:26 +00:00
parent b1cf78e059
commit fa56786e53
8 changed files with 320 additions and 33 deletions

View File

@ -1092,3 +1092,9 @@ cms.ui.item.lifecycle.publish_locked.update=Update
cms.ui.lifecycle.publish.error=An error occured while publishing this item.The system administrator has been notified about this problem. This item will stay locked until the lock is removed by the system administrator manually.
cms.ui.delete_confirmation=Permanently delete this item?
cms.ui.lifecycle.details.last_published=Item last (re-)published
cms.ui.item_search.flat.filter=Filter list
cms.ui.item_search.flat.no_items=No items matching the filter found
cms.ui.item_search.flat.title=Title
cms.ui.item_search.flat.place=Place
cms.ui.item_search.flat.type=Type
cms.ui.item_search.flatBrowse=Select item

View File

@ -1083,3 +1083,9 @@ cms.ui.item.lifecycle.publish_locked.update=Aktualisieren
cms.ui.lifecycle.publish.error=W\u00e4hrend des Publizierens ist ein Fehler aufgetreten. Der System-Administrator wurde per \u00fcber das Problem informiert. Dieses Item bleibt besperrt, bis der Administrator die Sperre manuell entfernt.
cms.ui.delete_confirmation=Wollen Sie dieses Content-Item l\u00f6schen?
cms.ui.lifecycle.details.last_published=Das Item wurde zuletzt republiziert am
cms.ui.item_search.flat.filter=Liste filtern
cms.ui.item_search.flat.no_items=Kein Item entspricht dem Filter
cms.ui.item_search.flat.title=Titel
cms.ui.item_search.flat.place=Ort
cms.ui.item_search.flat.type=Typ
cms.ui.item_search.flatBrowse=Item ausw\u00e4hlen

View File

@ -31,3 +31,9 @@ cms.ui.item.lifecycle.publish_locked.update=
cms.ui.lifecycle.publish.error=
cms.ui.delete_confirmation=
cms.ui.lifecycle.details.last_published=
cms.ui.item_search.flat.filter=
cms.ui.item_search.flat.no_items=
cms.ui.item_search.flat.title=Title
cms.ui.item_search.flat.place=Place
cms.ui.item_search.flat.type=Type
cms.ui.item_search.flatBrowse=Select item

View File

@ -562,3 +562,9 @@ cms.ui.item.lifecycle.publish_locked.update=
cms.ui.lifecycle.publish.error=
cms.ui.delete_confirmation=
cms.ui.lifecycle.details.last_published=
cms.ui.item_search.flat.filter=
cms.ui.item_search.flat.no_items=
cms.ui.item_search.flat.title=Title
cms.ui.item_search.flat.place=Place
cms.ui.item_search.flat.type=Type
cms.ui.item_search.flatBrowse=Select item

View File

@ -0,0 +1,239 @@
package com.arsdigita.cms.ui;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Link;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableColumnModel;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.cms.ContentBundle;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentPage;
import com.arsdigita.cms.ContentType;
import com.arsdigita.cms.Folder;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.persistence.DataCollection;
import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.Session;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.util.LockableImpl;
import java.math.BigDecimal;
/**
*
* @author Jens Pelzetter <jens@jp-digital.de>
* @version $Id$
*/
public class ItemSearchFlatBrowsePane extends Form implements FormInitListener, FormProcessListener {
private static final String QUERY_PARAM = "query";
public static final String WIDGET_PARAM = "widget";
public static final String SEARCHWIDGET_PARAM = "searchWidget";
private final Table resultsTable;
private final StringParameter queryParam;
public ItemSearchFlatBrowsePane(final String name) {
super(name);
queryParam = new StringParameter(QUERY_PARAM);
final BoxPanel boxPanel = new BoxPanel(BoxPanel.HORIZONTAL);
boxPanel.add(new Label(GlobalizationUtil.globalize("cms.ui.item_search.flat.filter")));
final TextField filter = new TextField(new StringParameter(QUERY_PARAM));
boxPanel.add(filter);
add(boxPanel);
resultsTable = new ResultsTable();
add(resultsTable);
addInitListener(this);
addProcessListener(this);
}
@Override
public void register(final Page page) {
super.register(page);
page.addComponentStateParam(this, queryParam);
}
public void init(final FormSectionEvent fse) throws FormProcessException {
}
public void process(final FormSectionEvent fse) throws FormProcessException {
final FormData data = fse.getFormData();
final PageState state = fse.getPageState();
state.setValue(queryParam, data.get(QUERY_PARAM));
}
private class ResultsTable extends Table {
private static final String TABLE_COL_TITLE = "title";
private static final String TABLE_COL_PLACE = "place";
private static final String TABLE_COL_TYPE = "type";
public ResultsTable() {
super();
setEmptyView(new Label(GlobalizationUtil.globalize("cms.ui.item_search.flat.no_items")));
final TableColumnModel columnModel = getColumnModel();
columnModel.add(new TableColumn(0,
GlobalizationUtil.globalize("cms.ui.item_search.flat.title").localize(),
TABLE_COL_TITLE));
columnModel.add(new TableColumn(1,
GlobalizationUtil.globalize("cms.ui.item_search.flat.place").localize(),
TABLE_COL_PLACE));
columnModel.add(new TableColumn(2,
GlobalizationUtil.globalize("cms.ui.item_search.flat.type").localize(),
TABLE_COL_TYPE));
setModelBuilder(new ResultsTableModelBuilder());
columnModel.get(0).setCellRenderer(new TitleCellRenderer());
}
}
private class ResultsTableModelBuilder extends LockableImpl implements TableModelBuilder {
public TableModel makeModel(final Table table, final PageState state) {
return new ResultsTableModel(table, state);
}
}
private class ResultsTableModel implements TableModel {
private final Table table;
private final DataCollection collection;
private ContentItem currentItem;
public ResultsTableModel(final Table table, final PageState state) {
this.table = table;
final Session session = SessionManager.getSession();
final BigDecimal typeId = (BigDecimal) state.getValue(new BigDecimalParameter(ItemSearch.SINGLE_TYPE_PARAM));
if (typeId == null) {
collection = session.retrieve(ContentPage.BASE_DATA_OBJECT_TYPE);
} else {
final ContentType type = new ContentType(typeId);
collection = session.retrieve(type.getClassName());
}
final String query = (String) state.getValue(queryParam);
if ((query != null) && !query.isEmpty()) {
collection.addFilter(String.format("(lower(%s) like lower('%%%s%%')) or (lower(%s) like lower('%%%s%%'))",
ContentItem.NAME, query,
ContentPage.TITLE, query));
}
}
public int getColumnCount() {
return table.getColumnModel().size();
}
public boolean nextRow() {
boolean ret;
if ((collection != null) && collection.next()) {
currentItem = (ContentItem) DomainObjectFactory.newInstance(collection.getDataObject());
ret = true;
} else {
ret = false;
}
return ret;
}
public Object getElementAt(final int columnIndex) {
switch (columnIndex) {
case 0:
if (currentItem instanceof ContentPage) {
return ((ContentPage) currentItem).getTitle();
} else {
return currentItem.getName();
}
case 1:
return getItemPath(currentItem);
case 2:
return currentItem.getContentType().getLabel();
default:
return null;
}
}
private String getItemPath(final ContentItem item) {
final StringBuilder path = new StringBuilder(item.getName());
ContentItem current = item;
while (current.getParent() != null) {
if (current.getParent() instanceof ContentBundle) {
current = (ContentBundle) current.getParent();
} else if (current.getParent() instanceof Folder) {
current = (Folder) current.getParent();
if (!current.getName().equals("/")) {
path.insert(0, '/');
path.insert(0, current.getName());
}
}
}
path.insert(0, ":/");
path.insert(0, item.getContentSection().getName());
return path.toString();
}
public Object getKeyAt(final int columnIndex) {
return currentItem.getID();
}
}
private class TitleCellRenderer extends LockableImpl implements TableCellRenderer {
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
final Link link = new Link(value.toString(), "");
final String widget = (String) state.getValue(new StringParameter(WIDGET_PARAM));
final String searchWidget = (String) state.getValue(new StringParameter(SEARCHWIDGET_PARAM));
final ContentPage page = new ContentPage((BigDecimal) key);
link.setOnClick(String.format(
"window.opener.document.%s.value=\"%s\";window.opener.document.%s.value=\"%s\";self.close();return false;",
widget,
key.toString(),
searchWidget,
page.getTitle()));
return link;
}
}
}

View File

@ -54,6 +54,7 @@ public class ItemSearchPage extends CMSPage {
private final static String XSL_CLASS = "CMS Admin";
private TabbedPane m_tabbedPane;
private ItemSearchFlatBrowsePane m_flatBrowse;
private ItemSearchBrowsePane m_browse;
private ItemSearchPopup m_search;
//private ItemSearchCreateItemPane m_create;
@ -72,11 +73,13 @@ public class ItemSearchPage extends CMSPage {
addGlobalStateParam(new BigDecimalParameter(ItemSearch.SINGLE_TYPE_PARAM));
addGlobalStateParam(new StringParameter(ItemSearchPopup.WIDGET_PARAM));
addGlobalStateParam(new StringParameter("searchWidget"));
m_sectionId = new BigDecimalParameter(CONTENT_SECTION);
addGlobalStateParam(m_sectionId);
m_browse = getBrowsePane();
m_flatBrowse = getFlatBrowsePane();
m_search = getSearchPane();
// m_create = getCreatePane();
@ -98,6 +101,14 @@ public class ItemSearchPage extends CMSPage {
return m_browse;
}
protected ItemSearchFlatBrowsePane getFlatBrowsePane() {
if (m_flatBrowse == null) {
m_flatBrowse = new ItemSearchFlatBrowsePane("flatBrowse");
}
return m_flatBrowse;
}
/**
* Creates, and then caches, the Creation pane. Overriding this
* method to return null will prevent this tab from appearing.
@ -135,6 +146,7 @@ public class ItemSearchPage extends CMSPage {
TabbedPane pane = new TabbedPane();
pane.setClassAttr(XSL_CLASS);
addToPane(pane, "flatBrowse", getFlatBrowsePane());
addToPane(pane, "browse", getBrowsePane());
addToPane(pane, "search", getSearchPane());
// addToPane(pane, "create", getCreatePane());

View File

@ -38,7 +38,6 @@ import java.math.BigDecimal;
*
* @author <a href="mailto:sseago@redhat.com">Scott Seago</a>
*/
public class ItemSearchParameter extends StringParameter {
private ContentType m_contentType;
@ -50,10 +49,9 @@ public class ItemSearchParameter extends StringParameter {
* @param name the name of the request parameter from which item
*/
public ItemSearchParameter(String name) {
this(name,null);
this(name, null);
}
/**
* Create a new item search parameter corresponding to a request parameter
* with the given name.
@ -62,10 +60,10 @@ public class ItemSearchParameter extends StringParameter {
* @param contentType If not null, search will be limited to the
* specified content type
*/
public ItemSearchParameter(String name,
ContentType contentType) {
public ItemSearchParameter(String name,
ContentType contentType) {
super(name);
m_contentType = contentType;
m_contentType = contentType;
}
/**
@ -80,22 +78,27 @@ public class ItemSearchParameter extends StringParameter {
*/
@Override
public Object transformValue(HttpServletRequest request)
throws IllegalArgumentException {
throws IllegalArgumentException {
String itemStr = Globalization.decodeParameter(request, getName());
return unmarshal(itemStr);
}
@Override
public Object unmarshal(String encoded)
throws IllegalArgumentException {
throws IllegalArgumentException {
// As stated above, if we get an invalid address just return null.
if (encoded == null || encoded.length() < 1) {
return null;
}
String idStr = encoded.substring(0,encoded.indexOf(' '));
}
String idStr;
if (encoded.indexOf(' ') < 0) {
idStr = encoded;
} else {
idStr = encoded.substring(0, encoded.indexOf(' '));
}
if (idStr == null || idStr.length() < 1) {
return null;
}
@ -105,19 +108,15 @@ public class ItemSearchParameter extends StringParameter {
}
ContentItem contentItem;
try {
contentItem = (ContentItem) DomainObjectFactory.newInstance
(new OID(ContentItem.BASE_DATA_OBJECT_TYPE, itemID));
contentItem = (ContentItem) DomainObjectFactory.newInstance(new OID(ContentItem.BASE_DATA_OBJECT_TYPE,
itemID));
} catch (DataObjectNotFoundException e) {
throw new IllegalArgumentException
(encoded +
" is not a valid contentItem." +
e.getMessage());
throw new IllegalArgumentException(encoded + " is not a valid contentItem." + e.getMessage());
}
if (m_contentType != null && !contentItem.isContentType(m_contentType)) {
return null;
}
if (m_contentType != null &&
!contentItem.isContentType(m_contentType)) {
return null;
}
return contentItem;
}
@ -126,11 +125,11 @@ public class ItemSearchParameter extends StringParameter {
if (value == null) {
return null;
} else {
ContentPage theItem = (ContentPage) value;
return (theItem.getID().toString() + " (" + theItem.getTitle() + ")");
ContentPage theItem = (ContentPage) value;
return (theItem.getID().toString() + " (" + theItem.getTitle() + ")");
}
}
@Override
public Class getValueClass() {
return ContentPage.class;

View File

@ -30,10 +30,12 @@ import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormSubmissionListener;
import com.arsdigita.bebop.event.PrintEvent;
import com.arsdigita.bebop.event.PrintListener;
import com.arsdigita.bebop.form.Hidden;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.bebop.parameters.ParameterModel;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.bebop.util.BebopConstants;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ContentItem;
@ -55,6 +57,7 @@ public class ItemSearchWidget extends FormSection
implements BebopConstants, FormSubmissionListener, FormInitListener {
private static final Logger s_log = Logger.getLogger(ItemSearchWidget.class);
private Hidden m_selected;
private TextField m_item;
private Submit m_search;
private Submit m_clear;
@ -67,7 +70,9 @@ public class ItemSearchWidget extends FormSection
private String m_searchName;
private String m_clearName;
private ParameterModel m_model;
private ParameterModel m_searchModel;
public static final String BEBOP_ITEM_SEARCH = "bebop:itemSearch";
public static final String SEARCH = "search";
public static final boolean LIMIT_TO_CONTENT_SECTION = false;
private class ItemFragment extends TextField {
@ -77,7 +82,7 @@ public class ItemSearchWidget extends FormSection
public ItemFragment(ParameterModel parameter, ItemSearchWidget parent) {
super(parameter);
this.parent = parent;
this.setReadOnly();
//this.setReadOnly();
this.setSize(35);
}
}
@ -89,7 +94,7 @@ public class ItemSearchWidget extends FormSection
public SearchFragment(String name, ItemSearchWidget parent) {
super(name, "Search");
this.parent = parent;
this.setAttribute("onClick", "return " + parent.m_item.getName().
this.setAttribute("onClick", "return " + parent.m_selected.getName(). //+ parent.m_item.getName().
replace('.', '_') + "Popup(this.form)");
this.setAttribute("value", "Search");
}
@ -109,7 +114,7 @@ public class ItemSearchWidget extends FormSection
public ClearFragment(String name, ItemSearchWidget parent) {
super(name, "Clear");
this.parent = parent;
this.setAttribute("onClick", "this.form." + parent.m_item.getName()
this.setAttribute("onClick", "this.form." + parent.m_selected.getName() //parent.m_item.getName()
+ ".value = \"\"; return false;");
this.setAttribute("value", "Clear");
}
@ -199,9 +204,13 @@ public class ItemSearchWidget extends FormSection
} else {
typeURLFrag = null;
}
m_searchModel = new StringParameter(SEARCH);
m_contentType = contentType;
m_item = new ItemFragment(model, this);
m_selected = new Hidden(model);
//m_item = new ItemFragment(model, this);
m_item = new TextField(m_searchModel);
m_search = new SearchFragment(m_searchName, this);
m_clear = new ClearFragment(m_clearName, this);
m_jsLabel = new LabelFragment("", false, this);
@ -215,8 +224,9 @@ public class ItemSearchWidget extends FormSection
ParameterMap params = new ParameterMap();
params.setParameter("section_id",
CMS.getContext().getContentSection().getID());
params.setParameter("widget", formName + ".elements['" + m_item.
params.setParameter("widget", formName + ".elements['" + m_selected. //m_item.
getName() + "']");
params.setParameter("searchWidget", formName + ".elements['" + m_item.getName() + "']");
if (typeURLFrag != null) {
params.setParameter("single_type", typeURLFrag);
}
@ -235,10 +245,12 @@ public class ItemSearchWidget extends FormSection
t.setLabel(" <script language=javascript> "
+ " <!-- \n"
+ " function "
+ m_item.getName().replace('.', '_')
//+ m_item.getName().replace('.', '_')
+ m_selected.getName().replace('.', '_')
+ "Popup(theForm) { \n"
+ " aWindow = window.open(\"" + url
+ "\", \"search\", \"toolbar=no,width=800,height=600,status=no,scrollbars=yes,resize=yes,menubar=no\");\n return false;\n"
+ " aWindow = window.open(\"" + url + "\", "
+ "\"search\", \"toolbar=no,width=800,height=600,status=no,scrollbars=yes,resize=yes\");\n"
+ "return false;\n"
+ " } \n"
+ " --> \n"
+ " </script> ");
@ -249,6 +261,7 @@ public class ItemSearchWidget extends FormSection
FormSection searchSection = new FormSection(new BoxPanel(
BoxPanel.HORIZONTAL));
searchSection.add(m_item);
searchSection.add(m_selected);
searchSection.add(m_search);
searchSection.add(m_clear);
searchSection.add(m_jsLabel);