Merged V2.0 to HEAD

5146: AR-1122
   5148: AR-1116
   5149: RM-5
   5152: AR-1167
   5153: WCM-324
   5154: WCM-325, WCM-301, WCM-258, WCM-25, WCM-320
   5156: WCM-338
   5158: AR-1164
   5169: AR-1216
   5177: WCM-328


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5327 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2007-03-07 12:01:58 +00:00
parent 0671335628
commit 52a3fa1ed1
19 changed files with 877 additions and 187 deletions

View File

@@ -1310,10 +1310,6 @@ search_in=Search In
no_engines_registered=Failed to find any registered OpenSearch engines!
current_repo=Current Alfresco Repository
toggle_options=Toggle Options
no_results=No results
of=of
failed_gen_url=Failed to generate url for search engine '{0}'.\\n\\nThis is probably caused by missing required parameters, check the template url for the search engine.
failed_search=Failed to retrieve search results for '{0}'
# UI Page Titles
title_about=About Alfresco
@@ -1501,6 +1497,6 @@ validation_provide_values_for_required_fields=Please provide values for all requ
# XForms ui
idle=Idle
loading=Loading
eg=e.g.
# File Picker
go_up=Go up

View File

@@ -1,15 +1,13 @@
(
TYPE:"{http://www.alfresco.org/model/content/1.0}content" AND
(
(
TYPE:"{http://www.alfresco.org/model/content/1.0}content" AND <#t>
( <#t>
( <#t>
<#list 1..terms?size as i>
@\\{http\\://www.alfresco.org/model/content/1.0\\}name:${terms[i - 1]} <#if (i < terms?size)> OR </#if>
@\{http\://www.alfresco.org/model/content/1.0\}name:${terms[i - 1]}<#if (i < terms?size)> OR </#if> <#t>
</#list>
)
(
) <#t>
( <#t>
<#list 1..terms?size as i>
TEXT:${terms[i - 1]} <#if (i < terms?size)> OR </#if>
TEXT:${terms[i - 1]}<#if (i < terms?size)> OR </#if> <#t>
</#list>
)
)
)
) <#t>
) <#t>

View File

@@ -24,6 +24,7 @@
</#if>
<link rel="search" type="application/opensearchdescription+xml" href="${request.servicePath}/search/keywordsearchdescription.xml"/>
<#list search.results as row>
<#attempt>
<entry>
<title>${row.name}</title>
<link rel="alternate" href="${absurl(row.url)}"/>
@@ -36,5 +37,7 @@
</author>
<relevance:score>${row.score}</relevance:score>
</entry>
<#recover>
</#attempt>
</#list>
</feed>

View File

@@ -25,6 +25,7 @@
<br>
<table>
<#list search.results as row>
<#attempt>
<tr>
<td><img src="${absurl(row.icon16)}"/></td><td><a href="${absurl(row.url)}">${row.name}</a></td>
</tr>
@@ -34,6 +35,8 @@
<td>${row.properties.description}</td>
</tr>
</#if>
<#recover>
</#attempt>
</#list>
</table>
<br>

View File

@@ -29,6 +29,7 @@
</#if>
<atom:link rel="search" type="application/opensearchdescription+xml" href="${request.servicePath}/search/keywordsearchdescription.xml"/>
<#list search.results as row>
<#attempt>
<item>
<title>${row.name}</title>
<link>${absurl(row.url)}</link>
@@ -36,6 +37,8 @@
<pubDate>${xmldate(row.properties.modified)}</pubDate>
<guid isPermaLink="false">${row.id}</guid>
</item>
<#recover>
</#attempt>
</#list>
</channel>
</rss>

View File

@@ -34,6 +34,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.util.TempFileProvider;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.FileUploadBean;
@@ -127,7 +128,8 @@ public class UploadFileServlet extends BaseServlet
if (logger.isDebugEnabled())
{
logger.debug("Temp file: " + tempFile.getAbsolutePath() +
" created from upload filename: " + filename);
" size " + tempFile.length() +
" bytes created from upload filename: " + filename);
}
}
}
@@ -152,7 +154,8 @@ public class UploadFileServlet extends BaseServlet
{
logger.debug("Sending back javascript response " + returnPage);
}
response.setContentType(MimetypeMap.MIMETYPE_HTML);
response.setCharacterEncoding("utf-8");
final PrintWriter out = response.getWriter();
out.println("<html><body><script type=\"text/javascript\">");
out.println(returnPage);
@@ -164,7 +167,7 @@ public class UploadFileServlet extends BaseServlet
// finally redirect
if (logger.isDebugEnabled())
{
logger.debug("Upload servicing complete, redirecting to: " + returnPage);
logger.debug("redirecting to: " + returnPage);
}
response.sendRedirect(returnPage);
@@ -173,7 +176,12 @@ public class UploadFileServlet extends BaseServlet
catch (Throwable error)
{
Application.handleServletError(getServletContext(), (HttpServletRequest)request,
(HttpServletResponse)response, error, logger, returnPage);
(HttpServletResponse)response, error, logger, returnPage);
}
if (logger.isDebugEnabled())
{
logger.debug("upload complete");
}
}
}

View File

