Nested Multifield or Multifield with in Multifield in CQ5 - aem

Wanted to a build a nested multifield dialogue in cq5.
My requirement is to build a single multified component with
Title
LinkText
Linkpath
ImageUpload
with in this multifield ,I wanted to have linktext as another multifield.
Note:
.I was able to create titile,linktext,linkpath,imageupload as multifield,but couldnt make linktext as another multifield inside a multifield. I am new to cq5 dev,Kinldy Suggest if there are any other approach.

I believe the only way to do this is to write your own widget. I have accomplished this but am unable to share the code. If you want you can check out this open source library I have been working on building out at https://github.com/Velir/AEM-Toolbox. The StucturedMultiList widget may suit your needs.

An example how to implement a custom widget as described by Chris Leggett can be found at:
http://cq.shishank.info/2011/12/19/multifield-with-custom-xtype/
How I've stored the value is in the format:
[item1|item2]
Using a bit of logic you can then extract a link text and url but the third value seems to step into bad practice if you're using this format, but the style of storing this information will be the same. Maybe you could store the information as JSON, but I haven't personally seen an implementation of this.
Hope that helps.

This will involve customizing the multifield js and creating custom xtypes by extending composite field. Most of the part of nesting custom multifields is same as creating a single custom multifield.
The inner multifield will return a comma separated String on getValue, this will have to be concatenated with other fields of outer multifield separated by a delimiter. The set value of inner multifield will expect a string array, for this you will have to modify the multifield js of inner multifield and override the set value method to take the comma separated string and split into an array.
The outer multifield will also have to be updated on change of inner multifield content.This can be done by calling the update method right after updating inner multifield(reference to the outer multifield can be obtained through findParentBy method)
The end result will look like this
String array
[0] : a-outer-field1<#->a-outer-field2<#->a-1-inner-field1<#-#>a-1-inner-field2<#-#>,a-2-innerfield1<#-#>a-2-innerfield2<#-#><#-*>
[1] : b-outer-field1<#->b-outer-field2<#->b-1-inner-field1<#-#>b-1-innerfield2<#-#>,b-2-innerfield1<#-#>b-2-innerfield2<#-#><#-*>
Check out this link http://cq5tutorials.blogspot.com/2014/04/cq5-multifield-in-multifield.html

Related

SAPUI5 No dynamic way to get form data without data binding. And no Form submit event.

I have a simple form that's in a dialog fragment used to submitting two fields for log-in auth.
For simplicity I was hoping to not have to use data binding, but rather use some method to gather all data inside my sap.ui.layout.form.SimpleForm.
I added a name property to each input element which says in the docs it is " Defines the name of the control for the purposes of form submission."
https://openui5.hana.ondemand.com/#/api/sap.m.InputBase/controlProperties#name
However hard as I try to find there doesn't seem to be any getFormData methods.
All SO questions and guides either use data binding to a model, or hard-code references to the individual input controls with .getValue() methods.
And looking further into the form API, there doesn't seem to be a Submit event either.
Given an arbitrary form, what would be the best way to gather all submission values without hard-coded references or data-binding?
Would a method that walks though all the children elements of a form looking for all submission values work? I think it might, but there are more submission input types then just the input component.
You can get the value of the fields by directly using;
var oField = sap.ui.getCore().byId('IdOfTheFieldAtTheDialog');
var sValue = oField.getValue();
But it's always better and convenient to use data binding which keep things neat.
And If I assume that you have the id of parent form container, you can iterate over the items and get the sap.m.Input elements in it without knowing the IDs of the individual inputs, and you may check the name property of the fields if you want. Check this snippet;
https://jsfiddle.net/hdereli/9e92osfk/3/

How to remove a validator from a Select?

