FluidTYPO3 duplicated Content Modules with Flux Grid at TYPO3 Backend - grid

I'm using TYPO3 7.6with the latest Flux-, VHS- and FluidcontentExtensions (FluidTYPO3). I've wrote a new FLUX-Content Element, a Tab-Container from Zurb Foundation 6.
The element is working fine (frontend), but at backend I have a row with my tabs and also columns .. sth. will dublicated my tabs and the content inside?! Already cleared Cache.
Here's a screenshot. The Tab-Elements will be dublicated, I don't know why?
My FLUX FCE:
<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
xmlns:flux="http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers"
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers">
<f:layout name="Content" />
<f:section name="Configuration">
<flux:form id="tabs" options="{group: 'LLL:typo3conf/ext/myelements/Resources/Private/Language/locallang.xlf:grid.elements'}">
<flux:form.sheet name="tabs">
<flux:form.section name="tabs">
<flux:form.object name="tab">
<flux:field.input name="title" />
<flux:field.input name="class" />
<flux:field.checkbox name="active" />
</flux:form.object>
</flux:form.section>
</flux:form.sheet>
<flux:grid>
<flux:grid.row>
<f:if condition="{tabs}">
<f:for each="{tabs}" as="tab" iteration="iteration">
<flux:form.content name="content.{iteration.index}" label="Tab {iteration.cycle}" />
</f:for>
</f:if>
</flux:grid.row>
</flux:grid>
</flux:form>
</f:section>
<f:section name="Preview">
<flux:widget.grid />
</f:section>
<f:section name="Main">
<f:render section="Tabs" arguments="{_all}" />
<div class="tabs-content" data-tabs-content="tabs-{record.uid}">
<f:if condition="{tabs}">
<f:for each="{tabs}" as="tab" iteration="iteration">
<div class="tabs-panel {f:if(condition: '{tab.tab.active} == 1', then: 'is-active')}" id="panel-{record.uid}-{iteration.index}">
<flux:content.render area="content.{iteration.index}" />
</div>
</f:for>
</f:if>
</div>
</f:section>
<f:section name="Tabs">
<f:if condition="{tabs}">
<ul class="tabs" data-tabs id="tabs-{record.uid}">
<f:for each="{tabs}" as="tab" iteration="iteration">
<li class="tabs-title {f:if(condition: '{tab.tab.active} == 1', then: 'is-active')}">
{tab.tab.title}
</li>
</f:for>
</ul>
</f:if>
</f:section>
</div>

This is the problem:
<flux:widget.grid />
According to Release Notes of flux 7.2:
Preview Widget replaced
We have replaced the way Flux generates previews when a Grid is
involved. Before, Flux would render the Grid from the Fluid template
file which means the template had to be parsed (or loaded from
compiled cache) and then rendered, involving a significant amount of
processing. The content element container areas are now rendered by a
special View class, significantly increasing performance when working
with multiple nested elements.
The new behaviour:
Renders a Grid as content element container in the page module if your
template defines one, regardless of whether or not you have a Preview
section.
Deprecates flux:widget.grid which no longer has any function.
Removes all support for setting the Fluid template used to render the
Grid.
Basically, we sacrifice the rarely used template replacement
feature for increased performance in very frequently executed code.
So, simply remove complete Preview section from a template.

Thank you Viktor.
It's necessary to delete all flux.grid-stuff from yout template.
The whole preview section and some grid/rows at the configuration section.
That's the correct tab-template for fluxand zurb foundation:
<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
xmlns:flux="http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers"
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers">
<f:layout name="Content" />
<f:section name="Configuration">
<flux:form id="Tabs" options="{group: 'LLL:typo3conf/ext/customerproject/Resources/Private/Language/locallang.xlf:grid.elements'}">
<flux:form.sheet name="tabs">
<flux:form.section name="tabs">
<flux:form.object name="tab">
<flux:field.input name="title" />
<flux:field.input name="class" />
<flux:field.checkbox name="active" />
</flux:form.object>
</flux:form.section>
</flux:form.sheet>
<f:if condition="{tabs}">
<f:for each="{tabs}" as="tab" iteration="iteration">
<flux:form.content name="content.{iteration.index}" label="Tab {iteration.cycle}" />
</f:for>
</f:if>
</flux:form>
</f:section>
<f:section name="Main">
<div class="flux grid01Tabs">
<f:render section="Tabs" arguments="{_all}" />
<div class="tabs-content" data-tabs-content="tabs-{record.uid}">
<f:if condition="{tabs}">
<f:for each="{tabs}" as="tab" iteration="iteration">
<div class="tabs-panel {f:if(condition: '{tab.tab.active} == 1', then: 'is-active')}" id="panel-{record.uid}-{iteration.index}">
<flux:content.render area="content.{iteration.index}" />
</div>
</f:for>
</f:if>
</div>
</div><!-- / tabWrap -->
</f:section>
<f:section name="Tabs">
<f:if condition="{tabs}">
<ul class="tabs" data-tabs id="tabs-{record.uid}">
<f:for each="{tabs}" as="tab" iteration="iteration">
<li class="tabs-title {f:if(condition: '{tab.tab.active} == 1', then: 'is-active')}">
{tab.tab.title}
</li>
</f:for>
</ul>
</f:if>
</f:section>
</div>

