- The CategoryWidget/TermWidget now highlights the ancestors of selected categories to make easier to find selected categories

- Some formatting of XSL code in Foundry


git-svn-id: https://svn.libreccm.org/ccm/trunk@3281 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2015-03-13 12:29:33 +00:00
parent 05580fc24a
commit 1e3cb64455
23 changed files with 360 additions and 219 deletions

View File

@ -15,7 +15,7 @@
name="LibreCMS-SL"
prettyName="LibreCMS (Slimline Bundle)"
version="2.3.0"
release="trunk-r2915"
release="trunk-r3276"
webxml="libre-web.xml"
webapp="ROOT"
xsi:schemaLocation="http://ccm.redhat.com/ccm-project file:tools-ng/common/xsd/project.xsd">

View File

@ -42,7 +42,7 @@ import java.util.Iterator;
import java.math.BigDecimal;
public class CategoryWidget extends Widget {
private BigDecimalParameter m_root;
private StringParameter m_mode;
@ -50,7 +50,7 @@ public class CategoryWidget extends Widget {
BigDecimalParameter root,
StringParameter mode) {
super(new ArrayParameter(new BigDecimalParameter(name)));
m_root = root;
m_mode = mode;
}
@ -59,54 +59,55 @@ public class CategoryWidget extends Widget {
protected String getType() {
return "category";
}
@Override
public boolean isCompound() {
return false;
}
@Override
protected void generateWidget(PageState state,
protected void generateWidget(PageState state,
Element parent) {
Element widget = parent.newChildElement("cms:categoryWidget",
CMS.CMS_XML_NS);
exportAttributes(widget);
widget.addAttribute("mode", (String)state.getValue(m_mode));
widget.addAttribute("mode", (String) state.getValue(m_mode));
widget.addAttribute("name", getName());
Set ids = new HashSet();
final Set selectedCategories = new HashSet();
BigDecimal[] values = (BigDecimal[])getValue(state);
final BigDecimal[] values = (BigDecimal[]) getValue(state);
if (values != null) {
ids.addAll(Arrays.asList(values));
selectedCategories.addAll(Arrays.asList(values));
}
Category root = (Category)DomainObjectFactory.newInstance(
final Category root = (Category) DomainObjectFactory.newInstance(
new OID(Category.BASE_DATA_OBJECT_TYPE,
(BigDecimal)state.getValue(m_root))
(BigDecimal) state.getValue(m_root))
);
CategoryCollection cats = root.getDescendants();
cats.addEqualsFilter("parents.link.relationType", "child");
cats.addPath("parents.link.sortKey");
cats.addPath("parents.id");
Map children = new HashMap();
while (cats.next()) {
Category cat = cats.getCategory();
BigDecimal parentID = (BigDecimal)cats.get("parents.id");
List childList = (List)children.get(parentID);
CategoryCollection categories = root.getDescendants();
categories.addEqualsFilter("parents.link.relationType", "child");
categories.addPath("parents.link.sortKey");
categories.addPath("parents.id");
final Map children = new HashMap();
while (categories.next()) {
final Category cat = categories.getCategory();
final BigDecimal parentID = (BigDecimal) categories.get("parents.id");
List childList = (List) children.get(parentID);
if (childList == null) {
childList = new ArrayList();
children.put(parentID, childList);
}
childList.add(new CategorySortKeyPair
(cat,(BigDecimal)cats.get("parents.link.sortKey")));
childList.add(
new CategorySortKeyPair(cat, (BigDecimal) categories.get("parents.link.sortKey")));
}
generateCategory(widget, null, root, null, ids, children);
generateCategory(widget, null, root, null, selectedCategories, children);
}
public void generateCategory(Element parent,
@ -117,7 +118,7 @@ public class CategoryWidget extends Widget {
Map children) {
Element el = new Element("cms:category",
CMS.CMS_XML_NS);
el.addAttribute("id", XML.format(cat.getID()));
el.addAttribute("name", cat.getName());
el.addAttribute("description", cat.getDescription());
@ -131,30 +132,32 @@ public class CategoryWidget extends Widget {
// be used to transform xml fragments returned by ajax in the Aplaws
// extension
el.addAttribute("order", ContentSection.getConfig().getCategoryTreeOrder());
String fullname = path == null ? "/" : path + " > " + cat.getName();
el.addAttribute("fullname", fullname);
StringBuilder nodeID = new StringBuilder(parent.getAttribute("node-id"));
if (nodeID.length() > 0) {
StringBuilder nodeID = new StringBuilder(parent.getAttribute("node-id"));
if (nodeID.length() > 0) {
nodeID.append("-");
}
nodeID.append(cat.getID());
el.addAttribute("node-id", nodeID.toString());
nodeID.append(cat.getID());
el.addAttribute("node-id", nodeID.toString());
parent.addContent(el);
List c = (List)children.get(cat.getID());
List c = (List) children.get(cat.getID());
if (c != null) {
Iterator i = c.iterator();
while (i.hasNext()) {
CategorySortKeyPair pair = (CategorySortKeyPair) i.next();
Category child = pair.getCategory();
BigDecimal childSortKey = pair.getSortKey();
generateCategory(el, fullname, child,
generateCategory(el, fullname, child,
childSortKey, selected, children);
}
}
}
}
private class CategorySortKeyPair {
private Category m_category;
private BigDecimal m_sortKey;
@ -162,11 +165,15 @@ public class CategoryWidget extends Widget {
m_category = category;
m_sortKey = sortKey;
}
public Category getCategory() {
return m_category;
}
public BigDecimal getSortKey() {
return m_sortKey;
}
}
}

View File

@ -29,34 +29,32 @@ import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.kernel.ACSObject;
/**
/**
* (No description available yet).
*
*
* Usage of this class is configured in parameter c.ad.cms.category_authoring_add_form
*/
public class ItemCategoryForm extends ACSObjectCategoryForm {
private static Logger s_log = Logger.getLogger(ItemCategoryForm.class);
public ItemCategoryForm(BigDecimalParameter root, StringParameter mode, Widget widget) {
super(root, mode, widget);
s_log.debug("creating new ItemTerm Form with widget " + widget);
super(root, mode, widget);
s_log.debug("creating new ItemTerm Form with widget " + widget);
}
public ItemCategoryForm(BigDecimalParameter root, StringParameter mode) {
this(root, mode, new CategoryWidget("category", root, mode));
this(root, mode, new CategoryWidget("category", root, mode));
}
/*
* @see com.arsdigita.categorization.ui.ACSObjectCategoryForm#getObject()
*/
protected ACSObject getObject(PageState state) {
ContentItem item = CMS.getContext().getContentItem();
return item.getParent();
ContentItem item = CMS.getContext().getContentItem();
return item.getParent();
}
}

View File

@ -43,18 +43,18 @@ import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.kernel.ACSObject;
import com.arsdigita.persistence.OID;
import java.util.HashSet;
import java.util.Set;
/**
* Abstract form for assigning categories to acs_objects. The assigned
* categories are those specified by the category widget, which is
* retrieved by the concrete subclass' implementation of getCategoryWidget.
* Abstract form for assigning categories to acs_objects. The assigned categories are those
* specified by the category widget, which is retrieved by the concrete subclass' implementation of
* getCategoryWidget.
*
* The category widget may be an implementation of CategoryWidget, which
* generates a javascript tree of categories. Implementations need only
* specify an XML prefix and namespace.
* The category widget may be an implementation of CategoryWidget, which generates a javascript tree
* of categories. Implementations need only specify an XML prefix and namespace.
*
* The object that is to be assigned to the categories is specified
* by the concrete subclass' implentation of getObject
* The object that is to be assigned to the categories is specified by the concrete subclass'
* implentation of getObject
*
* @author chris.gilbert@westsussex.gov.uk
*
@ -74,7 +74,6 @@ public abstract class ACSObjectCategoryForm extends Form {
Widget categoryWidget) {
super("category", new BoxPanel(BoxPanel.VERTICAL));
m_category = categoryWidget;
m_category.addValidationListener(new NotNullValidationListener());
m_buttons = new SaveCancelSection();
@ -85,20 +84,27 @@ public abstract class ACSObjectCategoryForm extends Form {
addInitListener(new FormInitListener() {
@Override
public void init(FormSectionEvent ev)
throws FormProcessException {
public void init(FormSectionEvent ev) throws FormProcessException {
PageState state = ev.getPageState();
ACSObject object = getObject(state);
final PageState state = ev.getPageState();
final ACSObject object = getObject(state);
List ids = new ArrayList();
CategoryCollection cats = new CategorizedObject(object).getParents();
while (cats.next()) {
ids.add(cats.getCategory().getID());
final List<BigDecimal> selectedCats = new ArrayList<BigDecimal>();
final Set<BigDecimal> ancestorCats = new HashSet<BigDecimal>();
final CategoryCollection categories = new CategorizedObject(object).getParents();
while (categories.next()) {
final Category category = categories.getCategory();
selectedCats.add(category.getID());
addAncestorCats(ancestorCats, category);
}
final BigDecimal[][] paramArray = new BigDecimal[2][];
paramArray[0] = selectedCats.toArray(new BigDecimal[selectedCats.size()]);
paramArray[1] = ancestorCats.toArray(new BigDecimal[ancestorCats.size()]);
m_category.setValue(state,
ids.toArray(new BigDecimal[ids.size()]));
// m_category.setValue(state,
// selectedCats.toArray(new BigDecimal[selectedCats.size()]));
m_category.setValue(state, paramArray);
}
});
@ -121,7 +127,7 @@ public abstract class ACSObjectCategoryForm extends Form {
BigDecimal[] ids = (BigDecimal[]) m_category.getValue(state);
for (BigDecimal id : ids) {
Category cat = (Category) DomainObjectFactory
.newInstance(new OID(Category.BASE_DATA_OBJECT_TYPE, id));
.newInstance(new OID(Category.BASE_DATA_OBJECT_TYPE, id));
if (!curSelectedCat.contains(id)) {
cat.addChild(object);
} else {
@ -144,9 +150,21 @@ public abstract class ACSObjectCategoryForm extends Form {
fireCompletionEvent(state);
throw new FormProcessException("Submission cancelled",
GlobalizationUtil.globalize(
"categorization.cancel.msg"));
"categorization.cancel.msg"));
}
}
});
}
private void addAncestorCats(final Set<BigDecimal> ancestorCats, final Category category) {
final CategoryCollection ascendants = category.getDefaultAscendants();
while(ascendants.next()) {
final Category ascendant = ascendants.getCategory();
ancestorCats.add(ascendant.getID());
}
}
}

View File

@ -41,27 +41,25 @@ import java.util.Iterator;
import org.apache.log4j.Logger;
/**
* This is a simple extension of the QueryComponent that
* provides management of the 'terms' parameter and uses
* FilterGenerators to populate a query specification
* This is a simple extension of the QueryComponent that provides management of the 'terms'
* parameter and uses FilterGenerators to populate a query specification
* <p>
* Typical use would be as follows:
*<pre>
* <pre>
* Form f = new Form("search");
* BaseQueryComponent q = new BaseQueryComponent();
* q.add(new ObjectTypeFilterComponent("com.arsdigita.kernel.User");
* q.add(new PermissionGenerator(PrivilegeDescriptor.READ));
* q.add(new Submit("Go"));
* f.add(q);
*</pre>
* </pre>
*/
public class BaseQueryComponent extends QueryComponent {
private static final Logger s_log =
Logger.getLogger(BaseQueryComponent.class);
private static final Logger s_log
= Logger.getLogger(BaseQueryComponent.class);
private Set m_filters;
private Form m_form;
private StringParameter m_terms = new StringParameter("terms");
@ -73,25 +71,25 @@ public class BaseQueryComponent extends QueryComponent {
super("query");
m_filters = new HashSet();
}
@Override
public void register(Page p) {
super.register(p);
findFilters(m_filters);
}
@Override
public void register(Form form, FormModel model) {
if (s_log.isDebugEnabled()) {
s_log.debug("Adding " + m_terms.getName() + " to form model");
}
s_log.debug("Adding " + m_terms.getName() + " to form model");
s_log.debug("Adding " + m_terms.getName() + " to form model");
m_terms.setPassIn(true);
model.addFormParam(m_terms);
m_form = form;
}
/**
* Gets the current search terms
*/
@ -99,41 +97,39 @@ public class BaseQueryComponent extends QueryComponent {
FormData fd = m_form.getFormData(state);
if (fd != null) {
ParameterData data = fd.getParameter(m_terms.getName());
s_log.debug("Search terms were : " + (String)data.getValue());
return (String)data.getValue();
s_log.debug("Search terms were : " + (String) data.getValue());
return (String) data.getValue();
}
return null;
}
protected FilterSpecification[] getFilters(PageState state) {
FilterSpecification[] filters = new FilterSpecification[m_filters.size()];
Iterator i = m_filters.iterator();
int c = 0;
while (i.hasNext()) {
FilterGenerator filter = (FilterGenerator)i.next();
FilterGenerator filter = (FilterGenerator) i.next();
filters[c++] = filter.getFilter(state);
}
return filters;
}
/**
*
*
* @param state
* @param parent
* @param parent
*/
@Override
public void generateXML(PageState state,
Element parent) {
Element content = generateParent(parent);
Element terms = Search.newElement("terms");
terms.addAttribute("param", m_terms.getName());
terms.addAttribute("value",
Globalization.decodeParameter(state.getRequest(),
terms.addAttribute("value",
Globalization.decodeParameter(state.getRequest(),
m_terms.getName()));
generateErrorXML(state, terms);
content.addContent(terms);
@ -152,7 +148,7 @@ public class BaseQueryComponent extends QueryComponent {
while (i.hasNext()) {
Element error = Search.newElement("error");
error.setText(
(String) ((GlobalizedMessage) i.next()).localize(state.getRequest())
(String) ((GlobalizedMessage) i.next()).localize(state.getRequest())
);
parent.addContent(error);
}
@ -162,10 +158,11 @@ public class BaseQueryComponent extends QueryComponent {
FilterTraversal trav = new FilterTraversal(filters);
trav.preorder(this);
}
private class FilterTraversal extends Traversal {
private Set m_filters;
public FilterTraversal(Set filters) {
m_filters = filters;
}

View File

@ -30,8 +30,8 @@ import com.arsdigita.util.Assert;
/**
* A base class for generating a query specification
* from the state. Subclasses must implement two
* methods, one for getting the query tmers,
* the other for gettting a set of filter specs.
* methods, one for getting the query terms,
* the other for getting a set of filter specs.
*/
public abstract class QueryComponent extends SimpleContainer
implements QueryGenerator {

View File

@ -21,7 +21,6 @@ package com.arsdigita.search.ui;
import com.arsdigita.bebop.SimpleComponent;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.parameters.IntegerParameter;
import com.arsdigita.bebop.util.GlobalizationUtil;
import com.arsdigita.globalization.Globalization;
import com.arsdigita.globalization.GlobalizedMessage;

View File

@ -7,7 +7,7 @@
</text>
<text id="category-step/header">
<translation lang="de">Kategorienzuweisen bearbeiten</translation>
<translation lang="de">Zugewiesene Kategorien</translation>
<translation lang="en">Edit assigned categories</translation>
</text>

View File

@ -33,7 +33,7 @@
xmlns:cms="http://www.arsdigita.com/cms/1.0"
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
exclude-result-prefixes="xsl bebop cms nav"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="2.0">
<!-- DE Seitenstruktur -->

View File

@ -28,14 +28,13 @@
<!-- Autor: Sören Bernstein -->
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:bebop="http://www.arsdigita.com/bebop/1.0"
xmlns:cms="http://www.arsdigita.com/cms/1.0"
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="1.0">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:bebop="http://www.arsdigita.com/bebop/1.0"
xmlns:cms="http://www.arsdigita.com/cms/1.0"
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="1.0">
<!-- DE Benutze DHTML-Editor (HTMLArea) -->
<!-- EN Use DHTML-Editor (HTMLArea) -->

View File

@ -49,6 +49,7 @@
<xsl:if test="not(./@method)">
<xsl:attribute name="method">post</xsl:attribute>
</xsl:if>
<xsl:attribute name="here" select="'foo'"/>
<xsl:call-template name="foundry:process-datatree-attributes"/>
<xsl:apply-templates/>
</form>

View File

@ -26,14 +26,13 @@
Processing bebop images
-->
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:bebop="http://www.arsdigita.com/bebop/1.0"
xmlns:cms="http://www.arsdigita.com/cms/1.0"
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="1.0">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:bebop="http://www.arsdigita.com/bebop/1.0"
xmlns:cms="http://www.arsdigita.com/cms/1.0"
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="2.0">
<!-- DE Verarbeite Bilder - Ignoriere javascript-mode -->
<!-- EN Processing images - inore javascript-mode -->

View File

@ -33,7 +33,7 @@
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="1.0">
version="2.0">
<!-- DE Ein Text-Label mit Formatierung -->
<!-- EN A formatted text label -->

View File

@ -26,14 +26,13 @@
Processing bebop lists
-->
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:bebop="http://www.arsdigita.com/bebop/1.0"
xmlns:cms="http://www.arsdigita.com/cms/1.0"
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="1.0">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:bebop="http://www.arsdigita.com/bebop/1.0"
xmlns:cms="http://www.arsdigita.com/cms/1.0"
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="2.0">
<!-- DE Eine verticale Liste als UL, wenn es keine item-path-Liste ist -->
<!-- EN A vertical list as ul, if it is not an item-path type list -->

View File

@ -33,7 +33,7 @@
xmlns:cms="http://www.arsdigita.com/cms/1.0"
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
exclude-result-prefixes="xsl bebop foundry cms"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="2.0">
<!-- DE Schreibe den PageState in versteckte Input-Felder -->

View File

@ -33,7 +33,6 @@
xmlns:cms="http://www.arsdigita.com/cms/1.0"
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
xmlns:mandalay="http://mandalay.quasiweb.de"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="2.0">

View File

@ -29,13 +29,13 @@
<!-- Autor: Sören Bernstein -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:bebop="http://www.arsdigita.com/bebop/1.0"
xmlns:cms="http://www.arsdigita.com/cms/1.0"
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="2.0">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:bebop="http://www.arsdigita.com/bebop/1.0"
xmlns:cms="http://www.arsdigita.com/cms/1.0"
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="2.0">
<!-- DE Erzeuge einen Div-Container mit Tabellenreitern -->
<!-- EN Create a div container with tab -->

View File

@ -32,7 +32,7 @@
xmlns:foundry="http://foundry.libreccm.org"
xmlns:nav="http://ccm.redhat.com/navigation"
exclude-result-prefixes="xsl bebop cms foundry nav"
version="1.0">
version="2.0">
<!-- DE Erzeuge Tabelle. Da die einzelnen Bestandteile (thead, tbody und tfoot) nicht
in der von HTML vorgesehenen Reihenfolge im XML stehen, müssen diese hier in

View File

@ -282,16 +282,20 @@
<!--<script type="text/javascript" src="{$context-prefix}/assets/jquery.js"/> -->
<!--<script type="text/javascript" src="{$theme-prefix}/includes/cms/category-step.js"/> -->
<xsl:choose>
<xsl:when test="@mode='javascript'">
<xsl:when test="./@mode = 'javascript'">
<ul>
<xsl:apply-templates select="cms:category" mode="javascript"/>
</ul>
<xsl:apply-templates select="cms:selectedCategories"/>
<xsl:apply-templates select="cms:selectedAncestorCategories"/>
<script type="text/javascript">
colorAncestors();
</script>
</xsl:when>
<xsl:otherwise>
<select name="@name" size="30" multiple="multiple">
<select name="./@name" size="30" multiple="multiple">
<xsl:apply-templates mode="plain">
<xsl:sort data-type="number" select="@sortKey"/>
<xsl:sort data-type="number" select="./@sortKey"/>
</xsl:apply-templates>
</select>
</xsl:otherwise>
@ -299,14 +303,26 @@
</xsl:template>
<xsl:template match="cms:selectedCategories">
<select id="catWdHd" name="{../@name}" size="5" multiple="multiple" style="display: none">
<select id="catWdHd"
name="{../@name}"
size="5"
multiple="multiple"
style="display: none">
<xsl:apply-templates select="cms:category" mode="hidden"/>
</select>
</xsl:template>
<xsl:template match="cms:selectedAncestorCategories">
<input id = "selectedAncestorCategories"
name = "selectedAncestorCategories"
value = "{string-join(./cms:category/@id, ',')}"
type = "hidden" />
</xsl:template>
<xsl:template match="cms:category" mode="hidden">
<option value="{@id}">
<xsl:value-of select="@id"/>
<option value="{./@id}">
<xsl:value-of select="./@id"/>
</option>
<xsl:apply-templates select="cms:category" mode="hidden"/>
</xsl:template>
@ -326,7 +342,7 @@
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<li id="catSelf{@id}">
<li id="catSelf{@id}" class="notSelectedAncestorCategory">
<!-- Treefunctions (expand and collapse) -->
<xsl:variable name="tree-toogle-mode">
<xsl:choose>

View File

@ -25,6 +25,36 @@
These functions are part of the ajax-pages to assign categories.
*/
function colorAncestors() {
var ancestorCategories =
document.category.selectedAncestorCategories.value.split(",");
for (var i = 0; i < ancestorCategories.length; ++i) {
//alert("trying to find catSelf" + ancestorCategories[i]);
console.log("trying to find catSelf" + ancestorCategories[i]);
var elem = document.getElementById("catSelf" + ancestorCategories[i]);
if (elem !== null) {
//alert("found catSelf" + ancestorCategories[i]);
console.log("found catSelf" + ancestorCategories[i]);
var oldClasses = elem.className.split(" ");
var classes = "";
for (var j = 0; j < oldClasses.length; ++j) {
if (oldClasses[j] !== "selectedAncestorCategory"
&& oldClasses[j] !== "notSelectedAncestorCategory") {
classes = classes + " " + oldClasses[j];
}
}
classes = classes + " selectedAncestorCategory";
//alert("setting class for catSelf" + ancestorCategories[i] + " to " + classes);
elem.className = classes;
// if (oldClassName.indexOf("selectedAncestorCategory") === -1) {
// elem.className = elem.className + "selectedAncestorCategory";
// }
}
}
}
// DE Lade einen Kategorienzweig nach, wenn dieser aufgeklappt wird
// EN Loading a branch of categories when it is expanded
function catBranchToggle(id, selCats) {
@ -35,7 +65,9 @@ function catBranchToggle(id, selCats) {
if (elBranch.innerHTML == "" || elBranch.innerHTML == "...") {
elBranch.innerHTML = "...";
elBranch.style.display = "block";
$(elBranch).load("load-cat.jsp", "nodeID=" + id + "&selectedCats=" + selCats);
$(elBranch).load("load-cat.jsp", "nodeID=" + id + "&selectedCats=" + selCats, function () {
colorAncestors()
});
} else {
elBranch.style.display = "block";
}
@ -46,6 +78,9 @@ function catBranchToggle(id, selCats) {
elToggleTreeImage.src = elToggleTreeImage.src.replace("Collapse", "Expand");
elToggleTreeImage.alt = "[+]";
}
colorAncestors();
return false;
}
@ -64,6 +99,9 @@ function catToggle(id, selCats) {
elToggleTreeImage.src = elToggleTreeImage.src.replace("Collapse", "Expand");
elToggleTreeImage.alt = "[+]";
}
colorAncestors();
return false;
}

View File

@ -1056,6 +1056,14 @@ form[name="category"] table table{
background: none;
}
form[name="category"] ul li.notSelectedAncestorCategory {
background-color: #e6dcde;
}
form[name="category"] ul li ul li.selectedAncestorCategory {
background-color: #fff;
}
div.bebop-segment {
margin-bottom:1em;
padding-bottom:0.5em;

View File

@ -7,7 +7,7 @@
</text>
<text id="category-step/header">
<translation lang="de">Kategorienzuweisen bearbeiten</translation>
<translation lang="de">Zugewiesene Kategorien bearbeiten</translation>
<translation lang="en">Edit assigned categories</translation>
</text>

View File

@ -53,24 +53,25 @@ import com.arsdigita.xml.XML;
* A Widget for selecting Terms. Based heavily on CategoryWidget.
*
* @author mbooth@redhat.com
*
* Chris Gilbert - updated to identify each node uniquely (correct behaviour
* for polyhierarchical trees) - also, allow ajax update on all branches or
* just top level branch
*
* nb - widget applies to allocation of categories to any ACSObject hence
* xml prefix should be more generic eg bebop rather than cms. cms retained
* for compatibility with existing stylesheets
*
* Chris Gilbert - updated to identify each node uniquely (correct behaviour for
* polyhierarchical trees) - also, allow ajax update on all branches or just top
* level branch
*
* nb - widget applies to allocation of categories to any ACSObject hence xml
* prefix should be more generic eg bebop rather than cms. cms retained for
* compatibility with existing stylesheets
*/
// NON Javadoc comment:
// Copied from c.ad.aplaws.ui in order to make forum-categorised independend from
// a specific ccm-???-aplaws, i.e. a specific integration layer.
public class TermWidget extends Widget {
private StringParameter m_mode;
private ACSObjectCategoryPicker m_picker;
private final StringParameter m_mode;
private final ACSObjectCategoryPicker m_picker;
public TermWidget(StringParameter mode, ACSObjectCategoryPicker picker) {
public TermWidget(final StringParameter mode,
final ACSObjectCategoryPicker picker) {
super(new ArrayParameter(new BigDecimalParameter("category")));
m_mode = mode;
@ -89,32 +90,83 @@ public class TermWidget extends Widget {
}
@Override
protected void generateWidget(PageState state, Element parent) {
Domain domain = m_picker.getDomain(state);
protected void generateWidget(final PageState state, final Element parent) {
final Domain domain = m_picker.getDomain(state);
Element widget = parent.newChildElement("cms:categoryWidget",
CMS.CMS_XML_NS);
final Element widget = parent.newChildElement("cms:categoryWidget",
CMS.CMS_XML_NS);
exportAttributes(widget);
widget.addAttribute("mode", (String) state.getValue(m_mode));
widget.addAttribute("name", getName());
Set ids = new HashSet();
BigDecimal[] values = (BigDecimal[]) getValue(state);
final Set<BigDecimal> selectedCats = new HashSet<BigDecimal>();
//jensp 2015-03-12: In same cases we need to be able to pass the selected categories *and*
//the selected roots for displaying the categories nicely. To maintain backwards
//compatibility we check the type of the value and work either with the selected categories
//only or with the selected categories and their roots.
final Set<BigDecimal> selectedAncestors = new HashSet<BigDecimal>();
final BigDecimal[] values;
final BigDecimal[] selAncestorsValues; //selectedAncestors
final Object valueObj = getValue(state);
if (valueObj instanceof BigDecimal[][]) {
if (((BigDecimal[][]) valueObj).length >= 1) {
values = ((BigDecimal[][]) valueObj)[0];
} else {
throw new IllegalArgumentException(
"Value of TermWidget is of type BigDecimal[][] but the array is empty.");
}
if (((BigDecimal[][]) valueObj).length >= 2) {
selAncestorsValues = ((BigDecimal[][]) valueObj)[1];
} else {
selAncestorsValues = null;
}
} else if (valueObj instanceof BigDecimal[]) {
values = (BigDecimal[]) valueObj;
selAncestorsValues = null;
} else {
throw new IllegalArgumentException(
"Value of TermWidget is not of type BigDecimal[] or BigDecimal[][]");
}
//BigDecimal[] values = (BigDecimal[]) getValue(state);
if (values != null) {
ids.addAll(Arrays.asList(values));
selectedCats.addAll(Arrays.asList(values));
}
Element selEl = widget.newChildElement("cms:selectedCategories", CMS.CMS_XML_NS);
selEl.addAttribute("name", this.getName());
Iterator selCats = ids.iterator();
while (selCats.hasNext()) {
Element selCat = selEl.newChildElement("cms:category", CMS.CMS_XML_NS);
selCat.addAttribute("id", selCats.next().toString());
if (selAncestorsValues != null) {
selectedAncestors.addAll(Arrays.asList(selAncestorsValues));
}
final Element selEl = widget.newChildElement(
"cms:selectedCategories", CMS.CMS_XML_NS);
selEl.addAttribute("name", getName());
final Iterator<BigDecimal> selCats = selectedCats.iterator();
// while (selCats.hasNext()) {
// final Element selCat = selEl.newChildElement("cms:category",
// CMS.CMS_XML_NS);
// selCat.addAttribute("id", selCats.next().toString());
// }
for(BigDecimal selectedCat : selectedCats) {
final Element selectedCatElem = selEl.newChildElement(
"cms:category", CMS.CMS_XML_NS);
selectedCatElem.addAttribute("id", selectedCat.toString());
}
final Element selAncestorsElem = widget.newChildElement(
"cms:selectedAncestorCategories", CMS.CMS_XML_NS);
selAncestorsElem.addAttribute("name", getName());
for(BigDecimal selAncestor : selectedAncestors) {
final Element selAncestorElem = selAncestorsElem.newChildElement(
"cms:category", CMS.CMS_XML_NS);
selAncestorElem.addAttribute("id", selAncestor.toString());
}
// only root terms at first, the rest is loaded on-demand via AJAX
DomainCollection terms = domain.getRootTerms();
final DomainCollection terms = domain.getRootTerms();
// DomainCollection terms = domain.getTerms();
terms.addPath("model.parents.link.sortKey");
terms.addPath("model.parents.id");
@ -135,35 +187,41 @@ public class TermWidget extends Widget {
List roots = new LinkedList();
while (terms.next()) {
Term term = (Term) terms.getDomainObject();
roots.add(new TermSortKeyPair(term, (BigDecimal) terms.get("model.parents.link.sortKey")));
roots.add(new TermSortKeyPair(term, (BigDecimal) terms.get(
"model.parents.link.sortKey")));
}
Element el = generateCategory(widget, domain.getModel(), ids, null);
Element el = generateCategory(widget, domain.getModel(), selectedCats,
null);
/**
* Used by kea based keyphrase extraction facility.
* (Added r1885)
*
* Used by kea based keyphrase extraction facility. (Added r1885)
*
* @Author: terry_permeance
*/
Indexer indexer = Indexer.retrieve(domain);
if (indexer != null) {
ContentItem item = CMS.getContext().getContentItem();
List<RankedTerm> autoTerms = indexer.index(item, 16);
Element autoCategories = widget.newChildElement("cms:autoCategories", CMS.CMS_XML_NS);
Element autoCategories = widget
.newChildElement("cms:autoCategories", CMS.CMS_XML_NS);
for (Iterator<RankedTerm> i = autoTerms.iterator(); i.hasNext();) {
RankedTerm nextRankedTerm = i.next();
Category cat = nextRankedTerm.getTerm().getModel();
if (!ids.contains(cat.getID())) {
if (!selectedCats.contains(cat.getID())) {
String fullname = cat.getQualifiedName(" > ", false);
if (fullname != null) {
Element catEl = autoCategories.newChildElement("cms:category", CMS.CMS_XML_NS);
Element catEl = autoCategories.newChildElement(
"cms:category", CMS.CMS_XML_NS);
catEl.addAttribute("id", XML.format(cat.getID()));
catEl.addAttribute("name", cat.getName());
catEl.addAttribute("description", cat.getDescription());
catEl.addAttribute("isAbstract", cat.isAbstract() ? "1" : "0");
catEl.addAttribute("isEnabled", cat.isEnabled() ? "1" : "0");
catEl.addAttribute("sortKey", nextRankedTerm.getRanking().toString());
catEl.addAttribute("isAbstract", cat.isAbstract() ? "1"
: "0");
catEl.addAttribute("isEnabled", cat.isEnabled() ? "1"
: "0");
catEl.addAttribute("sortKey", nextRankedTerm
.getRanking().toString());
catEl.addAttribute("fullname", fullname);
}
}
@ -172,10 +230,10 @@ public class TermWidget extends Widget {
if (Terms.getConfig().ajaxExpandAllBranches()) {
// add attribute to the parent node, so that in stylesheet
// we can look for any ancestor with this attribute (can't
// add attribute to categoryWidget element as that is not
// visible when subbranches are transformed)
el.addAttribute("expand", "all" );
// we can look for any ancestor with this attribute (can't
// add attribute to categoryWidget element as that is not
// visible when subbranches are transformed)
el.addAttribute("expand", "all");
}
for (Iterator i = roots.iterator(); i.hasNext();) {
@ -183,20 +241,22 @@ public class TermWidget extends Widget {
Term term = pair.getTerm();
BigDecimal sortKey = pair.getSortKey();
generateRootTerm(el, term, ids, sortKey);
generateRootTerm(el, term, selectedCats, sortKey);
}
}
public static Element generateCategory(Element parent,
Category cat,
Set selected,
BigDecimal sortKey) {
Category cat,
Set selected,
BigDecimal sortKey) {
Element el = parent.newChildElement("cms:category", CMS.CMS_XML_NS);
el.addAttribute("id", XML.format(cat.getID()));
el.addAttribute("name", cat.getName());
el.addAttribute("description", cat.getDescription());
el.addAttribute("isSelected", selected.contains(cat.getID()) ? "1" : "0");
el
.addAttribute("isSelected", selected.contains(cat.getID()) ? "1"
: "0");
el.addAttribute("isAbstract", cat.isAbstract() ? "1" : "0");
el.addAttribute("isEnabled", cat.isEnabled() ? "1" : "0");
if (sortKey != null) {
@ -204,13 +264,14 @@ public class TermWidget extends Widget {
}
// sort order attribute added to every node so that we can
// correctly transform xml fragments returned by ajax
el.addAttribute("order", ContentSection.getConfig().getCategoryTreeOrder());
el.addAttribute("order", ContentSection.getConfig()
.getCategoryTreeOrder());
el.addAttribute("genCat", "true");
StringBuilder path = new StringBuilder(parent.getAttribute("fullname"));
if (path.length() > 0) {
path.append(" > ");
}
path.append(cat.getName());
el.addAttribute("fullname", path.toString());
@ -221,7 +282,7 @@ public class TermWidget extends Widget {
StringBuilder nodeID = new StringBuilder(parent.getAttribute("node-id"));
if (nodeID.length() > 0) {
nodeID.append("-");
}
nodeID.append(cat.getID());
el.addAttribute("node-id", nodeID.toString());
@ -230,9 +291,9 @@ public class TermWidget extends Widget {
}
public static Element generateTerm(Element parent,
Term term,
Set selected,
BigDecimal sortKey) {
Term term,
Set selected,
BigDecimal sortKey) {
Category cat = term.getModel();
Element el = generateCategory(parent, cat, selected, sortKey);
@ -242,22 +303,23 @@ public class TermWidget extends Widget {
}
private static void generateRootTerm(Element parent,
Term term,
Set selected,
BigDecimal sortKey) {
Term term,
Set selected,
BigDecimal sortKey) {
Element el = generateTerm(parent, term, selected, sortKey);
el.addAttribute("root", "1");
}
public static void generateSubtree(Element parent, Category root, Set ids) {
DataCollection terms = SessionManager.getSession().retrieve(
Term.BASE_DATA_OBJECT_TYPE);
Term.BASE_DATA_OBJECT_TYPE);
terms.addEqualsFilter("model.roTransParents.id", root.getID());
terms.addEqualsFilter("model.parents.link.relationType", "child");
Map children = new HashMap();
while (terms.next()) {
Term term = (Term) DomainObjectFactory.newInstance(terms.getDataObject());
Term term = (Term) DomainObjectFactory.newInstance(terms
.getDataObject());
BigDecimal parentID = (BigDecimal) terms.get("model.parents.id");
List childList = (List) children.get(parentID);
@ -266,18 +328,20 @@ public class TermWidget extends Widget {
children.put(parentID, childList);
}
childList.add(new TermSortKeyPair(term, (BigDecimal) terms.get("model.parents.link.sortKey")));
childList.add(new TermSortKeyPair(term, (BigDecimal) terms.get(
"model.parents.link.sortKey")));
}
Element el = generateCategory(parent, root, ids, null);
el.addAttribute("fullname", root.getName());
el.addAttribute("node-id", root.getID().toString());
el.addAttribute("order", ContentSection.getConfig().getCategoryTreeOrder());
if (Terms.getConfig().ajaxExpandAllBranches()) {
el.addAttribute("order", ContentSection.getConfig()
.getCategoryTreeOrder());
if (Terms.getConfig().ajaxExpandAllBranches()) {
// recognisable attribute has to be in the XML for each snippet that is transformed,
// hence add it to the parent
el.addAttribute("expand", "all" );
}
// hence add it to the parent
el.addAttribute("expand", "all");
}
List roots = (List) children.get(root.getID());
if (null != roots) {
@ -293,10 +357,10 @@ public class TermWidget extends Widget {
}
private static void generateTermWithChildren(Element parent,
Term term,
Set selected,
BigDecimal sortKey,
Map children) {
Term term,
Set selected,
BigDecimal sortKey,
Map children) {
Category cat = term.getModel();
Element el = generateCategory(parent, cat, selected, sortKey);
@ -312,17 +376,14 @@ public class TermWidget extends Widget {
BigDecimal childSortKey = pair.getSortKey();
// either generate next level down, or get all levels below current
if (Terms.getConfig().ajaxExpandAllBranches()) {
generateTerm(el, child, selected, childSortKey);
generateTerm(el, child, selected, childSortKey);
} else {
generateTermWithChildren(el, child, selected, childSortKey,
children);
generateTermWithChildren(el, child, selected, childSortKey,
children);
}
}
}
}
@ -344,5 +405,7 @@ public class TermWidget extends Widget {
public BigDecimal getSortKey() {
return m_sortKey;
}
}
}