I have a form where I need to add/remove validators dynamically. Based on a dropdown selection, other form fields may have different validation rules.
For other kinds of inputs, I've used replace(methodThatCreatesTheInput()) to get rid of a previously added validator. (Not knowing of a better way. Specifically, there doesn't seem to be any way to directly remove a validator from a component...)
With Select, from wicket-extensions, this approach fails with something like:
WicketMessage: submitted http post value [[Ljava.lang.String;#5b4bf56d]
for SelectOption component [8:myForm:targetInput] contains an
illegal relative path element [targetConsortiums:1:option] which does not
point to an SelectOption component. Due to this the Select component cannot
resolve the selected SelectOption component pointed to by the illegal value.
A possible reason is that component hierarchy changed between rendering and
form submission.
The method that creates the Select:
private FormComponent<?> targetSelection() {
Map<Class<? extends Target>, List<Target>> targets = targetService.getAllAsMap();
SelectOptions<Target> propertyOptions = new SelectOptions<Target>("targetConsortiums",
targets.get(Consortium.class), new TargetRenderer());
SelectOptions<Target> consortiumOptions = new SelectOptions<Target>("targetProperties",
targets.get(Property.class), new TargetRenderer());
Select select = new Select(ID_TARGET, new PropertyModel<Target>(model, "target"));
select.add(propertyOptions);
select.add(consortiumOptions);
select.setRequired(true);
select.setMarkupId(ID_TARGET);
return select;
}
(Why use a Select instead of normal DropDownChoice? We want the two types of choices to be clearly separated, as documented in this question.)
Any ideas how to solve this? What I'm trying to achieve is, of course, very simple. Unfortunately Wicket disagrees, or I'm using it wrong.
Wicket 1.4.
I don't know how to do this on Wicket 1.4, but on Wicket 1.5 there is a remove method for validators on FormComponent (see javadoc)

Extjs 4 :Disable all the input elemets in an Extjs form at once

I have created a extjs form which is divided into 2 parts using column layout and have almost 10-15 input elements in it. How can i disable all these input elements at a time depending on a condition. Currently i have created a function which fetchs all the components in a form and using ext.each loop through each element to disable them
Here is the function that i use
function prepare_form_view(form){
var f=Ext.getCmp(form);
var els=f.query('component');
Ext.each(els,function(o){
var xtype=o.getXType();
if(xtype=='textfield'||xtype=='combobox'||xtype=='datefield'||xtype=='textareafield'||xtype=='button'){
o.disabledCls='myDisabledClass';
o.disable();
}
});
}
Is there any alternative way so that I can disable all elements without looping through each and every elements. I want to use this function with other forms too. I looking for something like 'setFieldDefult' function.
If you are using FormPanel in ExtJs 4.x this is what you are looking for -
yourFormPanel.getForm().applyToFields({disabled:true});
The getForm() method returns the Ext.form.Basic object, with this class, you also could access to all the fields on this form with getFields(), then you could iterator all the fields to do anything.
Hope this helps and good luck:-)
What about panel's disable/enable method? This seems much easier.
panel.disable();
panel.enable();
Here is a suggestion.. Since, you say your form is divided into two parts why don't you put them in a FieldSet ? You can disable the fieldset as a whole with one method ie, setDisabled.
This will avoid the looping of components and disabling / enabling them one after the another.
You could use the cascade function of the form panel which is the ExtJs way to to do it but if you check the source code of the cascade function you will see that it uses a for loop also. The only benifit of using the cascade function is that it will work also for forms with nested panels. I think that your implementation will not work properly a case like that.

Wicket - can you specify markups IDs for elements inside repeaters?

I'm having a hard time testing our Wicket application using Selenium because of the random markup ids.
For individual elements, I can use abc.setOutputMarkupId(true).setMarkupId("myId")
to set their markup id explicitly.
But what if the element is added dynamically using a repeater (like ListView)? Is there a way to specify how the markup id sequence should look like?
Well, can't you do the same thing with ListView? If you make your own ListView implementation, and then in the populateItem(final ListItem<?> listItem) method, on that respective listItem you do:
listItem.setOutputMarkupId(true); // write id attribute of element to html
listItem.setMarkupId("id"+i);
where i is some index you initialize in the ListView's constructor or something?
as Andrei told that its possible but dangerous.
setMarkupId doc:
Retrieves id by which this component is represented within the markup. This is either the id attribute set explicitly via a call to
org.apache.wicket.Component.setMarkupId(java.lang.String), id
attribute defined in the markup, or an automatically generated id - in
that order. If no explicit id is set this function will generate an id
value that will be unique in the page. This is the preferred way as
there is no chance of id collision.
http://www.kiwidoc.com/java/l/p/org.apache.wicket/wicket/1.4.0/p/org.apache.wicket/c/Component#top
and also you cant get the markup id with getMarkupId()

how to create group of gwt Order list

Hi,
My goal is to create a list of items in GWT similar to how it is done in HTML using ordered and unorderd lists. Can someone explain to me how this can be achieved in GWT?
Thanks!!
you can use the dom API in com.google.gwt.dom.client which has a syntax very close from the JavaScript one:
for (String listItem : listData) {
LIElement liElement = Document.get().createLIElement();
liElement.setInnerText(step);
this.olElement.appendChild(liElement);
}
this example simply add the list item build from the listData List end append them in the ordered list. I used UiBinder to get the olElement so you have to get a root element somewhere (Document has a method getElementById) and add your Element to it.