Expand my Community achievements bar.

SOLVED

How can I make the data display in different rows?

Avatar

Level 2

Hi 
I have created a multifield inside another multifield where if I click "add" I will be able to enter two different levels of data any number of time. I have written a java code to fetch the values and wrote html to display them in tabular format.
I am getting header correctly displayed but when displaying body different data is getting displayed in single row with ',' like below image. 

sushmapoojitha_0-1619957003398.png


How can I make the data display in different rows each ?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @sushmapoojitha 

 

You need to get the data in a list format and then iterate over the list to print it in a order in <tr>.

Now it looks like the data is stored in a JSON format in multifield node and you are printing the complete string.

 

Are you using custom multifield? Please share the structure of the mulfield node in which the data is getting stored.

 

If it's getting stored in a Json format, you need to write a POJO class with the field values and then iterate over it and convert into a list. Now the same list can be used in HTL to print in the desired format.

 

import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ChildResource;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;

import java.util.List;

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public interface TestModel {

@ChildResource(name = "outerMultiField")
List<OuterMultiField> getOuterMultiField(); // the name 'getOuterMultiField' corresponds to the multifield name="./outerMultiField"

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
interface OuterMultiField {
@ValueMapValue(name = "title")
String getTitle();

@ChildResource(name = "innerMultiField")
List<InnerMultiField> getInnerMultiField(); // the name 'getInnerMultiField' corresponds to the multifield name="./innerMultiField"
}

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
interface InnerMultiField {
@ValueMapValue(name = "text")
String getText();

}
}

 

<sly data-sly-use.testModel="com.something.core.models.TestModel">
<div>
<ul data-sly-list.outer="${testModel.outerMultiField}">
<li>${outer.title}
<ul data-sly-list.inner="${outer.innerMultiField}">
<li>
<b>${inner.text} <br/></b>
</li>
</ul>
</li>
</ul>
</div>
</sly>

asutosh_jena_0-1619961065513.png

 

 

Thanks!

View solution in original post

7 Replies

Avatar

Correct answer by
Community Advisor

Hi @sushmapoojitha 

 

You need to get the data in a list format and then iterate over the list to print it in a order in <tr>.

Now it looks like the data is stored in a JSON format in multifield node and you are printing the complete string.

 

Are you using custom multifield? Please share the structure of the mulfield node in which the data is getting stored.

 

If it's getting stored in a Json format, you need to write a POJO class with the field values and then iterate over it and convert into a list. Now the same list can be used in HTL to print in the desired format.

 

import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ChildResource;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;

import java.util.List;

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public interface TestModel {

@ChildResource(name = "outerMultiField")
List<OuterMultiField> getOuterMultiField(); // the name 'getOuterMultiField' corresponds to the multifield name="./outerMultiField"

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
interface OuterMultiField {
@ValueMapValue(name = "title")
String getTitle();

@ChildResource(name = "innerMultiField")
List<InnerMultiField> getInnerMultiField(); // the name 'getInnerMultiField' corresponds to the multifield name="./innerMultiField"
}

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
interface InnerMultiField {
@ValueMapValue(name = "text")
String getText();

}
}

 

<sly data-sly-use.testModel="com.something.core.models.TestModel">
<div>
<ul data-sly-list.outer="${testModel.outerMultiField}">
<li>${outer.title}
<ul data-sly-list.inner="${outer.innerMultiField}">
<li>
<b>${inner.text} <br/></b>
</li>
</ul>
</li>
</ul>
</div>
</sly>

asutosh_jena_0-1619961065513.png

 

 

Thanks!

Avatar

Level 2

yes i am using JSON format in multifield node to return the values.
sling:resourceType value is "granite/ui/components/coral/foundation/form/multifield"
I am using one text field and another multifield (having one text field) inside it and returning the output.

Avatar

Community Advisor

Hi @sushmapoojitha 

Please see the code below. This is how the node will be stored in content tree.

asutosh_jena_0-1619960763000.png

 

I have used Interfaces here as I am not processing any of the user inputs (no business logic).

 

import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ChildResource;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;

import java.util.List;

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public interface TestModel {

@ChildResource(name = "outerMultiField")
List<OuterMultiField> getOuterMultiField(); // the name 'getOuterMultiField' corresponds to the multifield name="./outerMultiField"

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
interface OuterMultiField {
@ValueMapValue(name = "title")
String getTitle();

@ChildResource(name = "innerMultiField")
List<InnerMultiField> getInnerMultiField(); // the name 'getInnerMultiField' corresponds to the multifield name="./innerMultiField"
}

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
interface InnerMultiField {
@ValueMapValue(name = "text")
String getText();

}
}

Sample HTL: 

<sly data-sly-use.testModel="com.something.core.models.TestModel">
<div>
<ul data-sly-list.outer="${testModel.outerMultiField}">
<li>${outer.title}
<ul data-sly-list.inner="${outer.innerMultiField}">
<li>
<b>${inner.text} <br/></b>
</li>
</ul>
</li>
</ul>
</div>
</sly>

 

This will give output something like below:

asutosh_jena_1-1619960937593.png

 

Hope this helps!

 

Thanks

Avatar

Level 2

Hi I am using only one node inside innerMultiField and repeating it inside the innerMultiField. I want that data to get printed in different rows but it is getting printed in single row by using ',' as divider. Can I make that data to print in different rows. This is the code i am using. 



public List<String> getConverttoJSONArray() {
converttoJSONArray = new ArrayList<String>();
log.debug("multifieldlinks " + multifieldlinks);
try {
if(null != multifieldlinks) {
log.debug("inside not null");
Iterator<Resource> children = multifieldlinks.listChildren();

while(children.hasNext()) {
log.debug("inside while");
Resource resource = children.next();
ValueMap valueMap = resource.getValueMap();
for(String key : valueMap.keySet()) {
if(key.equalsIgnoreCase("tmsg")) {
String value = valueMap.get(key, String.class);
log.debug("key value "+key + "--" + value);
converttoJSONArray.add(value);
}

}
}
}
log.debug("converttoJSONArray "+converttoJSONArray);
} catch (Exception e) {
log.error("Exception::::",e);
}
return converttoJSONArray;
}

Avatar

Community Advisor

Hi @sushmapoojitha 

 

The above example I mentioned is also using only a single field and able to print value in different row. The code that I have used will print the value in different row only.

Can you share the HTL code so that I can make the required changes and send it?

 

Thanks!