Related

Task edit document preview component Alfresco

First question:
I want to implement a preview of the document in the form of the task-edit of the workflows... How can I do this? I try to adapt the document-details.xml and document-details.ftl to workflow-details.xml and workflow-details.ftl but not works. I tried to copy the components that have web-preview of the document-details files to workflow-details. Any hint to make this?
I have this in workflow-details.ftl:
<#include "include/alfresco-template.ftl" />
<#templateHeader>
<#script type="text/javascript" src="${url.context}/res/modules/documentlibrary/doclib-actions.js" group="document-details"/>
<#link rel="stylesheet" type="text/css" href="${url.context}/res/components/document-details/document-details-panel.css" group="document-details"/>
<#link rel="stylesheet" type="text/css" href="${url.context}/res/components/workflow/task-edit-header.css" group="workflow-details"/>
<#templateHtmlEditorAssets />
</#>
<#templateBody>
<#markup id="alf-hd">
<div id="alf-hd">
<#region scope="global" id="share-header" chromeless="true"/>
<#region id="title" scope="template"/>
<#if page.url.args.nodeRef??>
<#region id="path" scope="template"/>
</#if>
</div>
</#>
<#markup id="bd">
<div id="bd">
<div class="share-form">
<#region id="data-header" scope="page" />
<div class="yui-gc">
<div class="yui-u first">
<#if (config.scoped['WorkflowDetails']['workflow-details'].getChildValue('display-web-preview') == "true")>
<#region id="web-preview" scope="template"/>
</#if>
</div>
</div>
<#region id="data-form" scope="page" />
<#region id="data-actions" scope="page" />
</div>
</div>
</#>
</#>
<#templateFooter>
<#markup id="alf-ft">
<div id="alf-ft">
<#region id="footer" scope="global"/>
<#region id="data-loader" scope="page" />
</div>
</#>
</#>
In workflow-details.xml I add this component:
<component>
<region-id>web-preview</region-id>
<sub-components>
<sub-component id="default">
<evaluations>
<evaluation>
<evaluators>
<evaluator type="config.component.evaluator">
<params>
<element>WorkflowDetails/workflow-details/display-web-preview</element>
</params>
</evaluator>
</evaluators>
<url>/components/preview/web-preview</url>
<properties>
<nodeRef>{nodeRef}</nodeRef>
<api>api</api>
<proxy>alfresco</proxy>
<dependencyGroup>workflow-details</dependencyGroup>
</properties>
</evaluation>
</evaluations>
</sub-component>
</sub-components>
</component>
This not shows the web-preview, only creates:
<div id="template_x002e_web-preview_x002e_workflow-details">
<div id="template_x002e_web-preview_x002e_workflow-details_x0023_default"> </div>
</div>
What's my error?
Second question:
In the preview of the Aikau page I get: Warning: unimplemented annotation type: Widget signature in the console of the firebug of the Mozilla Firefox and the document is displayed without the digital signatures... But, for example, if I upload a document with a digital signature, I can see the document with the signature in the page of document-details of the document. The preview of this page is different? How can I implement this preview?
The main problem you have here is that the you don't have any nodeRef request parameter when viewing a workflow task (this is mapped to the {nodeRef} token that is assigned to the <nodeRef> element in the web-preview component. As a result the web-preview WebScript will not have a node to render.
You are either going to need to make a customization such that the nodeRef of the attached file is included as a request parameter when viewing the workflow task or use your own WebScript (other than the web-preview WebScript) in order to access the nodeRef of the document to preview.
A couple of other things to consider here, is that it is entirely possible to have more than one document assigned to a workflow, so you'd need to handle that scenario (i.e. which document is previewed, or how to preview all documents).
I don't think that this is going to be a simple customization though.
It can be easier to just use the javascript previewer that is integrated in share (pdf.js). If you use directly the javascript library, it shouldn't be difficult to open a preview.
There are examples in the official site of the project: pdf.js
you can use the share webscript to initialise the javascript with the list of urls of the documents attached to the workflow. If the document attached is not a pdf, you will need to use its pdf rendition.
For future references. You can do it as follows (example):
Create Share extension and add the following container to the /src/main/amp/config/alfresco/templates/org/alfresco/workflow-details.ftl:
<div class="yui-gc">
<div class="yui-u first">
<#if (config.scoped['DocumentDetails']['document-details'].getChildValue('display-web-preview') == "true")>
<#region id="web-preview" scope="template"/>
</#if>
</div>
</div>
Also add the same #templateHeader as in the document-details.ftl. Your workflow-details.ftl will look like this:
<#include "include/alfresco-template.ftl" />
<#templateHeader>
<#script type="text/javascript" src="${url.context}/res/modules/documentlibrary/doclib-actions.js" group="document-details"/>
<#link rel="stylesheet" type="text/css" href="${url.context}/res/components/document-details/document-details-panel.css" group="document-details"/>
<#templateHtmlEditorAssets />
</#>
<#templateBody>
<#markup id="alf-hd">
<div id="alf-hd">
<#region scope="global" id="share-header" chromeless="true"/>
<#region id="title" scope="template"/>
<#if page.url.args.nodeRef??>
<#region id="path" scope="template"/>
</#if>
</div>
</#>
<#markup id="bd">
<div id="bd">
<div class="share-form">
<#region id="data-header" scope="page" />
<#region id="data-form" scope="page" />
<div class="yui-gc">
<div class="yui-u first">
<#if (config.scoped['DocumentDetails']['document-details'].getChildValue('display-web-preview') == "true")>
<#region id="web-preview" scope="template"/>
</#if>
</div>
</div>
<#region id="data-actions" scope="page" />
</div>
</div>
</#>
</#>
<#templateFooter>
<#markup id="alf-ft">
<div id="alf-ft">
<#region id="footer" scope="global"/>
<#region id="data-loader" scope="page" />
</div>
</#>
</#>
Add the WebPreview component to the \src\main\amp\config\alfresco\site-data\template-instances\workflow-details.xml:
<!-- WebPreview -->
<component>
<region-id>web-preview</region-id>
<sub-components>
<sub-component id="default">
<evaluations>
<evaluation>
<evaluators>
<evaluator type="config.component.evaluator">
<params>
<element>DocumentDetails/document-details/display-web-preview</element>
</params>
</evaluator>
</evaluators>
<url>/components/preview/web-preview</url>
<properties>
<nodeRef>{nodeRef}</nodeRef>
<api>api</api>
<proxy>alfresco</proxy>
<dependencyGroup>document-details</dependencyGroup>
</properties>
</evaluation>
</evaluations>
</sub-component>
</sub-components>
</component>
Your workflow-details.xml will look like this:
<?xml version='1.0' encoding='UTF-8'?>
<template-instance>
<template-type>org/alfresco/workflow-details</template-type>
<properties>
<pageFamily>documentlibrary</pageFamily>
</properties>
<components>
<!-- Site Navigation -->
<component>
<region-id>navigation</region-id>
<sub-components>
<sub-component id="default">
<evaluations>
<!-- if referred from my tasks page: Task toolbar -->
<evaluation id="tasks">
<evaluators>
<evaluator type="equals.component.evaluator">
<params>
<referrer>{referrer}</referrer>
<tasks>tasks</tasks>
</params>
</evaluator>
</evaluators>
<url>/components/workflow/task-toolbar</url>
</evaluation>
<!-- if referred from my workflows page: Workflows toolbar -->
<evaluation id="workflows">
<evaluators>
<evaluator type="equals.component.evaluator">
<params>
<referrer>{referrer}</referrer>
<workflows>workflows</workflows>
</params>
</evaluator>
</evaluators>
<url>/components/workflow/workflow-toolbar</url>
</evaluation>
<!-- if in site: Site navigation -->
<evaluation id="site">
<evaluators>
<evaluator type="site.component.evaluator"/>
</evaluators>
<url>/components/navigation/collaboration-navigation</url>
</evaluation>
</evaluations>
</sub-component>
</sub-components>
</component>
<!-- WebPreview -->
<component>
<region-id>web-preview</region-id>
<sub-components>
<sub-component id="default">
<evaluations>
<evaluation>
<evaluators>
<evaluator type="config.component.evaluator">
<params>
<element>DocumentDetails/document-details/display-web-preview</element>
</params>
</evaluator>
</evaluators>
<url>/components/preview/web-preview</url>
<properties>
<nodeRef>{nodeRef}</nodeRef>
<api>api</api>
<proxy>alfresco</proxy>
<dependencyGroup>document-details</dependencyGroup>
</properties>
</evaluation>
</evaluations>
</sub-component>
</sub-components>
</component>
<!-- Path -->
<component>
<region-id>path</region-id>
<sub-components>
<sub-component id="default">
<evaluations>
<!-- if in site: Site title -->
<evaluation id="site">
<evaluators>
<evaluator type="site.component.evaluator"/>
</evaluators>
<url>/components/document-details/path</url>
</evaluation>
<!-- otherwise: Repository title -->
<evaluation id="repo">
<url>/components/document-details/repo/path</url>
</evaluation>
</evaluations>
</sub-component>
</sub-components>
</component>
</components>
</template-instance>
If you want to place the component in an arbitrary region, you may need to use JavaScript, for example:
...
var container = YAHOO.util.Dom.get('user-list');
var web_preview = YAHOO.util.Dom.get('template_x002e_web-preview_x002e_workflow-details_x0023_default');
YAHOO.util.Dom.insertAfter(web_preview, container);
...
The container with ID==user-list I placed in the userdetails.ftl which added to the share-config-custom.xml as follows:
...
<field id="mswf:userDetails" set="userDetails" label="...">
<control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
</field>
...
The result may look as shown below.
Here is an easier solution that handles multiple documents and uses web-preview component:
In your share-config-custom.xml override packageItems field:
<field id="packageItems" set="items">
<control template="/com/yourdomain/components/form/controls/workflow/packageitems.ftl" />
</field>
Control template (/com/yourdomain/components/form/controls/workflow/packageitems.ftl):
<#include "/org/alfresco/components/form/controls/workflow/packageitems.ftl" />
<#assign el>${controlId}-wp</#assign>
<#assign dependencyGroup="web-preview">
<#include "/org/alfresco/components/preview/include/web-preview-css-dependencies.lib.ftl" />
<#include "/org/alfresco/components/preview/include/web-preview-js-dependencies.lib.ftl" />
<div class="yui-g" id="${el}"></div>
<script type="text/javascript">//<![CDATA[
(function(){
var nodeRefs = ("${field.value?html}" || "").split(',');
for (var ni = 0; ni < nodeRefs.length; ni++) {
Alfresco.util.loadWebscript({
url: Alfresco.constants.URL_SERVICECONTEXT + "components/preview/web-preview",
properties: { nodeRef: nodeRefs[ni], htmlid: "${el}-preview-" + ni},
target: "${el}"
});
}
})();
//]]></script>

