AEM/CQ5 Dialog multifield not saving input - java

I am building a component which allows the user to add a multi field. When the multifield is added to the dialog, the user is presented with two text boxes. When the user adds information to the text boxes, and clicks 'OK'. When the dialog closes, no information is stored/saved.
Can anyone point out where I've gone wrong?
See the dialog code below:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="cq:Dialog"
xtype="dialog">
<items
jcr:primaryType="nt:unstructured"
xtype="panel">
<items jcr:primaryType="cq:WidgetCollection">
<heading
jcr:primaryType="nt:unstructured"
allowBlank="true"
disabled="false"
fieldLabel="Heading (optional)"
grow="false"
hideLabel="false"
name="./headingTitle"
readOnly="false"
selectOnFocus="false"
validateOnBlur="true"
xtype="textfield"/>
<message
jcr:primaryType="nt:unstructured"
fieldLabel="Message (optional)"
name="./message"
validateOnBlur="true"
xtype="textfield"/>
<link-list
jcr:primaryType="cq:Widget"
fieldLabel="Tabs titles and binding"
border="{Boolean}false"
name="./link-list"
width="1000"
xtype="multifield">
<fieldConfig
jcr:primaryType="cq:Widget"
path="/apps/group/components/nab-broker-tabs/dialog/items/items/link-list/fieldConfig/items.infinity.json"
xtype="cq.compositefield">
<items jcr:primaryType="cq:WidgetCollection">
<linkText
jcr:primaryType="cq:Widget"
fieldLabel="Titles"
name="linkText"
width="180"
xtype="textfield"/>
<linkBinding
jcr:primaryType="cq:Widget"
fieldLabel="binding ID"
name="linkBinding"
width="180"
xtype="textfield"/>
</items>
</fieldConfig>
</link-list>
</items>
</items>
</jcr:root>

Since multiple values are to be stored, you should be using a custom xtype to store multifield values.
refer: http://helpx.adobe.com/experience-manager/using/creating-custom-xtype.html

In case of complex multifield components, I would suggest you to use Multi Field Panel from ACS AEM Commons.
It will do the job for you.

Related

JSON to XML with type attribute in java

I'm rewriting C# application into java code.
There is REST API which return jsons.
I have to parse json to XML but C# library and Java doing it in difference ways.
How to keep type= attribute in java? I can't use JAXB annotations becouse there are too many objects in response and they might changing. XML.toString(jsonObject) doesn't work for me.
C# parsing is done in this way:
XDocument.load(JsonReaderWriterFactory.CreateJsonReader(Encoding.ASCII.GetBytes(jsonString), new XmlDictionaryReaderQuotas()));
C# result:
<root type="object">
<Items type="array">
<item type="object">
<Name type="string">test</Name>
<Total type="number">12.8000000</Total>
<CurrencyCode type="string">CHF</CurrencyCode>
<Country type="string">CH</Country>
</item>
</Items>
</root>
Java result:
<root>
<Items>
<item>
<Name>test</Name>
<Total>12.8000000</Total>
<CurrencyCode>CHF</CurrencyCode>
<Country>CH</Country>>
</item>
</Items>
</root>
I've used org.w3c.Document and org.w3c.dom.Element and set up attribute "type".
Anyway thanks for help :)

Multifield component in AEM - values are not saved

I'm trying to do multifield component here. When I enter values in fields, they are present on page and everything works fine. When I reopen component to edit existing data, it's empty like there were no values entered (they still appear on site) at all.
Here is code from my dialog.xml:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Multifield TouchUI Component"
sling:resourceType="cq/gui/components/authoring/dialog"
helpPath="en/cq/current/wcm/default_components.html#Text">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<fieldset
jcr:primaryType="nt:unstructured"
jcr:title="Footer"
sling:resourceType="granite/ui/components/foundation/form/fieldset">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<dashboard
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/textfield"
fieldDescription="Enter Headline"
fieldLabel="Headline"
name="./headline"/>
<groups
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/multifield"
class="full-width"
fieldDescription="Click '+' to add a new page"
fieldLabel="Groups">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/fieldset"
eaem-nested=""
name="./groups">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
method="absolute"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<country
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/textfield"
fieldDescription="Enter headline of this group"
fieldLabel="Headline"
name="./headline"/>
<states
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/multifield"
class="full-width"
fieldDescription="Click '+' to add a new page"
fieldLabel="Sites">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/fieldset"
name="./sites">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
method="absolute"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<state
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/textfield"
fieldDescription="Enter name of specific site"
fieldLabel="Site Name"
name="./site"/>
<path
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/pathbrowser"
fieldDescription="Select Path"
fieldLabel="Path"
name="./path"
rootPath="/content"/>
</items>
</column>
</items>
</field>
</states>
</items>
</column>
</items>
</field>
</groups>
</items>
</column>
</items>
</fieldset>
</items>
</column>
</items>
</content>
</jcr:root>
I know that there are some solutions using widgets, xtype and ext.js (ClassicUI), but I want to do it with granite/coral (TouchUI). As I researched the problem is that I should save values from every field as child nodes, but I do not understand how because examples are (as I noticed) same as code provided above.
If there is no help with this example, I would also be grateful if someone share their solution of multifield component that actually saves content author's input.
Also, if someone think that there is no such option in TouchUI, feel free to leave comment although that makes no sense.
I had similar problem with Multifields, and the only fix I found was using the Multifield of components/coral/foundation and adding only fields of the same group inside the multifield.
Try with this:
<sites
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
class="full-width"
composite="{Boolean}true"
fieldDescription="Click '+' to add a new page"
fieldLabel="Sites">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
name="./sites">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
method="absolute"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<state
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Site"
fieldDescription="Enter name of specific site"
name="./site"/>
<path
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Path"
fieldDescription="Select Path"
name="./path"/>
</items>
</column>
</items>
</field>
</sociallist>
I ran into the same (or similar) issue just today. For me, it turned out I needed to add the composite="{Boolean}true" property to my multifield. A composite multilfield can handle multiple fields within a field set.
So using your code as an example:
<states
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/multifield"
class="full-width"
fieldDescription="Click '+' to add a new page"
fieldLabel="Sites"
composite="{Boolean}true">
This post explains it well

