Problem with multiple components

I am creating a multi-user component having 2 text fields. Below is my xml dialog.

<?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" jcr:primaryType="cq:Dialog" title="dialog" xtype="dialog"> <items jcr:primaryType="cq:WidgetCollection"> <links jcr:primaryType="cq:Widget" fieldLabel="QuickLinks" name="./links" xtype="multifield"> <fieldConfig jcr:primaryType="cq:Widget" xtype="multifield"> <items jcr:primaryType="cq:WidgetCollection"> <title jcr:primaryType="cq:Widget" fieldLabel="Title" hideLabel="{Boolean}false" name="./jcr:title" xtype="textfield"/> <url jcr:primaryType="cq:Widget" fieldLabel="URL" name="./jcr:url" xtype="textfield"/> </items> </fieldConfig> </links> </items> </jcr:root> 

I can edit the content and the content is saved. However, I have 2 problems - 1) When the dialog loads, it is always empty, and it does not show the saved content when the dialog is reopened. 2) Up and down arrows no longer work. Any suggestions for fixing them are commendable. Thank you very much.

+5
source share
3 answers

The multifield xtype field configuration accepts only one element (that is, it can have one text field. If you configure multiple values, they will be stored as a multi-valued property called links, and when only one value is configured, it will be saved as a single-valued property called links). All data configured in your multi-user mode will be saved as a link property in your node. You cannot get them as "jcr: title" and "jcr: url".

You must create your own xtype type that says "linksXtype", which stores "jcr: title" and "jcr: url" as one line, separated by some pattern, for example "***" ("jcr: title *** jcr: . URL ")

Here you can find out the details of creating a custom xtype: link

The xtype type can be created as follows:

 Ejst.CustomWidget = CQ.Ext.extend(CQ.form.CompositeField, { /** * @private * @type CQ.Ext.form.TextField */ hiddenField: null, /** * @private * @type CQ.Ext.form.ComboBox */ jcrtitle: null, /** * @private * @type CQ.Ext.form.TextField */ jcrurl: null, constructor: function(config) { config = config || { }; var defaults = { "border": false, "layout": "table", "columns":2 }; config = CQ.Util.applyDefaults(config, defaults); Ejst.CustomWidget.superclass.constructor.call(this, config); }, // overriding CQ.Ext.Component#initComponent initComponent: function() { Ejst.CustomWidget.superclass.initComponent.call(this); this.hiddenField = new CQ.Ext.form.Hidden({ name: this.name }); this.add(this.hiddenField); this.jcrtitle = new CQ.Ext.form.TextField({ fieldLabel:"Jcr url", cls:"ejst-customwidget-1", listeners: { change: { scope:this, fn:this.updateHidden } }, optionsProvider: this.optionsProvider }); this.add(this.jcrtitle); this.jcrurl = new CQ.Ext.form.TextField({ fieldLabel:"Jcr Title", cls:"ejst-customwidget-2", listeners: { change: { scope:this, fn:this.updateHidden } } }); this.add(this.jcrurl); }, // overriding CQ.form.CompositeField#setValue setValue: function(value) { var parts = value.split("/"); this.jcrtitle.setValue(parts[0]); this.jcrurl.setValue(parts[1]); this.hiddenField.setValue(value); }, // overriding CQ.form.CompositeField#getValue getValue: function() { return this.getRawValue(); }, // overriding CQ.form.CompositeField#getRawValue getRawValue: function() { return this.jcrtitle.getValue() + "***" + this.jcrurl.getValue(); }, // private updateHidden: function() { this.hiddenField.setValue(this.getValue()); } }); // register xtype CQ.Ext.reg('linksXtype', Ejst.CustomWidget); 

change dialog.xml to something like this

 <?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" jcr:primaryType="cq:Dialog" title="dialog" xtype="dialog"> <items jcr:primaryType="cq:WidgetCollection"> <links jcr:primaryType="cq:Widget" fieldLabel="QuickLinks" name="./links" xtype="multifield"> <fieldConfig jcr:primaryType="cq:Widget" xtype="linksXtype"> </fieldConfig> </links> </items> </jcr:root> 

To get the values, iterate over the array of strings stored as a property of the links, and split each row by "***"

EDIT :

Adobe Consulting Services under ACS-Commons provides a more elegant multifieldpanel widget to handle this use case. This simplifies the approach and eliminates the need to write a custom xtype for each combination of required fields. Data is stored in JSON format and comes with taglib to retrieve data from node. Link: http://adobe-consulting-services.imtqy.com/acs-aem-commons/features/widgets.html#multi-field-panel-since-150

+5
source

As Sharath says, you will need to define your own XType, instead of putting multiple fields in the multfield itself.

As an alternative to concatenating fields in the String[] property, another approach is to create child nodes for each added field, for example. but not:

 <links link="[Example|http://example.com,Google|http://google.com]"/> 

As a result, you will receive:

 <links> <link_1 title="Example" url="http://example.com"/> <link_2 title="Google" url="http://google.com"/> <links> 

You can read the values ​​back without having to parse them from the String value. It also means that things like rollout, which update path fields, should work like standard ones.

The code is too long to be fully produced here, but there is a good starting point for this on the Adobe forums here . (It has an Adobe copyright notice, but is submitted by the user - not sure of its official status, but good as a reference implementation; EDIT: possibly linked to the Citytechnic MultiCompositeField on Github , as ery points out ).

The above example also uses the same approach as the multifield itself, i.e. it reads from the fieldConfig node of the composite and creates a property for each record on the child nodes that it creates.

This makes the composite field completely reusable, since you only need one composite XType no matter how many options you want to create, i.e. will allow you to choose the approach that you outline in the question:

 <links jcr:primaryType="cq:Widget" fieldLabel="QuickLinks" name="./links" xtype="mtmulticompositefield"> <fieldConfigs jcr:primaryType="cq:WidgetCollection"> <title jcr:primaryType="cq:Widget" fieldLabel="Title" hideLabel="{Boolean}false" name="./jcr:title" xtype="textfield"/> <url jcr:primaryType="cq:Widget" fieldLabel="URL" name="./jcr:url" xtype="textfield"/> </fieldConfigs> </links> 

It also allows the use of more complex XTypes as children, for example. images without further work.

+2
source

I know that the problem is resolved at this point, I comment, but this is for reference only. 1) When a dialog loads, it is always empty, and it does not display the saved content when the dialog is reopened

Answer: I used extjs to create a multifield for my dialog, and in my functional code extjs set () was like

setValue: function (value) {

  var link = JSON.parse(value); this.websiteName.setValue(link.text); this.websiteLinks.setValue(link.text); this.hiddenField.setValue(value); }, 

but the code should be

setValue: function (value) {

  var link = JSON.parse(value); this.websiteName.setValue(link.field1Name); this.websiteLinks.setValue(link.field2Name); this.hiddenField.setValue(value); }, 

Just by adjusting this, your dialog will display the filled values. Also check your name in the dialog box. That should be right.

2) Up and down arrows no longer work.
This problem is mainly related to your js file. What I experienced. Whenever clicks do not work, check your js for errors in the developer tools in the browser. With one syntax error, your js stops working and clicks too.

Hope this helps someone :)

0
source

Source: https://habr.com/ru/post/1204390/


All Articles