Spring Security redirects to forbidden page(403)

I am using spring-security on top of spring-mvc application. Few points about the application I am working on.
Home page is login page i.e /users(). Login menu served as HTML dropdown menu.
Implementing userDetailsService() and UserDetails() instead of AuthenticationManager/provider
Required is person to view the home page without any roles.
Current situation :
Redirects it to 403 page mentioned in the entrypoint-ref.
No idea how to redirect it to user.jsp or /users
All examples I can find on net somehow show same stuff which is implementing `AuthenticationManager. Some code :
security-context.xml
<import resource="servlet-context.xml" />
<!-- Global Security settings -->
<security:global-method-security pre-post-annotations="enabled" />
<!-- Spring Security framework settings -->
<security:http pattern="/users" use-expressions="true" auto-config="true" disable-url-rewriting="true" entry-point-ref="formAuthenticationEntryPoint">
<security:session-management>
<security:concurrency-control max-sessions="5" error-if-maximum-exceeded="false"/>
</security:session-management>
<security:intercept-url pattern="/*" requires-channel="any" access="permitAll" />
<security:intercept-url pattern="/**" requires-channel="any" access="permitAll" />
</security:http>
<!-- queries to be run on data -->
<beans:bean id="formAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<bean id="LoginServiceImplementation" class="com.WirTauschen.service.LoginServiceImpl"></bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="userDetailsService" />
</security:authentication-manager>
</beans>
LoginServiceImpl :
#Service("userDetailsService")
public class LoginServiceImpl implements UserDetailsService{
#Autowired private UserDao userDao;
#Autowired private Assembler assembler;
#Override
#Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails userDetails = null;
User user = userDao.findByName(username);
if(user == null) { throw new UsernameNotFoundException("Wrong username or password");} //Never specify which one was it exactly
return assembler.buildUserFromUserEntity(user);
}
}
Login-form(part of hompage HTML code enveloped in user.jsp)
<nav class="col-lg-5 col-md-5 col-sm-5">
<ul class="pull-right">
<li class="purple"><i class="icons icon-user-3"></i> Login
<ul id="login-dropdown" class="box-dropdown">
<li>
<form id="form" action="<c:url value='/login'/>" method="POST">
<div class="box-wrapper">
<h4>LOGIN</h4>
<div class="iconic-input">
<input type="text" placeholder="Username" name="username" id="username" value="">
<i class="icons icon-user-3"></i>
</div>
<div class="iconic-input">
<input type="password" placeholder="Password" name="password" id="password" value="">
<i class="icons icon-lock"></i>
</div>
<input type="checkbox" id="loginremember"> <label for="loginremember">Remember me</label>
<br>
<br>
<div class="pull-left">
<input name="submit" type="submit" class="orange" value="Login">
</div>
<div class="pull-right">
Forgot your password?
<br>
Forgot your username?
<br>
</div>
<br class="clearfix">
</div>
<div class="footer">
<h4 class="pull-left">NEW CUSTOMER?</h4>
<a class="button pull-right" href="create_an_account.html">Create an account</a>
</div>
</form>
</li>
</ul>
</li>
<li><i class="icons icon-lock"></i> Create an Account</li>
</ul>
</nav>
Form-login from security-applicationContext.xml
<security:form-login login-page="/users" default-target-url="/users"/>
Any help would be nice. Never knew spring-security will be nothing but torture.
UPDATE
You have to understand how Spring works: the client tries to get to a protected resource (users page, for example); if he did not login yet, he is being redirected (Spring redirects him) to the login page.
In your Spring beans.xml you declare what is your login page. If you put there "/login.html", you have to make sure that you have this kind of page, with the login form. After the user logs in, Spring will redirect him back to the /users.
Makes sense?
UPDATE II
You can make (like Amazon...) a landing page (e.g. index.html) which is public, meaning users can see it without logging in. Then, there are links there to 'protected resources', and if a user try to click on it and get the protected resource, Spring will redirect him to the login page. If you wanna do that, you put you 'protected resources' under a specific directory (e.g. /secured) and you place there all protected resources HTML/JSP/etc. You configure this in the beans.xml: (note here that 'welcome' page is non-secured, everybody will be able to see it without login)
<sec:http pattern="/welcome" security="none" />
<sec:http authentication-manager-ref="authenticationManager">
<sec:intercept-url pattern="/secure/**" access="ROLE_USER" />

Is it possible to make document picker default to document library in alfresco share?

I have a copy of association.ftl which I use for a control added to the advanced search form in share. Unfortunately when opened the default display is companyhome where as I'd rather have it default to the related site's document library.
I read this wiki and also tried the changing the parentNodeRef value in the javascript to at least add sites to the path to no success.
The share form config control:
<config evaluator="model-type" condition="cm:content">
<forms>
<!-- Search form -->
<form id="search">
<field-visibility>
<show id="cm:name" force="true" />
<show id="space" force="true" />
</field-visibility>
<appearance>
<field id="cm:name" label-id="prop.search.cm_name" />
<field id="space" label-id="prop.search.cm_search_in_folder" >
<control template="/org/alfresco/components/form/controls/space.ftl">
<control-param name="startLocation">{doclib}</control-param>
</control>
</field>
</appearance>
</form>
</forms>
</config>
The freemarker control file :
<#include "common/picker.inc.ftl" />
<#assign controlId = fieldHtmlId + "-cntrl">
<script type="text/javascript">//<![CDATA[
(function()
{
<#renderPickerJS field "picker" />
picker.setOptions(
{
<#if field.control.params.showTargetLink??>
showLinkToTarget: ${field.control.params.showTargetLink},
<#if page?? && page.url.templateArgs.site??>
targetLinkTemplate: "${url.context}/page/site/${page.url.templateArgs.site!""}/document-details?nodeRef={nodeRef}",
<#else>
targetLinkTemplate: "${url.context}/page/document-details?nodeRef={nodeRef}",
</#if>
</#if>
<#if field.control.params.allowNavigationToContentChildren??>
allowNavigationToContentChildren: ${field.control.params.allowNavigationToContentChildren},
</#if>
itemType: "cm:folder",
multipleSelectMode: false,
parentNodeRef: "alfresco://company/home/sites", //<== Not the default path
<#if field.control.params.rootNode??>
rootNode: "${field.control.params.rootNode}",
</#if>
itemFamily: "node",
displayMode: "${field.control.params.displayMode!"items"}"
});
})();
//]]></script>
<div class="form-field">
<#if form.mode == "view">
<div id="${controlId}" class="viewmode-field">
<span class="viewmode-label">${field.label?html}:</span>
<span id="${controlId}-currentValueDisplay" class="viewmode-value current-values"></span>
</div>
<#else>
<label for="${controlId}">${field.label?html}:</label>
<div id="${controlId}" class="object-finder">
<div id="${controlId}-currentValueDisplay" class="current-values"></div>
<input type="hidden" id="${fieldHtmlId}" name="-" value="${field.value?html}" />
<input type="hidden" id="${controlId}-added" name="${field.name}_added" />
<input type="hidden" id="${controlId}-removed" name="${field.name}_removed" />
<div id="${controlId}-itemGroupActions" class="show-picker"></div>
<#renderPickerHTML controlId />
</div>
</#if>
</div>
The wiki is pretty clear on how to do this:
Supply a startLocation as parameter to the picker in the forms-config, since you want to go with the documentLibrary of the site the user searches from I would recommend you to implement a NodeLocator as described in the wiki:
https://wiki.alfresco.com/wiki/NodeLocatorService
In fact that seems to already have been implemented for you and seems to reside in the alfresco source:
http://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/COMMUNITYTAGS/V4.2e/root/projects/repository/source/java/org/alfresco/repo/site/DocLibNodeLocator.java
However I cant find the bean declaration so you might have to add it to your spring-bean definitions (or copy the source to an own implementation) to be able to use it properly.

How to use if="some condition" in ZK template tag

I have a <template> tag in my ZUL file, and I want to use this template when some condition accured (for example, when some LABEL's value change to some text).
Please look at below code... As you can see, "templateStatus" is my label's name, but it did not work.
How can I fix this issue?
<template name="allTaskTemplate" var="allTask" if="templateStatus.value == 'allTask'">
<row>
<label value="" />
<label value="#load(allTask.documentDTO.docTypeDTO.title)"/>
<label value="#load(allTask.documentDTO.docNumber)"/>
<label value="#load(allTask.documentDTO.docDateTime)"/>
<label value="#load(allTask.assignerID)"/>
<label value="#load(allTask.assigneeID)"/>
<label value="#load(allTask.assignDateTime)"/>
<label value="#load(allTask.assignDateTime)"/>
<label value="#load(allTask.assignDateTime)"/>
<label value="#load(allTask.assignDateTime)"/>
<label value="#load(allTask.documentDTO.docTypeStateDTO.stateActionDTO.actionDTO.title)"/>
<label value="#load(allTask.catalogDTO.catalogTypeDTO.title)"/>
</row>
</template>
</grid>
Using an if statement:
<zk if="${vm.type=='foo'}">
<!-- Child components -->
</zk>
<zk if="${vm.type=='check'}">
<!-- Child components -->
</zk>
<zk if="${vm.type=='something'}">
<!-- Child components -->
</zk>
<zk if="${vm.type=='value'}">
<!-- Child components -->
</zk>
See the below example of ZK. You can use conditional templates...
<grid model="#bind(vm.itemList) #template(vm.type eq 'foo'?'template1':'template2')">
<template name="template1">
<!-- child components -->
</template>
<template name="template2">
<!-- child components -->
</template>
</grid>
For more information, you can see the official page of ZK, Collection and Selection.
Se the below code for...
<menubar id="mbar" children="#bind(vm.menuList) #template(empty each.children?'menuitem':'menu')">
<template name="menu" var="menu">
<menu label="#bind(menu.name)">
<menupopup children="#bind(menu.children) #template(empty each.children?'menuitem':'menu')"/>
</menu>
</template>
<template name="menuitem" var="item">
<menuitem label="#bind(item.name)" onClick="#command('menuClicked',node=item)" />
</template>
</menubar>
See the above. Using more than two templates you can do something like this. I don't know your requirement, but you can use the above logic and implement it in your code.
Or you can see the ZK Forum for the same, Zk forum.

How do i bind data to a child View Model?

I have a page with two different View Models:
<?page title="My page" contentType="text/html;charset=UTF-8"?>
<div apply="org.zkoss.bind.BindComposer"
viewModel="#id('vm') #init('com.mycompany.FirstViewModel')">
<!-- A lot of unimportant stuff -->
<tabbox>
<tabs>
<tab label="Tab1" ></tab>
<!-- Other unimportant tabs -->
</tabs>
<tabpanels>
<tabpanel>
<include src="inc/other.zul" p="#ref(vm.selected)" pid="#ref(vm.selected.id)" ></include>
</tabpanel>
</tabpanels>
</tabbox>
</div>
And the include is:
<window>
<label id="sid" value="#load(pid)" />
<div apply="org.zkoss.bind.BindComposer"
viewModel="#id('vms') #init('com.mycompany.SecondViewModel')">
<listbox model="#id('vars') #load(p.someList)"
selectedItem="#bind(vms.selected)"
emptyMessage="No data in list">
<!-- Template and stuff -->
</listbox>
<label id="sid1" value="#load(pid)" />
</div>
</window>
The problem is that once I define the second viewModel, all the external references are inaccessible: I have a value for the first label, but I have no values for the listbox or the second label. Is there a way to do that? I tried with no success to do this:
<div apply="org.zkoss.bind.BindComposer"
viewModel="#id('vms') #init('com.mycompany.SecondViewModel')" list="#ref(p.someList)">
<listbox model="#id('vars') #load(list)"
selectedItem="#bind(vms.selected)"
emptyMessage="No data in list">
I could merge the second View Model in the first one, but that wouldn't be very convenient! I am also open to other solutions which allow me to have a modular approach.
My version of ZK is 6.0.1
The reason you are unable to access the external components is your composer i.e BindComposer you have same composer for the Main zul as well as for the Included zul. You need to access the Included Listbox from external ZUL.
So remove the Composer of Include ZUL, give an ID to window you have two Space Owners access the inner Listbox
<?page title="My page" contentType="text/html;charset=UTF-8"?>
<div apply="org.zkoss.bind.BindComposer"
viewModel="#id('vm') #init('com.mycompany.FirstViewModel')">
<!-- A lot of unimportant stuff -->
<tabbox>
<tabs>
<tab label="Tab1" ></tab>
<!-- Other unimportant tabs -->
</tabs>
<tabpanels>
<tabpanel>
<include id="include" src="inc/other.zul" p="#ref(vm.selected)" pid="#ref(vm.selected.id)" ></include>
</tabpanel>
</tabpanels>
</tabbox>
</div>
<window id="win">
<label id="sid" value="#load(pid)" />
<div
viewModel="#id('vms') #init('com.mycompany.SecondViewModel')">
<listbox id="listbox2" model="#id('vars') #load(p.someList)"
selectedItem="#bind(vms.selected)"
emptyMessage="No data in list">
<!-- Template and stuff -->
</listbox>
<label id="sid1" value="#load(pid)" />
</div>
</window>
Now while accessing in your BindComposer declare variable as public :
Listbox include$win$listbox2;
in your doAfterCompose() add this line
Sysout("You can access your inner Listbox and it is:"+include$win$listbox2);
Now you see you will not get your Listbox NULL!!
Link : http://books.zkoss.org/wiki/ZK_Developer's_Reference/UI_Composing/ID_Space
It is (was) actually a bug in ZK, which has been fixed for a future version.

Resources