AEM Add new tab to dialog of OOTB page component touch UI dialog

I want to add a new tab to the OOTB page component touch UI dialog (/libs/foundation/components/page), so that all pages that inherit from that OOTB component will have these fields.
It's unfortunately not an option to just add the tab to each template component, as I'm building a plugin instead of an implementation.
I have been trying to overlay /libs/foundation/components/page/_cq_dialog/content/items/tabs/items/ and add just my tab to that leaf items node, but then it doesn't pull the rest of the OOTB tabs. I think it's because it's not a leaf node, and it wants to be when doing overlay. So I need to somehow merge what I'm defining with the OOTB touch ui dialog.
This is my /apps/foundation/components/page/_cq_dialog node:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Page"
sling:resourceType="cq/gui/components/authoring/dialog"
extraClientlibs="[cq.common.wcm,cq.siteadmin.admin.properties]"
mode="edit">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container"
class="cq-dialog-content-page">
<items jcr:primaryType="nt:unstructured">
<tabs
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container"
rel="cq-siteadmin-admin-properties-tabs">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/tabs"
type="nav"/>
<items jcr:primaryType="nt:unstructured">
<custom
jcr:primaryType="nt:unstructured"
jcr:title="Custom"
sling:resourceType="granite/ui/components/foundation/section">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
margin="{Boolean}false"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<customsection
jcr:primaryType="nt:unstructured"
jcr:title="Custom field"
sling:resourceType="granite/ui/components/foundation/form/fieldset">
<items jcr:primaryType="nt:unstructured">
<customfield
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/textfield"
fieldLabel="custom field"
name="customField"/>
</items>
</customsection>
</items>
</column>
</items>
</custom>
</items>
</tabs>
</items>
</content>
</jcr:root>
Thank you!
The reason you are not seeing the rest of the tabs from the foundation page component is because you are overlaying the root items node of all the tabs. When you overlay you are redefining the functionality of the libs component and giving precedence to the overlayed component. If you'd like to have the rest of the tabs as well, you'll have to copy them all to your overlayed component, which is highly not recommended because you will lose out on upgrades to the component when you upgrade AEM or install service packs down the line.
I would recommend extending the component instead by setting a value of sling:resourceType to foundation/components/page in the base page component of your site. This way you add just that extra custom tab and inherit the rest of them from libs. In all probability (if following aem best practices), your site would already have a base page component having this property and the rest of the templates would be inheriting from this component. Add the below _cq_dialog to that page component and you should see the new tab across all the pages.
.content.xml of your base page component. One of the main templates from /apps/<<prj>>/templates will have a sling:resourceType linking to this page component.
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:Component"
jcr:title="Base Page Component"
sling:resourceSuperType="foundation/components/page"
componentGroup=".hidden"/>
_cq_dialog - reusing your code except for a new prop - sling:orderBefore="cloudservices", to order your new tab
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured">
<content jcr:primaryType="nt:unstructured">
<items jcr:primaryType="nt:unstructured">
<tabs jcr:primaryType="nt:unstructured">
<items jcr:primaryType="nt:unstructured">
<custom
jcr:primaryType="nt:unstructured"
jcr:title="Custom"
sling:orderBefore="cloudservices"
sling:resourceType="granite/ui/components/foundation/section">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
margin="{Boolean}false"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<customsection
jcr:primaryType="nt:unstructured"
jcr:title="Custom field"
sling:resourceType="granite/ui/components/foundation/form/fieldset">
<items jcr:primaryType="nt:unstructured">
<customfield
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/textfield"
fieldLabel="custom field"
name="customField"/>
</items>
</customsection>
</items>
</column>
</items>
</custom>
</items>
</tabs>
</items>
</content>
</jcr:root>
Screenshot
More about component hierarchy and inheritance here