@@ -13,14 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.alfresco.web.bean.wcm;
@@ -59,6 +52,7 @@ import org.alfresco.web.forms.Form;
import org.alfresco.web.forms.FormInstanceData;
import org.alfresco.web.forms.FormInstanceDataImpl;
import org.alfresco.web.forms.FormProcessor;
import org.alfresco.web.forms.RenderingEngineTemplate;
import org.alfresco.web.forms.Rendition;
import org.alfresco.web.forms.RenditionImpl;
import org.alfresco.web.forms.XMLUtil;
@@ -597,16 +591,15 @@ public class AVMEditBean
if (LOGGER.isDebugEnabled())
LOGGER.debug("regenerating renditions of " + fid);
for (Rendition rendition : fid.getRenditions())
for (RenderingEngineTemplate ret : this.getForm().getRenderingEngineTemplates())
{
try
{
rendition.regenerate(fid);
ret.render(fid);
}
catch (Exception e)
{
Utils.addErrorMessage("error regenerating " + rendition.getName() +
" using " + rendition.getRenderingEngineTemplate().getName() +
Utils.addErrorMessage("error regenerating rendition using " + ret.getName() +
": " + e.getMessage(),
e);
}

View File

@@ -39,6 +39,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
@@ -166,6 +167,37 @@ public class XMLUtil
return XMLUtil.documentBuilder;
}
/**
* FOR DIAGNOSTIC PURPOSES ONLY - incomplete<br/>
* Builds a path to the node relative to the to node provided.
* @param from the node from which to build the xpath
* @param to an ancestor of <tt>from</tt> which will be the root of the path
* @return an xpath to <tt>to</tt> rooted at <tt>from</tt>.
*/
public static String buildXPath(final Element from, final Element to)
{
String result = "";
Node tmp = from;
do
{
Node tmp2 = tmp;
int position = 1;
while (tmp2.getPreviousSibling() != null)
{
if (tmp2.getNodeName().equals(tmp.getNodeName()))
{
position++;
}
tmp2 = tmp2.getPreviousSibling();
}
String part = tmp.getNodeName() + "[" + position + "]";
result = result == null ? "/" + part : "/" + part + result;
tmp = tmp.getParentNode();
}
while (tmp != to.getParentNode() && tmp != null);
return result;
}
public static DocumentBuilder getDocumentBuilder(final boolean namespaceAware,
final boolean validating)
{

View File

@@ -93,14 +93,15 @@ public class Schema2XForms
private final Map<String, Long> counter = new HashMap<String, Long>();
private String targetNamespace;
// typeTree
// each entry is keyed by the type name
// value is an ArrayList that contains the XSTypeDefinition's which
// are compatible with the specific type. Compatible means that
// can be used as a substituted type using xsi:type
// In order for it to be compatible, it cannot be abstract, and
// it must be derived by extension.
// The ArrayList does not contain its own type + has the other types only once
/**
* each entry is keyed by the type name
* value is an ArrayList that contains the XSTypeDefinition's which
* are compatible with the specific type. Compatible means that
* can be used as a substituted type using xsi:type
* In order for it to be compatible, it cannot be abstract, and
* it must be derived by extension.
* The ArrayList does not contain its own type + has the other types only once
*/
private TreeMap<String, TreeSet<XSTypeDefinition>> typeTree;
/**
@@ -159,6 +160,7 @@ public class Schema2XForms
//check if target namespace
final StringList schemaNamespaces = schema.getNamespaces();
final HashMap<String, String> schemaNamespacesMap = new HashMap<String, String>();
if (schemaNamespaces.getLength() != 0)
{
// will return null if no target namespace was specified
@@ -172,12 +174,16 @@ public class Schema2XForms
continue;
}
final String prefix = schemaDocument.lookupPrefix(schemaNamespaces.item(i));
LOGGER.debug("adding namespace " + schemaNamespaces.item(i) +
" with prefix " + prefix +
" to xform and default instance element");
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("adding namespace " + schemaNamespaces.item(i) +
" with prefix " + prefix +
" to xform and default instance element");
}
this.addNamespace(xformsDocument.getDocumentElement(),
prefix,
schemaNamespaces.item(i));
schemaNamespacesMap.put(prefix, schemaNamespaces.item(i));
}
}
@@ -273,7 +279,8 @@ public class Schema2XForms
if (importedInstanceDocumentElement != null)
{
this.insertPrototypeNodes(importedInstanceDocumentElement,
defaultInstanceDocumentElement);
defaultInstanceDocumentElement,
schemaNamespacesMap);
}
this.createSubmitElements(xformsDocument, modelSection, rootGroup);
@@ -296,8 +303,18 @@ public class Schema2XForms
this.counter.clear();
}
/**
* Inserts prototype nodes into the provided instance document by aggregating insertion
* points from the generated prototype instance docment.
*
* @param instanceDocumentElement the user provided instance document
* @param prototypeInstanceElement the generated prototype instance document
* @param schemaNamespaces the namespaces used by the instance document needed for
* initializing the xpath context.
*/
private void insertPrototypeNodes(final Element instanceDocumentElement,
final Element prototypeDocumentElement)
final Element prototypeDocumentElement,
final HashMap<String, String> schemaNamespaces)
{
final JXPathContext prototypeContext =
JXPathContext.newContext(prototypeDocumentElement);
@@ -307,15 +324,20 @@ public class Schema2XForms
JXPathContext.newContext(instanceDocumentElement);
instanceContext.registerNamespace(NamespaceService.ALFRESCO_PREFIX,
NamespaceService.ALFRESCO_URI);
for (final String prefix : schemaNamespaces.keySet())
{
prototypeContext.registerNamespace(prefix, schemaNamespaces.get(prefix));
instanceContext.registerNamespace(prefix, schemaNamespaces.get(prefix));
}
class PrototypeInsertionData
{
final Node prototype;
final List nodes;
final List<Node> nodes;
final boolean append;
PrototypeInsertionData(final Node prototype,
final List nodes,
final List<Node> nodes,
final boolean append)
{
this.prototype = prototype;
@@ -323,55 +345,141 @@ public class Schema2XForms
this.append = append;
}
};
final List<PrototypeInsertionData> prototypesToInsert =
new LinkedList<PrototypeInsertionData>();
final HashMap<String, PrototypeInsertionData> prototypesToInsert =
new HashMap<String, PrototypeInsertionData>();
// find all prototype nodes
final Iterator it =
prototypeContext.iteratePointers("//*[@" + NamespaceService.ALFRESCO_PREFIX +
":prototype='true']");
":prototype='true'][ancestor::*[not(@" + NamespaceService.ALFRESCO_PREFIX +
":prototype)]]");
// find all relevant insertion points within the instance document
while (it.hasNext())
{
final Pointer p = (Pointer)it.next();
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("evaluating prototype node " + p.asPath());
}
String path = p.asPath().replaceAll("\\[\\d+\\]", "") + "[last()]";
LOGGER.debug("evaluating " + path + " against instance document");
List l = instanceContext.selectNodes(path);
if (prototypesToInsert.containsKey(path))
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("already checked path " + path + " - ignoring.");
}
continue;
}
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("evaluating " + path + " against instance document");
}
List<Node> l = (List<Node>)instanceContext.selectNodes(path);
if (l.size() != 0)
{
prototypesToInsert.add(new PrototypeInsertionData((Node)p.getNode(),
l,
false));
// this is a 1 to n repeat - add a prototype node to the list of repeat instances
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("path " + path + " evaluated to " + l.size() + " nodes");
}
prototypesToInsert.put(path, new PrototypeInsertionData((Node)p.getNode(),
l,
false));
}
if (path.lastIndexOf("/") != 0)
{
// this could be a 0 to n repeat - check if there are any relevant parent
// insertion points
path = path.replaceAll("\\/([^/]+)\\[last\\(\\)\\]$", "[not(child::$1)]");
l = (List<Node>)instanceContext.selectNodes(path);
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("path " + path + " evaluated to " + l.size() + " nodes");
}
prototypesToInsert.put(path, new PrototypeInsertionData((Node)p.getNode(),
l,
true));
}
else
{
int index = path.lastIndexOf('/');
path = index == 0 ? "/" : path.substring(0, index);
l = instanceContext.selectNodes(path);
prototypesToInsert.add(new PrototypeInsertionData((Node)p.getNode(),
l,
true));
// this could be a repeat at the root of the document
path = path.replaceAll("\\[last\\(\\)\\]$", "");
l = (List<Node>)instanceContext.selectNodes(path);
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("path " + path + " evaluated to " + l.size() + " nodes");
}
if (l.size() == 0)
{
l.add(instanceDocumentElement);
prototypesToInsert.put(path, new PrototypeInsertionData((Node)p.getNode(),
l,
true));
}
}
}
for (PrototypeInsertionData data : prototypesToInsert)
// apply prototype nodes to all discovered insertion points
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("adding prototype for " + data.prototype.getNodeName() +
" to " + data.nodes.size() + " nodes");
for (Object o : data.nodes)
LOGGER.debug("instance dcoument before mutation " +
XMLUtil.toString(instanceDocumentElement, true));
}
for (Map.Entry<String, PrototypeInsertionData> me : prototypesToInsert.entrySet())
{
final PrototypeInsertionData data = me.getValue();
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("adding prototype for " + data.prototype.getNodeName() +
" from path " + me.getKey() +
" to " + data.nodes.size() + " nodes");
}
for (final Node n : data.nodes)
{
final Node n = (Node)o;
if (data.append)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("appending " + data.prototype.getNodeName() +
" to " + XMLUtil.buildXPath((Element)n, instanceDocumentElement));
}
n.appendChild(data.prototype.cloneNode(true));
}
else if (n.getNextSibling() != null)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("inserting " + data.prototype.getNodeName() +
" into " + XMLUtil.buildXPath((Element)n.getParentNode(),
instanceDocumentElement) +
" before " + XMLUtil.buildXPath((Element)n.getNextSibling(),
instanceDocumentElement));
}
n.getParentNode().insertBefore(data.prototype.cloneNode(true),
n.getNextSibling());
}
else
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("appending " + data.prototype.getNodeName() +
" to " + XMLUtil.buildXPath((Element)n.getParentNode(),
instanceDocumentElement));
}
n.getParentNode().appendChild(data.prototype.cloneNode(true));
}
}
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("instance dcoument after mutation " +
XMLUtil.toString(instanceDocumentElement, true));
}
}
}

