How to retrieve value from linkedhashmap using iterators in Struts2......? - struts2

I have function which return LinkedHashMap in Struts2 and i just came to know that we cannot use for loop in struts2 instead we have to use Iterators, and am new to struts
can any on help me to retrieve value from linkedhashmap using iterators, below is how values are lined up in hashmap:
LinkedHashMap<String, ArrayList<String>> topSuppliers = new LinkedHashMap<String, ArrayList<String>>();
while(resultset.next()){
ArrayList<String> innerList = new ArrayList<String>();
String manufId = resultset.getString("manufacturer_id");
String manufLogo = resultset.getString("SUPPLIER_LOGO_IMAGE");
String manufName = resultset.getString("MANUFACTURER_NAME");
String manufURL = resultset.getString("MANUFACTURER_URL");
innerList.add(manufId);
innerList.add(manufLogo);
innerList.add(manufName);
innerList.add(manufURL);
topSuppliers.put(manufName,innerList);
}
return topSuppliers;
And i want to display them in a set of 4 manufacturers:
Set1: 1,2,3,4
Set2: 5,6,7,8
Set3: 9,10,11,12
etc......
Thank you........

You should iterate over List of Map instead of Map of List
Example :
#Getter
private List<Map> listOfMap = Lists.newArrayList();
public String execute() {
while (resultset.next()) {
final Map<String, String> map = Maps.newHashMap();
map.put("manufId", resultset.getString("manufacturer_id"));
map.put("manufLogo", resultset.getString("SUPPLIER_LOGO_IMAGE"));
map.put("manufName", resultset.getString("MANUFACTURER_NAME"));
map.put("manufURL", resultset.getString("MANUFACTURER_URL"));
listOfMap.add(map);
}
return SUCCESS;
}
<s:iterator value="listOfMap">
${manufId}
${manufLogo}
${manufName}
${manufURL}
</s:iterator>
The listOfMap also can use as a dataSource for Struts2 JasperReports Plugin.

You can use s:iterator over a map.
<s:iterator value="topSuppliers">
<s:property value="key" />: <s:iterator value="value" status="status"><s:property /><s:if test="!#status.last">,</s:if></s:iterator>
</s:iterator>
This iterates over the map using Map.Entry and then iterates over your value list using another iterator and iterator status to add "," unless it's the last entry.

Related

Thymeleaf custom dialect with fragments: how to keep th: attributes

