In a f:attribute I use to calculate the value, but I see it is calculated only when it is called.
I need to specify the value using variable consumed during the visualization, so if it asks for the value not during the production of the component where the f:attribute refer, the value will be not correct.
I hope correctly specify my problem. How can I force the evaluation of attribute value?
Thanks if someone answer me!
The xhtml is:
<rich:scrollableDataTable
value="#{myBean.getScrollData(frm,sez)}"
var="eachRow"
rows="20"
>
<rich:columns value="#{sez.getElements()}" var="info"
index="index" sortable="false"
>
<h:inputText id="txtf#{info.getId()}" value="#{eachRow.data[info]}"
valueChangeListener="#{myBean.handle}"
>
<f:attribute name="xxx" value="#{eachRow.getId()}"/>
</h:inputText>
</rich:columns>
</rich:scrollableDataTable>
the myBean java is:
public void handle(ValueChangeEvent e){
Object value = e.getNewValue();
if ((value==null || value.equals("")) && e.getOldValue()==null) return;
String xxx = e.getComponent().getAttributes().get("xxx").toString();
System.out.println("handle("+xxx+","+value+")");
}
the ScrollData java is:
private String id="";
public String getId(){ return id;}
id is a property of ScrollData read from DB.
I see the xxx value is inspected only during post, so the eachRow is positioned on the last record of the table... and it's wrong.
This mechanism goes ok when not used in DataTable and I see the getId() method is called during the creation of the page (it's correct).
This is expected behaviour. The <f:attribute> is a taghandler which is tied to its single parent UIComponent and processed during view build time. Effectively, when the JSF UI components are to be parsed based on XHTML markup, all taghandlers are evaluated and applied. In your case, the JSF component tree contains only one <h:inputText> component which is reused during every row iteration during the view render time. The <f:attribute> is not re-evaluated during the view render time. So it holds still only the value which was available during the view build time, i.e. it contains null.
There are several ways to achieve the functional requirement anyway, one of them is to just evaluate #{eachRow} programmatically by Application#evaluateExpressionGet() in the value change listener method.
public void handle(ValueChangeEvent e) {
FacesContext context = FacesContext.getCurrentInstance();
EachRow eachRow = context.getApplication().evaluateExpressionGet(context, "#{eachRow}", EachRow.class);
// ...
}
See also:
JSTL in JSF2 Facelets... makes sense? (the same answer applies to <f:attribute>).
How can I pass selected row to commandLink inside dataTable?
Related
I have a HotelRepository which has a named method which returns a default Page<Hotel> item as result instead of a list.
I want to change the content type Hotel to HotelDto in the page since the DTO has customized parameter that I'd like to display. I have already a constructor to convert Hotel to HotelDto.
My attempt:
Page<Hotel> hotels = dao.findAll(pageRequest);
return new PageImpl<>(
hotels.getContent().stream()
.map(hotel -> new HotelListItemDto(hotel, hotel.getSupplier())).collect(Collectors.toList()),
pageRequest, hotels.getContent().size());
The problem is that it only manipulate one page of the result. Of course, I can get all the results as a list first then create a page based on the list, but it loses the advantage of Page (I think returning page would improve the performance of the search request).
So what should I do to keep the page advantage but still have the ability to customize the output?
You almost did it :)
Unless I'm skipping something, the only thing you need to change is the size that you are passing to the PageImpl constructor.
Instead of using hotels.getContent().size() (gives you the size of the content on the actual page) you should use hotels.getTotalElements() which gives you the total size of the elements in all the pages available.
Update 1:
To do it properly, you should change your code for:
Page<Hotel> hotels = dao.findAll(pageRequest);
return new PageImpl<>(
hotels.getContent().stream()
.map(hotel -> new HotelListItemDto(hotel, hotel.getSupplier())).collect(Collectors.toList()),
pageRequest, hotels.getTotalElements());
The code from above is going to create a page analog to the hotels page. And this is how your parameters are enough for the PageImpl:
The first parameter is the list with the content (of type HotelListItemDemo) that the new page will have. Since this is just a mapping for the hotels content to another type, the number of elements will be exactly the same.
The second parameter is the page request, which gives the PageImpl the information about the page size, the page index (and maybe the order, if you requested one).
The last parameter is the total number of elements that you would have if you append all the pages available in the query (value returned in the hotels.getTotalElements() method). With that, the PageImpl can also calculate things like hasNext() that I mentioned in the comments.
Hope this helps you.
Since page.getContent() is unmodifiable, the map() function of the page class should be used to maintain the functionality of the page.
#Override
public Page<HotelListItemDtodto > findAll(Pageable pageable) {
Page<Hotel> hotels = dao.findAll(pageable);
return page.map(this::entityToDTO);
}
private HotelListItemDto entityToDto(Hotel entity) {
if (entity == null)
return null;
return new HotelListItemDto(hotel, hotel.getSupplier());
}
I am combining wicket and jQuery for some project.
I have in HTML:
<a wicket:id="link" testAttr="test"></a>
And using jQuery I modify this attribute when other components on the page are clicked. My question here is how to obtain the current value of attribute "testAttr" from Java? I am fetching the value on every ajax call and see with inspect element that is changed, so no problem with that.
I have tried with getMarkupAttributes() but I always get value "test" and not the current one which I see on the page with inspect element. Also tried with AttributeModifier and Appender, onComponentTag, but had no luck.
Does anybody have an idea what to do here?
You have to send the current attribute value to the server as a 'dynamic extra parameter':
link.add(new AjaxEventBehavior("click") {
updateAjaxAttributes(ARA ara) {
super.updateAttributes(ara);
ara.getDynamicExtraParameters()
.add("return {'q' : jQuery('#' + attrs.c).attr('testAttr') };");
}
onEvent(ART art) {
RequestCycle requestCycle = RequestCycle.get();
String val = requestCycle.getRequest()
.getRequestParameters()
.getParameterValue("q")
.toString();
// ...
}
});
I assembled this piece of code from parts all over the XPages community, you might recognise a few:
var submitId= param.get( '$$xspsubmitid');
var component:com.ibm.xsp.component.xp.XspEventHandler= PageData.getComponentByClientId(submitId, view);
dprint("id= " + component.getClass().toString())
var params= component.getParameters();
for(var x:com.ibm.xsp.complex.Parameter in params) {
dprint(x);
dprint(x.getName());
dprint(x.getValue());
}
PageData is a managed bean, and getComponentByClientId does exactly what it says; its code, for completeness' sake:
public UIComponent getComponentByClientId(String id, UIComponent root) {
UIComponent component= new XspQuery().byClientId(id, root);
return component;
}
And as for XspQuery:
package org.openntf.xsp.extlib.query;
I want to find the name of the current field that triggered the partial update, and the form it is in. Both elements, fields and forms, are internal to my application. Their names are put in two Event Parameters, like this:
<xp:this.parameters>
<xp:parameter name="formName" value="#{javascript:compositeData.formName}"></xp:parameter>
<xp:parameter name="fieldName" value="#{javascript:compositeData.fieldName}"></xp:parameter>
</xp:this.parameters>
The issue is: when I put this code in one of the page events afterRestoreView, beforeRenderResponse or afterRenderResponse, the name of the parameter is correctly printed, but the call to getValue() never returns anything! More accurately: execution of the code stops, I don't know the exact error yet (which isn't exactly accurate, I admit).
How can I fetch these parameters?
TIA!
Looking at code in Mastering XPages, the way to access the value of an eventHandler parameter within the eventHandler's SSJS code is just to reference the name property as a variable. e.g. print(formName + ": " + fieldName)
I should have asked this question way earlier but now I am really tired of dodging around this problem:
I have a normal datatable like
<p:dataTable id="dt1" var="tVar" value="#{mrBean.queriedElements}" filteredValue="#{mrBean.filteredElements}" ...
Now in addition to the primefaces filters, I made my own panelGrid in which you can apply filters to the data base which work before any PF action.
The following lists exist: queriedElements which holds all the data that is returned after my personal filter applied and filteredElements which is needed for primefaces datatable filtering. In addition, I am not exactly sure whether I need an element list that represents all the data from the database. If no personal filter is applied, queriedElements = allElements.
The datatable displays a lot of information on the objects contained and you can change these objects via a dialog. I want the following:
When saved, update all changes made to the selectedElement
When cancelled, revert all changes in the datatable (I dont use a temporary object that is edited but the very object from the list)
When closing the dialog, remember all filters and paginator position
What is the best practise to do so and how can I avoid redundant code for queriedElements and filteredElements (in case I must iterate through it to change it explicitly in addition to database merges)? I found the first attribute for pagination, but I'm not really sure how to use it properly combined with my other requirements. My main problem is that the datatable almost never displays the right values if I don't refetch from database.
PF 4.0
I don't know why PF 4.0 doesn't do this by itself, but something that worked for me can be found at http://www.brainhemorage.com/?p=258
Although I had to replaced the lines
ValueExpression filterBy = column.getValueExpression("filterBy");
String filterField = null;
if (filterBy != null)
filterField = table.resolveStaticField(filterBy);
String filterId = column.getContainerClientId(context) + separator + "filter";
String filterValue = params.containsKey(filterId) && !table.isReset() ? params.get(filterId) :
table.getFilters().get(filterField); // <-- and here, was ""
String filterStyleClass = column.getFilterStyleClass();
by
String filterId = column.getContainerClientId(context) + separator + "filter";
String filterValue = params.containsKey(filterId) && !table.isReset() ? params.get(filterId) :
table.getFilters().get(column.getFilterBy());
because getValueExpression always returned null.
Although this doesn't answer my question about the BP, this will surely help others with the filteredValue problem.
I have read JSP recently, and have a doubt in the javabeans technolgy it uses. Lets say that the following JavaBeans code :
package mortgage;
public class Mortgage
{
private double amount = -1.0;
public void setAmount(double amount)
{
this.amount = amount;
}
}
And lets say i have to make use of this JavaBeans in my JSP and take the parameter values obtain from the HTML form or from the URL query string and JSP code as follows:
<jsp:useBean id="calc" class="mortgage.Mortgage" />
<p> Testing . . .
<c:set target="${calc}" property="amount" value="${param.mortgageAmount}" />
. . . . .
This example was little modified from my book. My question is what does this value in the above code JSP does? Where does the mortgageAmount came from?(is this the value from the HTML form element?)
And also what does target and property does?
Since I am a novice, i dont know what actually is going on the above code. Please help me and correct me if am wrong?
value represents expression that would be set to the target
Where does the mortgageAmount came from?
it assumed to be coming as param as you have used it in your code by param.mortgageAmount in url like
yourapp/page.jsp?mortgageAmount=someVAlue
In Simlper words
value is and Expression to be evaluated which will be set to
target object's property represented by property
See Also
Javadoc
param is a JSP implicit object. It's a map whose entries are the page parameters - so anything that's come in as a parameter in the query string, or (i think) through a form post.
Target and property govern what the c:set does; it sets the named property on the named target object to the given value.