View File

@@ -13,16 +13,13 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.alfresco.web.forms.xforms;
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ResourceBundle;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
@@ -76,7 +73,8 @@ public class XFormsProcessor
"go_up",
"cancel",
"upload",
"path"
"path",
"eg"
};
public XFormsProcessor()
@@ -154,6 +152,25 @@ public class XFormsProcessor
js.append("alfresco_xforms_constants.FORM_INSTANCE_DATA_NAME = '").
append(session.getFormInstanceDataName()).
append("';\n");
SimpleDateFormat sdf = (SimpleDateFormat)
SimpleDateFormat.getDateInstance(DateFormat.SHORT,
Application.getLanguage(fc));
js.append("alfresco_xforms_constants.DATE_FORMAT = '").
append(sdf.toLocalizedPattern()).
append("';\n");
sdf = (SimpleDateFormat)
SimpleDateFormat.getTimeInstance(DateFormat.SHORT,
Application.getLanguage(fc));
js.append("alfresco_xforms_constants.TIME_FORMAT = '").
append(sdf.toLocalizedPattern()).
append("';\n");
sdf = (SimpleDateFormat)
SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.SHORT,
Application.getLanguage(fc));
js.append("alfresco_xforms_constants.DATE_TIME_FORMAT = '").
append(sdf.toLocalizedPattern()).
append("';\n");
for (String[] ns : JS_NAMESPACES)
{
js.append("alfresco_xforms_constants.").

View File

@@ -27,6 +27,7 @@ package org.alfresco.web.ui.repo.component.property;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -77,7 +78,7 @@ public class UIAssociationEditor extends BaseAssociationEditor
// and place them in a map keyed by the noderef of the child node
if (this.originalAssocs == null)
{
this.originalAssocs = new HashMap<String, Object>();
this.originalAssocs = new LinkedHashMap<String, Object>();
List assocs = (List)node.getAssociations().get(this.associationName);
if (assocs != null)
@@ -98,7 +99,7 @@ public class UIAssociationEditor extends BaseAssociationEditor
if (added == null)
{
// if there aren't any added associations for 'associationName' create a map and add it
added = new HashMap<String, Object>();
added = new LinkedHashMap<String, Object>();
node.getAddedAssociations().put(this.associationName, (Map)added);
}
@@ -107,7 +108,7 @@ public class UIAssociationEditor extends BaseAssociationEditor
if (removed == null)
{
// if there aren't any added associations for 'associationName' create a map and add it
removed = new HashMap<String, Object>();
removed = new LinkedHashMap<String, Object>();
node.getRemovedAssociations().put(this.associationName, (Map)removed);
}
}

View File

@@ -27,6 +27,7 @@ package org.alfresco.web.ui.repo.component.property;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -77,7 +78,7 @@ public class UIChildAssociationEditor extends BaseAssociationEditor
// and place them in a map keyed by the noderef of the child node
if (this.originalAssocs == null)
{
this.originalAssocs = new HashMap<String, Object>();
this.originalAssocs = new LinkedHashMap<String, Object>();
List assocs = (List)node.getChildAssociations().get(this.associationName);
if (assocs != null)
@@ -98,7 +99,7 @@ public class UIChildAssociationEditor extends BaseAssociationEditor
if (added == null)
{
// if there aren't any added associations for 'associationName' create a map and add it
added = new HashMap<String, Object>();
added = new LinkedHashMap<String, Object>();
node.getAddedChildAssociations().put(this.associationName, (Map)added);
}
@@ -107,7 +108,7 @@ public class UIChildAssociationEditor extends BaseAssociationEditor
if (removed == null)
{
// if there aren't any added associations for 'associationName' create a map and add it
removed = new HashMap<String, Object>();
removed = new LinkedHashMap<String, Object>();
node.getRemovedChildAssociations().put(this.associationName, (Map)removed);
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:alf="http://www.alfresco.org"
xmlns:alfdotcom="http://www.eyestreet.com/alfresco" targetNamespace="http://www.eyestreet.com/alfresco"
elementFormDefault="qualified">
<!-- Include navigation simpleType definition -->
<!-- xs:include schemaLocation="/get_nav_simple_type.jsp" / -->
<xs:simpleType name="form-method">
<xs:restriction base="xs:normalizedString">
<xs:enumeration value="get">
<xs:annotation>
<xs:appinfo>
<alf:label>GET</alf:label>
</xs:appinfo>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="post">
<xs:annotation>
<xs:appinfo>
<alf:label>POST</alf:label>
</xs:appinfo>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="form-element-type">
<xs:restriction base="xs:normalizedString">
<xs:enumeration value="text">
<xs:annotation>
<xs:appinfo>
<alf:label>Text</alf:label>
</xs:appinfo>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="textarea">
<xs:annotation>
<xs:appinfo>
<alf:label>Text Area</alf:label>
</xs:appinfo>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="checkbox">
<xs:annotation>
<xs:appinfo>
<alf:label>Checkbox</alf:label>
</xs:appinfo>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="select">
<xs:annotation>
<xs:appinfo>
<alf:label>Selection (Single)</alf:label>
</xs:appinfo>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="selectmulti">
<xs:annotation>
<xs:appinfo>
<alf:label>Selection (Multiple)</alf:label>
</xs:appinfo>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="form-element">
<xs:sequence>
<xs:element name="id" type="xs:normalizedString" />
<xs:element name="type" type="alfdotcom:form-element-type" />
<xs:element name="label" type="xs:normalizedString" />
<xs:element name="description" type="xs:normalizedString" minOccurs="0" />
<xs:element name="default-value" type="xs:normalizedString" minOccurs="0" />
<xs:element name="select-values" type="xs:normalizedString" minOccurs="0" />
<xs:element name="required" type="xs:boolean" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="form-element-hidden">
<xs:sequence>
<xs:element name="id" type="xs:normalizedString" />
<xs:element name="value" type="xs:normalizedString" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="form-section">
<xs:sequence>
<xs:element name="section-title" type="xs:normalizedString" minOccurs="0" />
<xs:element name="section-text" type="xs:anyType" minOccurs="0" />
<xs:element name="form-elements" type="alfdotcom:form-element" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:element name="web-form">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:normalizedString">
<xs:annotation>
<xs:appinfo>
<alf:label>Form ID</alf:label>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="title" type="xs:normalizedString" />
<xs:element name="description" type="xs:anyType" minOccurs="0" />
<xs:element name="action" type="xs:normalizedString" />
<xs:element name="method" type="alfdotcom:form-method" default="post" />
<xs:element name="submit-text" type="xs:normalizedString" minOccurs="0" />
<!-- xs:element name="section" type="alfdotcom:navigation" / -->
<xs:element name="enabled" type="xs:boolean" default="true" />
<xs:element name="sections" type="alfdotcom:form-section" minOccurs="1" maxOccurs="unbounded" />
<xs:element name="hidden-fields" type="alfdotcom:form-element-hidden" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -1,17 +1,28 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:complexType name="repeat-simple">
<xs:complexType name="repeat-min1">
<xs:sequence>
<xs:element name="not-repeated" type="xs:normalizedString" minOccurs="1" maxOccurs="1" default="nr"/>
<xs:element name="one-to-one" type="xs:normalizedString" minOccurs="1" maxOccurs="1"/>
<xs:element name="zero-to-inf" type="xs:normalizedString" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="one-to-inf" type="xs:normalizedString" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="repeat-min0">
<xs:sequence>
<xs:element name="not-repeated" type="xs:normalizedString" minOccurs="1" maxOccurs="1" default="nr"/>
<xs:element name="zero-to-one" type="xs:normalizedString" minOccurs="0" maxOccurs="1"/>
<xs:element name="zero-to-inf" type="xs:normalizedString" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="one-to-inf" type="xs:normalizedString" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="repeat-nested">
<xs:complexType>
<xs:sequence>
<xs:element name="repeat-simple" type="repeat-simple" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="not-repeated" type="xs:normalizedString" minOccurs="1" maxOccurs="1"/>
<xs:element name="not-repeated" type="xs:normalizedString" minOccurs="1" maxOccurs="1" default="nr"/>
<xs:element name="repeat-simple-min-0-min1" type="repeat-min1" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="repeat-simple-min-1-min0" type="repeat-min0" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>

View File

@@ -138,6 +138,7 @@
<xs:element name="date_and_time_components">
<xs:complexType>
<xs:sequence>
<xs:element name="date_and_time" type="xs:datetime"/>
<xs:element name="date" type="xs:date"/>
<xs:element name="time" type="xs:time"/>
<xs:element name="day" type="xs:gDay"/>

View File

@@ -224,3 +224,8 @@
line-height: 20px;
min-width: 100px;
}
.xformsGhostText
{
color: grey;
}

View File

@@ -34,7 +34,7 @@
<nobr><h:outputText styleClass="mainTitle" value="#{msg.title_admin_node_browser}"/></nobr>
</td>
<td width="100%" align="right">
<h:commandButton value="#{msg.close}" action="adminConsole" />
<h:commandButton value="#{msg.close}" action="dialog:close" />
</td>
</tr>
</table>

View File

@@ -13,14 +13,8 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
////////////////////////////////////////////////////////////////////////////////
// XForms user interface
//
@@ -35,15 +29,17 @@
//
// Initiliaze dojo requirements, tinymce, and add a hook to load the xform.
////////////////////////////////////////////////////////////////////////////////
djConfig.bindEncoding = "UTF-8";
dojo.require("dojo.debug.console");
dojo.require("dojo.date.common");
dojo.require("dojo.widget.DebugConsole");
dojo.require("dojo.widget.DatePicker");
dojo.require("dojo.widget.TimePicker");
dojo.require("dojo.widget.Button");
dojo.require("dojo.widget.Slider");
dojo.require("dojo.debug.console");
dojo.require("dojo.lang.assert");
dojo.require("dojo.lfx.html");
dojo.require("dojo.widget.Button");
dojo.require("dojo.widget.DatePicker");
dojo.require("dojo.widget.DebugConsole");
dojo.require("dojo.widget.Slider");
dojo.require("dojo.widget.TimePicker");
dojo.hostenv.writeIncludes();
function _xforms_init()
@@ -332,7 +328,7 @@ dojo.declare("alfresco.xforms.Widget",
/** Sets the widget's initial value. */
setInitialValue: function(value, forceCommit)
{
this.initialValue =
this._initialValue =
(typeof value == "string" && value.length == 0 ? null : value);
if (forceCommit)
{
@@ -346,32 +342,35 @@ dojo.declare("alfresco.xforms.Widget",
*/
getInitialValue: function()
{
if (typeof this.initialValue != "undefined")
if (typeof this._initialValue != "undefined")
{
return this.initialValue;
return this._initialValue;
}
var xpath = this._getXPathInInstanceDocument();
var d = this.xformsNode.ownerDocument;
var contextNode = this.xform.getInstance();
dojo.debug("locating " + xpath + " in " + contextNode.nodeName);
var result = _evaluateXPath("/" + xpath,
this.xform.getInstance(),
XPathResult.FIRST_ORDERED_NODE_TYPE);
if (!result)
this._initialValue = _evaluateXPath("/" + xpath,
this.xform.getInstance(),
XPathResult.FIRST_ORDERED_NODE_TYPE);
if (!this._initialValue)
{
dojo.debug("unable to resolve xpath /" + xpath + " for " + this.id);
return null;
this._initialValue = null;
}
result = (result.nodeType == dojo.dom.ELEMENT_NODE
? dojo.dom.textContent(result)
: result.nodeValue);
if (typeof result == "string" && result.length == 0)
else
{
result = null;
this._initialValue = (this._initialValue.nodeType == dojo.dom.ELEMENT_NODE
? dojo.dom.textContent(this._initialValue)
: this._initialValue.nodeValue);
if (typeof this._initialValue == "string" && this._initialValue.length == 0)
{
this._initialValue = null;
}
dojo.debug("resolved xpath " + xpath + " to " + this._initialValue);
}
dojo.debug("resolved xpath " + xpath + " to " + result);
return result;
return this._initialValue;
},
/** Produces an xpath to the model node within the instance data document. */
@@ -667,7 +666,7 @@ dojo.declare("alfresco.xforms.NumericalRange",
alfresco.xforms.Widget,
function(xform, xformsNode)
{
this.fractionDigits = (this.xformsNode.hasAttribute(alfresco_xforms_constants.ALFRESCO_PREFIX + ":fractionDigits")
this.fractionDigits = (_hasAttribute(this.xformsNode, alfresco_xforms_constants.ALFRESCO_PREFIX + ":fractionDigits")
? Number(this.xformsNode.getAttribute(alfresco_xforms_constants.ALFRESCO_PREFIX + ":fractionDigits"))
: -1);
},
@@ -742,7 +741,10 @@ dojo.declare("alfresco.xforms.NumericalRange",
_hSlider_valueChangedHandler: function(value)
{
value = Math.round(value * Math.pow(10, this.fractionDigits)) / Math.pow(10, this.fractionDigits);
if (this.fractionDigits >= 0)
{
value = Math.round(value * Math.pow(10, this.fractionDigits)) / Math.pow(10, this.fractionDigits);
}
this.currentValueDiv.replaceChild(document.createTextNode("Value: " + value),
this.currentValueDiv.firstChild);
if (!this.widget._isDragInProgress)
@@ -987,10 +989,18 @@ dojo.declare("alfresco.xforms.AbstractSelectWidget",
var valid = true;
if (binding.constraint)
{
valid = _evaluateXPath(binding.constraint, value, XPathResult.BOOLEAN_TYPE);
dojo.debug("evaludated constraint " + binding.constraint +
" on " + dojo.dom.textContent(value) +
" to " + valid);
if (!dojo.render.html.ie)
{
valid = _evaluateXPath(binding.constraint, value, XPathResult.BOOLEAN_TYPE);
dojo.debug("evaludated constraint " + binding.constraint +
" on " + dojo.dom.textContent(value) +
" to " + valid);
}
else
{
valid = !(dojo.dom.textContent(value) == dojo.dom.textContent(label) &&
dojo.dom.textContent(value).match(/^\[.+\]$/));
}
}
result.push({
id: value.getAttribute("id"),
@@ -1356,8 +1366,47 @@ dojo.declare("alfresco.xforms.DatePicker",
alfresco.xforms.Widget,
function(xform, xformsNode)
{
this._noValueSet = (alfresco_xforms_constants.resources["eg"] + " " +
dojo.date.format(new Date(),
{datePattern: alfresco_xforms_constants.DATE_FORMAT,
selector: 'dateOnly'}));
},
{
_createPicker: function()
{
var datePickerDiv = document.createElement("div");
this.domNode.parentNode.appendChild(datePickerDiv);
var dp_initial_value = this.getValue() || dojo.date.toRfc3339(new Date());
this.widget.picker = dojo.widget.createWidget("DatePicker",
{
value: dp_initial_value
},
datePickerDiv);
this.domContainer.style.height =
Math.max(this.widget.picker.domNode.offsetHeight +
this.widget.offsetHeight +
dojo.html.getMargin(this.domNode.parentNode).height,
20) + "px";
dojo.event.connect(this.widget.picker,
"onValueChanged",
this,
this._datePicker_valueChangedHandler);
},
_destroyPicker: function()
{
if (this.widget.picker)
{
this.domNode.parentNode.removeChild(this.widget.picker.domNode);
this.widget.picker = null;
this.domContainer.style.height =
Math.max(this.widget.offsetHeight +
dojo.html.getMargin(this.domNode.parentNode).height,
20) + "px";
}
},
/////////////////////////////////////////////////////////////////
// overridden methods
@@ -1365,32 +1414,36 @@ dojo.declare("alfresco.xforms.DatePicker",
render: function(attach_point)
{
var initial_value = this.getInitialValue() || "";
var initial_value = this.getInitialValue();
attach_point.appendChild(this.domNode);
this.widget = document.createElement("input");
this.widget.setAttribute("id", this.id + "-widget");
this.widget.setAttribute("type", "text");
this.widget.setAttribute("value", initial_value);
if (initial_value)
{
var jsDate = dojo.date.fromRfc3339(initial_value);
this.widget.setAttribute("value",
dojo.date.format(jsDate,
{datePattern: alfresco_xforms_constants.DATE_FORMAT,
selector: 'dateOnly'}));
}
else
{
this.widget.setAttribute("value", this._noValueSet);
dojo.html.addClass(this.widget, "xformsGhostText");
}
this.domNode.appendChild(this.widget);
var expandoImage = document.createElement("img");
expandoImage.setAttribute("src", alfresco_xforms_constants.WEBAPP_CONTEXT + "/images/icons/action.gif");
expandoImage.align = "absmiddle";
expandoImage.style.margin = "0px 5px";
this.domNode.appendChild(expandoImage);
dojo.event.connect(expandoImage, "onclick", this, this._expando_clickHandler);
dojo.event.connect(this.widget, "onfocus", this, this._dateTextBox_focusHandler);
var datePickerDiv = document.createElement("div");
attach_point.appendChild(datePickerDiv);
var dp_initial_value = (initial_value
? initial_value
: dojo.date.toRfc3339(new Date()));
this.widget.picker = dojo.widget.createWidget("DatePicker",
{
isHidden: true,
value: dp_initial_value
},
datePickerDiv);
this.widget.picker.hide();
dojo.event.connect(this.widget.picker,
"onValueChanged",
this,
this._datePicker_valueChangedHandler);
dojo.event.connect(this.widget, "onchange", this, this._dateTextBox_changeHandler);
},
setValue: function(value, forceCommit)
@@ -1402,16 +1455,29 @@ dojo.declare("alfresco.xforms.DatePicker",
else
{
alfresco.xforms.DatePicker.superclass.setValue.call(this, value, forceCommit);
this.widget.setAttribute("value", value);
this.widget.picker.setDate(value);
var jsDate = dojo.date.fromRfc3339(value);
this.widget.value = dojo.date.format(jsDate,
{datePattern: alfresco_xforms_constants.DATE_FORMAT,
selector: 'dateOnly'});
dojo.html.removeClass(this.widget, "xformsGhostText");
}
},
getValue: function()
{
return (this.widget.value == null || this.widget.value.length == 0
? null
: this.widget.value);
if (this.widget.value == null ||
this.widget.value.length == 0 ||
this.widget.value == this._noValueSet)
{
return null;
}
else
{
var jsDate = dojo.date.parse(this.widget.value,
{datePattern: alfresco_xforms_constants.DATE_FORMAT,
selector: 'dateOnly'});
return dojo.date.toRfc3339(jsDate, "dateOnly");
}
},
/////////////////////////////////////////////////////////////////
@@ -1420,24 +1486,32 @@ dojo.declare("alfresco.xforms.DatePicker",
_dateTextBox_focusHandler: function(event)
{
dojo.html.hide(this.widget);
this.widget.picker.show();
this.domContainer.style.height =
Math.max(this.widget.picker.domNode.offsetHeight +
dojo.html.getMargin(this.domNode.parentNode).height,
20) + "px";
this._destroyPicker();
},
_dateTextBox_changeHandler: function(event)
{
this._commitValueChange();
},
_datePicker_valueChangedHandler: function(date)
{
this.widget.picker.hide();
dojo.html.show(this.widget);
this.domContainer.style.height =
Math.max(this.domNode.parentNode.offsetHeight +
dojo.html.getMargin(this.domNode.parentNode).height,
20) + "px";
this.widget.value = dojo.date.toRfc3339(date, "dateOnly");
var rfcDate = dojo.date.toRfc3339(date, "dateOnly");
this._destroyPicker();
this.setValue(rfcDate);
this._commitValueChange();
},
_expando_clickHandler: function()
{
if (this.widget.picker)
{
this._destroyPicker();
}
else
{
this._createPicker();
}
}
});
@@ -1446,8 +1520,55 @@ dojo.declare("alfresco.xforms.TimePicker",
alfresco.xforms.Widget,
function(xform, xformsNode)
{
this._noValueSet = (alfresco_xforms_constants.resources["eg"] + " " +
dojo.date.format(new Date(),
{timePattern: alfresco_xforms_constants.TIME_FORMAT,
selector: "timeOnly"}));
this._xformsFormat = "HH:mm:ss";
},
{
/** */
_createPicker: function()
{
var timePickerDiv = document.createElement("div");
this.domNode.appendChild(timePickerDiv);
var jsDate = (this.getValue()
? dojo.date.parse(this.getValue(),
{timePattern: this._xformsFormat,
selector: "timeOnly"})
: new Date());
this.widget.picker = dojo.widget.createWidget("TimePicker",
{
value: jsDate
},
timePickerDiv);
this.widget.picker.anyTimeContainerNode.innerHTML = "";
// don't let it float - it screws up layout somehow
this.widget.picker.domNode.style.cssFloat = "none";
this.domContainer.style.height =
Math.max(this.widget.picker.domNode.offsetHeight +
this.widget.offsetHeight +
dojo.html.getMargin(this.domNode.parentNode).height,
20) + "px";
dojo.event.connect(this.widget.picker,
"onValueChanged",
this,
this._timePicker_valueChangedHandler);
},
_destroyPicker: function()
{
if (this.widget.picker)
{
this.domNode.removeChild(this.widget.picker.domNode);
this.widget.picker = null;
this.domContainer.style.height =
Math.max(this.widget.offsetHeight +
dojo.html.getMargin(this.domNode.parentNode).height,
20) + "px";
}
},
/////////////////////////////////////////////////////////////////
// overridden methods
@@ -1455,37 +1576,37 @@ dojo.declare("alfresco.xforms.TimePicker",
render: function(attach_point)
{
var initial_value = this.getInitialValue() || "";
var initial_value = this.getInitialValue();
attach_point.appendChild(this.domNode);
this.widget = document.createElement("div");
// this.widget.setAttribute("id", this.id + "-widget");
this.domNode.appendChild(this.widget);
this.widget = document.createElement("input");
this.widget.setAttribute("id", this.id + "-widget");
this.widget.setAttribute("type", "text");
if (initial_value)
{
initial_value = initial_value.split(":");
var date = new Date();
date.setHours(initial_value[0]);
date.setMinutes(initial_value[1]);
initial_value = dojo.widget.TimePicker.util.toRfcDateTime(date);
var jsDate = dojo.date.parse(initial_value, {timePattern: this._xformsFormat, selector: "timeOnly"});
this.widget.setAttribute("value",
dojo.date.format(jsDate,
{timePattern: alfresco_xforms_constants.TIME_FORMAT,
selector: "timeOnly"}));
}
else
{
this.widget.setAttribute("value", this._noValueSet);
dojo.html.addClass(this.widget, "xformsGhostText");
}
this.domNode.appendChild(this.widget);
this.widget.picker = dojo.widget.createWidget("TimePicker",
{
widgetId: this.id + "-widget",
storedTime: initial_value
},
this.widget);
this.widget.picker.anyTimeContainerNode.innerHTML = "";
var expandoImage = document.createElement("img");
expandoImage.setAttribute("src", alfresco_xforms_constants.WEBAPP_CONTEXT + "/images/icons/action.gif");
expandoImage.align = "absmiddle";
expandoImage.style.margin = "0px 5px";
// don't let it float - it screws up layout somehow
this.widget.picker.domNode.style.cssFloat = "none";
this.domNode.style.height = dojo.html.getMarginBox(this.widget.picker.domNode).height + "px";
dojo.event.connect(this.widget.picker,
"onSetTime",
this,
this._timePicker_setTimeHandler);
this.domNode.appendChild(expandoImage);
dojo.event.connect(expandoImage, "onclick", this, this._expando_clickHandler);
dojo.event.connect(this.widget, "onfocus", this, this._timeTextBox_focusHandler);
dojo.event.connect(this.widget, "onchange", this, this._timeTextBox_changeHandler);
},
setValue: function(value, forceCommit)
@@ -1497,22 +1618,263 @@ dojo.declare("alfresco.xforms.TimePicker",
else
{
alfresco.xforms.TimePicker.superclass.setValue.call(this, value, forceCommit);
this.widget.picker.setDateTime(value);
var jsDate = dojo.date.parse(value, {timePattern: this._xformsFormat, selector: "timeOnly"});
this.widget.value = dojo.date.format(jsDate,
{timePattern: alfresco_xforms_constants.TIME_FORMAT,
selector: "timeOnly"});
dojo.html.removeClass(this.widget, "xformsGhostText");
}
},
getValue: function()
{
return dojo.date.strftime(this.widget.picker.time, "%H:%M:00");
if (this.widget.value == null ||
this.widget.value.length == 0 ||
this.widget.value == this._noValueSet)
{
return null;
}
else
{
var jsDate = dojo.date.parse(this.widget.value,
{timePattern: alfresco_xforms_constants.TIME_FORMAT,
selector: "timeOnly"});
return dojo.date.format(jsDate, {timePattern: this._xformsFormat, selector: "timeOnly"});
}
},
/////////////////////////////////////////////////////////////////
// DOM event handlers
/////////////////////////////////////////////////////////////////
_timePicker_setTimeHandler: function(event)
_timeTextBox_focusHandler: function(event)
{
this._destroyPicker();
},
_timeTextBox_changeHandler: function(event)
{
this._commitValueChange();
},
_timePicker_valueChangedHandler: function(date)
{
var xfDate = dojo.date.format(date, {timePattern: this._xformsFormat, selector: "timeOnly"});
this.setValue(xfDate);
this._commitValueChange();
},
_expando_clickHandler: function()
{
if (this.widget.picker)
{
this._destroyPicker();
}
else
{
this._createPicker();
}
}
});
/** The date time picker widget which handles xforms widget xf:input with type xf:datetime */
dojo.declare("alfresco.xforms.DateTimePicker",
alfresco.xforms.Widget,
function(xform, xformsNode)
{
this._noValueSet = (alfresco_xforms_constants.resources["eg"] + " " +
dojo.date.format(new Date(),
{datePattern: alfresco_xforms_constants.DATE_TIME_FORMAT,
selector: "dateOnly"}));
},
{
/** */
_createPicker: function()
{
this._pickerDiv = document.createElement("div");
this._pickerDiv.style.position = "relative";
this._pickerDiv.style.width = this.widget.offsetWidth + "px";
this.domNode.appendChild(this._pickerDiv);
var datePickerDiv = document.createElement("div");
datePickerDiv.style.position = "absolute";
datePickerDiv.style.left = "0px";
datePickerDiv.style.top = "0px";
this._pickerDiv.appendChild(datePickerDiv);
var dp_initial_value = this.getValue() || dojo.date.toRfc3339(new Date());
this.widget.datePicker = dojo.widget.createWidget("DatePicker",
{
value: dp_initial_value
},
datePickerDiv);
var timePickerDiv = document.createElement("div");
timePickerDiv.style.position = "absolute";
timePickerDiv.style.right = "0px";
timePickerDiv.style.top = "0px";
this._pickerDiv.appendChild(timePickerDiv);
var jsDate = this.getValue() ? dojo.date.fromRfc3339(this.getValue()) : new Date();
this.widget.timePicker = dojo.widget.createWidget("TimePicker",
{
value: jsDate
},
timePickerDiv);
this.widget.timePicker.anyTimeContainerNode.innerHTML = "";
// don't let it float - it screws up layout somehow
this.widget.timePicker.domNode.style.cssFloat = "none";
this._pickerDiv.style.height = Math.max(this.widget.timePicker.domNode.offsetHeight,
this.widget.datePicker.domNode.offsetHeight);
this.domContainer.style.height =
Math.max(this._pickerDiv.offsetHeight +
this.widget.offsetHeight +
dojo.html.getMargin(this.domNode.parentNode).height,
20) + "px";
dojo.event.connect(this.widget.datePicker,
"onValueChanged",
this,
this._datePicker_valueChangedHandler);
dojo.event.connect(this.widget.timePicker,
"onValueChanged",
this,
this._timePicker_valueChangedHandler);
},
_destroyPicker: function()
{
if (this._pickerDiv)
{
this.domNode.removeChild(this._pickerDiv);
this.widget.datePicker = null;
this.widget.timePicker = null;
this._pickerDiv = null;
this.domContainer.style.height =
Math.max(this.widget.offsetHeight +
dojo.html.getMargin(this.domNode.parentNode).height,
20) + "px";
}
},
/////////////////////////////////////////////////////////////////
// overridden methods
/////////////////////////////////////////////////////////////////
render: function(attach_point)
{
var initial_value = this.getInitialValue();
attach_point.appendChild(this.domNode);
this.widget = document.createElement("input");
this.widget.setAttribute("id", this.id + "-widget");
this.widget.setAttribute("type", "text");
if (initial_value)
{
var jsDate = dojo.date.fromRfc3339(initial_value);
this.widget.setAttribute("value",
dojo.date.format(jsDate,
{timePattern: alfresco_xforms_constants.DATE_TIME_FORMAT,
selector: "timeOnly"}));
}
else
{
this.widget.setAttribute("value", this._noValueSet);
dojo.html.addClass(this.widget, "xformsGhostText");
}
this.domNode.appendChild(this.widget);
this.widget.style.width = (3 * this.widget.offsetWidth) + "px";
var expandoImage = document.createElement("img");
expandoImage.setAttribute("src", alfresco_xforms_constants.WEBAPP_CONTEXT + "/images/icons/action.gif");
expandoImage.align = "absmiddle";
expandoImage.style.margin = "0px 5px";
this.domNode.appendChild(expandoImage);
dojo.event.connect(expandoImage, "onclick", this, this._expando_clickHandler);
dojo.event.connect(this.widget, "onfocus", this, this._dateTimeTextBox_focusHandler);
dojo.event.connect(this.widget, "onchange", this, this._dateTimeTextBox_changeHandler);
},
setValue: function(value, forceCommit)
{
if (!this.widget)
{
this.setInitialValue(value, forceCommit);
}
else
{
alfresco.xforms.DateTimePicker.superclass.setValue.call(this, value, forceCommit);
var jsDate = dojo.date.fromRfc3339(value);
this.widget.value = dojo.date.format(jsDate,
{datePattern: alfresco_xforms_constants.DATE_TIME_FORMAT,
selector: "dateOnly"});
dojo.html.removeClass(this.widget, "xformsGhostText");
}
},
getValue: function()
{
if (this.widget.value == null ||
this.widget.value.length == 0 ||
this.widget.value == this._noValueSet)
{
return null;
}
else
{
var jsDate = dojo.date.parse(this.widget.value,
{datePattern: alfresco_xforms_constants.DATE_TIME_FORMAT,
selector: "dateOnly"});
return dojo.date.toRfc3339(jsDate);
}
},
/////////////////////////////////////////////////////////////////
// DOM event handlers
/////////////////////////////////////////////////////////////////
_dateTimeTextBox_focusHandler: function(event)
{
this._destroyPicker();
},
_dateTimeTextBox_changeHandler: function(event)
{
this._commitValueChange();
},
_timePicker_valueChangedHandler: function(date)
{
var value = this.getValue() ? dojo.date.fromRfc3339(this.getValue()) : new Date();
value.setHours(date.getHours());
value.setMinutes(date.getMinutes());
value = dojo.date.toRfc3339(value);
this.setValue(value);
this._commitValueChange();
},
_datePicker_valueChangedHandler: function(date)
{
var value = this.getValue() ? dojo.date.fromRfc3339(this.getValue()) : new Date();
value.setYear(date.getYear());
value.setMonth(date.getMonth());
value.setDate(date.getDate());
value = dojo.date.toRfc3339(value);
this.setValue(value);
this._commitValueChange();
},
_expando_clickHandler: function()
{
if (this._pickerDiv)
{
this._destroyPicker();
}
else
{
this._createPicker();
}
}
});
@@ -3262,6 +3624,7 @@ dojo.declare("alfresco.xforms.XForm",
case "gMonthDay":
return new alfresco.xforms.MonthDayPicker(this, xformsNode);
case "dateTime":
return new alfresco.xforms.DateTimePicker(this, xformsNode);
case "yearMonthDuration":
case "dayTimeDuration":
// number types
@@ -3486,6 +3849,7 @@ dojo.declare("alfresco.xforms.XForm",
_handleEventLog: function(events)
{
var prototypeClones = [];
var generatedIds = null;
for (var i = 0; i < events.childNodes.length; i++)
{
if (events.childNodes[i].nodeType != dojo.dom.ELEMENT_NODE)
@@ -3592,6 +3956,8 @@ dojo.declare("alfresco.xforms.XForm",
dojo.debug("applying id " + xfe.targetId +
" to " + node.nodeName + "(" + originalId + ")");
node.setAttribute("id", xfe.targetId);
generatedIds = generatedIds || new Object();
generatedIds[xfe.targetId] = originalId;
if (prototypeClones.length != 1)
{
var e = _findElementById(prototypeClones[prototypeClones.length - 2], originalId);
@@ -3607,6 +3973,33 @@ dojo.declare("alfresco.xforms.XForm",
var position = Number(xfe.properties["position"]) - 1;
var originalId = xfe.properties["originalId"];
var clone = prototypeClones.pop();
// walk all nodes of the clone and ensure that they have generated ids.
// those that do not are nested repeats that should not be added
dojo.lang.assert(clone.getAttribute("id") in generatedIds,
"expected clone id " + clone.getAttribute("id") +
" to be a generated id");
function _removeNonGeneratedChildNodes(node, ids)
{
var child = node.firstChild;
while (child)
{
var next = child.nextSibling;
if (child.nodeType == dojo.dom.ELEMENT_NODE)
{
if (child.getAttribute("id") in ids)
{
_removeNonGeneratedChildNodes(child, ids);
}
else
{
node.removeChild(child);
}
}
child = next;
}
};
_removeNonGeneratedChildNodes(clone, generatedIds);
if (prototypeClones.length != 0)
{
dojo.debug("using parentClone " + prototypeClones.peek().getAttribute("id") +