I'm creating a custom dialect that replaces <myprefix:mytag> with a <div th:replace="myTagFragment::myfrag"> and it works with no attributes or "standard" attributes.
It stops working if I use th: attributes in the custom tag.
This works:
<myprefix:mytag required id="myid">
This does not work:
<myprefix:mytag th:field="*{name}">
TagProcessor code snippet:
protected void doProcess(ITemplateContext context, IModel model, IElementModelStructureHandler structureHandler) {
final IOpenElementTag customTag = (IOpenElementTag) model.get(0);
//
// I create a comma-separated list of the original attributes and add them in the fragment with th:attr
Map<String, String> attributes = sourceTag.getAttributeMap();
String attributeString = attributes.toString(); // "{attr1=val1, attr2=val2}"
attributeString = StringUtils.chop(attributeString); // Remove "}"
attributeString = StringUtils.removeStart(attributeString, "{"); // Remove "{"
structureHandler.setLocalVariable("attributeString", attributeString); // "attr1=val1, attr2=val2"
//
Map<String, String> newtagAttributes = new HashMap<>();
newtagAttributes.put("th:replace", "myTagFragment::myfrag");
IOpenElementTag replacementTag = modelFactory.createOpenElementTag("div", newtagAttributes, AttributeValueQuotes.DOUBLE, false);
model.replace(0, replacementTag);
Fragment snippet from "myTagFragment.html":
<th:block th:fragment="myfrag">
<div>somestuffhere</div>
<input th:attr="__${attributeString}__">
When I use
<myprefix:mytag type="password" maxlength="70" id="titolo">
I correctly get the replaced fragment:
<div>somestuffhere</div>
<input type="password" maxlength="70" id="titolo">
but if I want to use th: attributes in the original tag, they fail because something like
th:field is not processed properly when added with th:attr="__${attributeString}__" of course.
Maybe there is a way to retrieve the fragment model from inside the TagProcessor and add the th: attributes by code?
Any other idea to replace a custom tag with a template fragment while keeping the original attributes and have them processed when needed?
The (partial) solution I found so far is to process th: attributes myself in the TagProcessor: most of them just need to be replaced with the equivalent plain version after evaluation, some others need a special trearment, some more I just ignore.
(pseudo)Code snippet:
Map<String, String> attributes = sourceTag.getAttributeMap();
Map<String, String> targetAttributes = new HashMap<>();
for (Map.Entry<String,String> sourceAttribute : attributes.entrySet()) {
String attributeName = sourceAttribute.getKey();
String attributeValue = sourceAttribute.getValue();
if (attributeName.startsWith("th:") && !attributeName.endsWith("append")) {
String thAttributeName = ... remove "th:" from the name
String parsedValue = null;
if (!"attr".equals(thAttributeName)) {
try {
final IStandardExpression expression = parser.parseExpression(context, attributeValue);
parsedValue = (String) expression.execute(context);
} catch (Exception e) {
log.debug("Can't parse \"{}\" for tag \"{}\" - skipping", attributeValue, attributeName);
continue; // Next attribute
}
switch (thAttributeName) {
case "field":
targetAttributes.put("name", parsedValue);
targetAttributes.put("value", parsedValue);
break;
... also handle "attr", "alt-title", "lang-xmllang"
default:
targetAttributes.put(thAttributeName, parsedValue);
} else {
// Plain attributes with no "th:"
targetAttributes.put(attributeName, attributeValue);
}
}
... repeat the loop to handle "append" and "prepend" attributes here
String attributeString = targetAttributes.toString();
... same cose as in the question follows
The problem with this approach is that all conditional and looping th tags are lost, so I can't use th:each on my custom tag for example.
Another solution is to give a higher precedence to my custom dialect so that all th: attributes are executed before my tag processor.
This way I can use th:each and other stuff on my custom tag (see discussion here).
The only problem seems to be with th:field because it checks the tag before adding name/value attributes and skips them on any custom tag.
public class YadaDialect extends AbstractProcessorDialect {
public YadaDialect() {
super("Yada Dialect", "yada", StandardDialect.PROCESSOR_PRECEDENCE+1);
}

How to update the option by json result in Dart

My option values are download from server. How can I update the option values after server return result?
<select name="book" template iterate="book in books" bind-value="selected">
<option selected="{{selected == book}}">{{book}}</option>
</select>
In .dart
List<String> books= <String>[''];
#observable
String selected = 'Doraemon';
void main() {
var request = HttpRequest.getString(url).then((jstr){
// Parse json
Map data = json.parse(jstr);
print(data['option']['books']);
// Refresh the list, but how to refresh option value?
books.addAll(data['option']['books']);
}
You should wrap the books value in a call to "toObservable". https://www.dartlang.org/web-ui/observables/#observing-collections
List<String> books= toObservable(<String>['']);

PrimeFaces DataTable Enum filtering

I am using PF 3.4 and trying to filter a column which has enum value. I am using jsf 2.0's enum converter. But filtering does not work for me here is the sample code :
<p:dataTable id="projeTeklifiListesiDataTable"
value="#{controller.model.projeTeklifiListesi}"
var="proje" paginator="true" rowKey="#{proje.id}"
rows="50"
selection="#{controller.model.secilenProjeTeklifi}"
selectionMode="single" styleClass="defaultList">
<p:column headerText="#{etiket['pfdy_hzrl_vt013']}"
filterBy="#{projeTeklifi.projeTeklifiDurumu}"
filterOptions="#{controller.model.projeTeklifiDurumuListesi}"
sortBy="#{projeTeklifi.projeTeklifiDurumu.toString()}">
#{proje.projeTeklifiDurumu.toString()}
</p:column>
<p:column headerText="#{etiket['pfdy_dkd_vt010']}" filterBy="#{projeTeklifi.basariDurumu}"
filterOptions="#{controller.model.basariDurumuListesi}"
sortBy="#{projeTeklifi.basariDurumu.toString()}">
#{proje.basariDurumu.toString()}
</p:column>
</p:dataTable>
this are the lists for the filter options
public SelectItem[] getProjeTeklifiDurumuListesi()
{
final ProjeTeklifiDurumu[] durumListesi = ProjeTeklifiDurumu.values();
final SelectItem[] projeTeklifiDurumListesi = new SelectItem[durumListesi.length+1];
projeTeklifiDurumListesi[0] = new SelectItem("", "Seçiniz");
for(int i =0;i<durumListesi.length;i++)
{
final SelectItem select = new SelectItem(ProjeTeklifiDurumu.valueOf(durumListesi[i].name()),durumListesi[i].toString());
projeTeklifiDurumListesi[i+1]=select;
}
return projeTeklifiDurumListesi;
}
public SelectItem[] getBasariDurumuListesi()
{
final BasariDurumu[] durumListesi = BasariDurumu.values();
final SelectItem[] projeTeklifiDurumListesi = new SelectItem[durumListesi.length+1];
projeTeklifiDurumListesi[0] = new SelectItem("", "Seçiniz");
for(int i =0;i<durumListesi.length;i++)
{
final SelectItem select = new SelectItem(durumListesi[i],durumListesi[i].toString());
projeTeklifiDurumListesi[i+1]=select;
}
return projeTeklifiDurumListesi;
}
I have tried with different value bindings for SelectedItem class bind the enum itself, bind the name of the enum, called toString() method but it does not filter. I can see that my value binding of the filter option is posted correctly but does not filters the data.
Any clue would be helpful.
Thank you.
Look at org.primefaces.component.datatable.DataHelper
void decodeFilters(FacesContext context, DataTable table) {
...
String columnValue = String.valueOf(column.getValueExpression("filterBy").getValue(context.getELContext()));
...
}
They are decoding the value as is, so no converter will be used i think.

PrimeFaces DataTable: (Multi)selection does not work for dynamically built tables giving only nulls

I'm working with the multiple row selection to give a user ability to delete the selecting records. According to the PDF documentation, and the ShowCase Labs, I must use the code translated to the Java like that:
final DataTable = new DataTable();
...
// (1)
dataTable.setSelectionMode("multiple");
// (2)
dataTable.setValueExpression("selection", createValueExpression(DbeBean.class, "selection", Object[].class));
// (3)
dataTable.setValueExpression("rowKey", createValueExpression("#{" + VARIABLE + ".indexKey}", Object.class));
...
final ClientBehaviorHolder dataTableAsHolder = dataTable;
...
// (4)
dataTableAsHolder.addClientBehavior("rowSelect", createAjaxBehavior(createMethodExpression(metaData.controllerBeanType, "onRowSelect", void.class, new Class<?>[] {SelectEvent.class})));
multiple - This line features the multiple selection, works fine visually at the front-end.
selection - Being invoked, the #{dbeBean.selection} is really bound and the public void setSelection(T[] selection) is only invoked.
rowKey - Being invoked, works fine, the getIndexKey() is invoked and returns the necessary result.
rowSelect - This event handler is invoked too, DbeBean.onRowSelect(SelectEvent e).
I also use lazy data model (I don't really believe it may be the reason but who knows?; by the way, it returns List<T> though setSelection() requires T[] -- why it's like that?):
public abstract class AbstractLazyDataSource<T extends IIndexable<K>, K> extends LazyDataModel<T> {
...
#Override
public final List<T> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
...
final IResultContainer<T> resultContainer = getData(querySpecifier);
final List<T> data = resultContainer.getData();
setRowCount(resultContainer.getTotalEntitiesCount());
return getPage(data, first, pageSize);
}
...
#Override
public final K getRowKey(T object) {
return object.getIndexKey(); // T instanceof IIndexable<K>, have to return a unique ID
}
...
However, the handlers do not work as they are expected to work. Please help me to understand why (2) DbeBean.setSelection(T[] selection) & (4) DbeBean.onRowSelect(SelectEvent e) get only the null value: T[] selection = null, and SelectEvent: e.getObject = null, respectively. What am I doing wrong?
Thanks in advance.
PrimeFaces 3.2
Mojarra 2.1.7
I've got it to work: I simply removed the rowKey property during to the dynamic p:dataTable creation (DataTable), and simply overloaded getRowData in lazy data model. Now it works.

Struts2 using Map in select tag

You can easily use a List in struts2 select tag, but is there a way to use Map in tag?? If it is possible please provide a sample code...
thanx !
In my action class
public class MyAction extends ActionSupport {
private Map<String, String> map;
public String execute() throws Exception {
map = new HashMap<String, String>();
map.put("abc", "abc");
map.put("xyz", "xyz");
return SUCCESS;
}
}
For the jsp mapped to success, use some thing like this
<s:select list = "map" name = "name" label = "Name" headerKey="" headerValue = "Enter Value"/>
It depends on what are you trying to do. Lacking details, I can only point you to the docs : the list attribute of the select tag is an ...
Iterable source to populate from. If
the list is a Map (key, value), the
Map key will become the option 'value'
parameter and the Map value will
become the option body.
Below in the same doc there is an example with a (literal, inline) map (Months).

Resources