From: <pb...@fe...> - 2012-12-01 15:37:27
|
Author: pboy Date: 2012-12-01 15:37:17 +0000 (Sat, 01 Dec 2012) New Revision: 2334 Added: trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchFlatBrowsePane.java Modified: trunk/ccm-cms/src/com/arsdigita/cms/CMSResources.properties trunk/ccm-cms/src/com/arsdigita/cms/CMSResources_de.properties trunk/ccm-cms/src/com/arsdigita/cms/CMSResources_en_GB.properties trunk/ccm-cms/src/com/arsdigita/cms/CMSResources_fr.properties trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchPage.java trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchParameter.java trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchWidget.java Log: Added new tab in ItemSearchWidget. Displays a shallow list of all items of specific type. Enables to filter the list by name / title. Additionally usability improved: IF field is hidden now, replaced by a text field displaying the title of selected item. ToDo: Accept a string entered in that field of ItemSearchWidget. Modified: trunk/ccm-cms/src/com/arsdigita/cms/CMSResources.properties =================================================================== --- trunk/ccm-cms/src/com/arsdigita/cms/CMSResources.properties 2012-12-01 15:29:28 UTC (rev 2333) +++ trunk/ccm-cms/src/com/arsdigita/cms/CMSResources.properties 2012-12-01 15:37:17 UTC (rev 2334) @@ -1092,3 +1092,9 @@ 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 Modified: trunk/ccm-cms/src/com/arsdigita/cms/CMSResources_de.properties =================================================================== --- trunk/ccm-cms/src/com/arsdigita/cms/CMSResources_de.properties 2012-12-01 15:29:28 UTC (rev 2333) +++ trunk/ccm-cms/src/com/arsdigita/cms/CMSResources_de.properties 2012-12-01 15:37:17 UTC (rev 2334) @@ -1083,3 +1083,9 @@ 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 Modified: trunk/ccm-cms/src/com/arsdigita/cms/CMSResources_en_GB.properties =================================================================== --- trunk/ccm-cms/src/com/arsdigita/cms/CMSResources_en_GB.properties 2012-12-01 15:29:28 UTC (rev 2333) +++ trunk/ccm-cms/src/com/arsdigita/cms/CMSResources_en_GB.properties 2012-12-01 15:37:17 UTC (rev 2334) @@ -31,3 +31,9 @@ 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 Modified: trunk/ccm-cms/src/com/arsdigita/cms/CMSResources_fr.properties =================================================================== --- trunk/ccm-cms/src/com/arsdigita/cms/CMSResources_fr.properties 2012-12-01 15:29:28 UTC (rev 2333) +++ trunk/ccm-cms/src/com/arsdigita/cms/CMSResources_fr.properties 2012-12-01 15:37:17 UTC (rev 2334) @@ -562,3 +562,9 @@ 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 Added: trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchFlatBrowsePane.java =================================================================== --- trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchFlatBrowsePane.java (rev 0) +++ trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchFlatBrowsePane.java 2012-12-01 15:37:17 UTC (rev 2334) @@ -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 <je...@jp...> + * @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; + } + + + + } +} Modified: trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchPage.java =================================================================== --- trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchPage.java 2012-12-01 15:29:28 UTC (rev 2333) +++ trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchPage.java 2012-12-01 15:37:17 UTC (rev 2334) @@ -54,6 +54,7 @@ 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 @@ 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 @@ 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 @@ TabbedPane pane = new TabbedPane(); pane.setClassAttr(XSL_CLASS); + addToPane(pane, "flatBrowse", getFlatBrowsePane()); addToPane(pane, "browse", getBrowsePane()); addToPane(pane, "search", getSearchPane()); // addToPane(pane, "create", getCreatePane()); Modified: trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchParameter.java =================================================================== --- trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchParameter.java 2012-12-01 15:29:28 UTC (rev 2333) +++ trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchParameter.java 2012-12-01 15:37:17 UTC (rev 2334) @@ -38,7 +38,6 @@ * * @author <a href="mailto:ss...@re...">Scott Seago</a> */ - public class ItemSearchParameter extends StringParameter { private ContentType m_contentType; @@ -50,10 +49,9 @@ * @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 @@ * @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 @@ */ @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 @@ } 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 @@ 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; Modified: trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchWidget.java =================================================================== --- trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchWidget.java 2012-12-01 15:29:28 UTC (rev 2333) +++ trunk/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchWidget.java 2012-12-01 15:37:17 UTC (rev 2334) @@ -30,10 +30,12 @@ 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 @@ 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 @@ 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 ItemFragment(ParameterModel parameter, ItemSearchWidget parent) { super(parameter); this.parent = parent; - this.setReadOnly(); + //this.setReadOnly(); this.setSize(35); } } @@ -89,7 +94,7 @@ 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 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 @@ } 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 @@ 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 @@ 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 @@ 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); |