Load page in a tab with ZK

I have this code in ZK, with a menu to navigate:
<zk apply="org.zkoss.bind.BindComposer"
viewModel="#id('vm') #init('menu')">
<tabbox width="100%" sclass="nav_tabs">
<tabs id="tabs">
<tab label="Admin" onSelect="updateCategory(self.label)"/>
<tab label="User" onSelect="updateCategory(self.label)"/>
</tabs>
<tabpanels>
<tabpanel>
<toolbar hflex="true">
<toolbarbutton label="CreateUser" onClick="#Command('load',label=self.label)" />
<toolbarbutton label="CreateMno" onClick="#Command('load',label=self.label)" />
</toolbar>
</tabpanel>
<tabpanel>
<toolbar hflex="true">
<toolbarbutton label="LoadData" onClick="#Command('load',label=self.label)" />
<toolbarbutton label="DownloadData" onClick="#Command('load',label=self.label)" />
</toolbar>
</tabpanel>
</tabpanels>
</tabbox>
<separator height="30px"></separator>
<zscript><![CDATA[
void updateCategory(String category) {
current_category.setValue(category);
current_subpage.setValue("Index");
}
]]></zscript>
<hlayout>
<label id="current_category" sclass="nav_text nav_category" onClick="#command('submit')">Our Product</label>
<label sclass="nav_text">-</label>
<label id="current_subpage" sclass="nav_text">Index</label>
</hlayout>
</zk>
Then i have two roles Admin, and User, and i need load the pages of each user, and i am trying that when a user click in the toolbarbutton, for example CreateUser, then call a method that load in the space of my toolbar button the page, but i do not how can i do it.
Something like:
http://www.zkoss.org/zkdemo/tabbox/navigation_tabs
but i not need a string in Our product -> Product 1 - > Our Product-Product 1, i need load a page, and i am calling the page with the same name to the label.
And a page from a java class
Somebody can help me?
Please add the following to your tabpanel:
<include id="includeID" mode="instant" src="page.zul" />
Later on, you may load another page by adding the following to a zscript:
includeID.setSrc("another_page.zul");

I18n in Struts-menu with Struts 2

I've developed a menu using struts-menu 2.4.3 with Struts 2. It's working ok but I need to take the titles of the menus from a properties file (router-messages.properties). The whole application is internationalized like this. But it just doesn't work with struts-menu. Here is my menu-config.xml file:
<Menu name="mainMenu" title="" >
<Item name="ecfMenu" title="ECFs" roles="FISCO" location="DisconnectedEcfsSearch" />
<Item name="reportsMenu" title="Relatórios" roles="ADMIN" location="AlarmReportSearch"/>
<Item name="fiscoMenu" title="Fisco" roles="ADMIN" location="UpdateFiscoForm"/>
<Item name="alarmMenu" title="Alarmes" roles="ADMIN" location="AlarmNotification"/>
<Item name="userMenu" title="application.header.users" roles="ADMIN" location="UserSearch"/>
<Item name="consoleMenu" title="Console" roles="FISCO" location="ConsoleSearch"/>
</Menu>
Please notice that I'm trying to use a key to my properties file in the item 'userMenu'. All other items work, but not this one.
Here's my jsp:
<menu:useMenuDisplayer permissions="rolesAdapter" name="Velocity"
config="/WEB-INF/tabs.html">
<menu:displayMenu name="mainMenu" />
</menu:useMenuDisplayer>
I searched around and even found a guy with the same question but there was no response for him. =/
Does anybody know how to make struts-menu recognize that I'm using a key to a properties file and not a literal String??
Thanks!
Try this:
For the menu-config.xml:
<Menu name="mainMenu" title="" >
<Item name="userMenu" title="application.header.users" roles="ADMIN" location="UserSearch"/>
</Menu>
For the JSP:
Use this:
<%# taglib prefix="menu" uri="http://struts-menu.sf.net/tag-el"%>
Instead of this:
<%# taglib prefix="menu" uri="http://struts-menu.sf.net/tag"%>
Invoking the menu:
<menu:useMenuDisplayer bundle="messages" permissions="rolesAdapter" name="Velocity"
config="/WEB-INF/tabs.html">
<menu:displayMenu name="mainMenu" />
</menu:useMenuDisplayer>
For the bundle="messages" provide the name of your resource bundle.
I hope it works for you!

Categories