How to get Trinidad tr:inputText to echo its changed value instantly? - jsf

I have the following Trinidad tr:inputText field in my xhtml file that is bound to "value1" in my managed bean class; the inputText field is of type:
org.apache.myfaces.trinidad.component.core.input.CoreInputText
<tr:inputText value="#{myBean.value1}" autoSubmit="true" immediate="true" valueChangeListener="#{myBean.textChangeListener}" styleClass="stylePageTextSmallColored">
</tr:inputText>
<tr:commandButton id="btnCommit" inlineStyle="width:20" immediate="true" text="Commit" action="#{myBean.doCommit()}" styleClass="styleButton">
</tr:commandButton>
public void textChangeListener(ValueChangeEvent e) {
log.debug(">> textChangeListener: value=["+(String)e.getNewValue()+"]");
}
public String doCommit() throws Throwable {
log.debug("In doCommit: value1="+value1);
value1 = "("+value1+")";
// I update my database with the modified value1 string here; the database has the correct
// updated value1 string (with the parentheses).
// How do I get the modified value1 (above) to echo back to the screen instantly
// inside the doCommit() method with its changes?
}
When I type into this field and change its value then press the "commit" button, I can see its value properly obtained from the screen in the doCommit() method and the textChangeListener() method indicates that it has been called. I would like to make some changes to the "value1" variable and echo its value back instantly to the screen without doing another screen submit; can this be done as part of the doCommit() method or through some other mechanism/tag in the xhtml file?
Please note that this is using Trinidad and the input text class is listed above.
Update...
Thank you for the reference Jasper; I want the SAME inputText field to update itself after the setter method is called and the input text is changed (by the setter method). Thanks to the reference page that you pointed to; I tried the following and it works by using the partialTriggers attribute:
<tr:inputText id="myValue" value="#{myBean.value1}" autoSubmit="true" immediate="true" partialTriggers="myValue" valueChangeListener="#{myBean.textChangeListener}" styleClass="stylePageTextSmallColored"> </tr:inputText>

You can do so using Trinidad's Partial Page Rendering.
In short: you need to add an id attribute to your input, and have and tr:outputText component with a partialTriggers attribute where you refer to the input component.
Minimal implementation in your case would be:
<tr:inputText id="value1Input"
value="#{myBean.value1}"
autoSubmit="true"
immediate="true"/>
<tr:outputText value="value1: #{myBean.value1}"
partialTriggers="value1Input"/>

Related

Primefaces: how to update a p:inputText with a parameter on the setter? [duplicate]

This question already has answers here:
How to set a Map value in h:inputText
(1 answer)
Write to a map property in an h:inputText in h:dataTable
(1 answer)
Closed 4 months ago.
I have a page where the user must input grading for a number of categories. The categories are retrieved dynamically from a database (there are different user types, and for each type you get different categories). As there are subcategories, I have implemented it using <p:treeTable>.
I have the grades stored in a map, with the category id as the key and the grade as the value:
HashMap<Integer, Double> detailedGrades
The problem is how to get and set the grade for each category using <p:inputText>, because the category id has to be a parameter in that. I have managed to do the getter like this:
<p:inputText id="cat" value="#registerCandidateGradeBean.getGradeForCat(gradingCat.pkCertGradeCategoryId)}"/>
and in the bean:
public Double getGradeForCat(int catID){
return detailedGrades.containsKey(catID) ? detailedGrades.get(catID) : null;
}
This displays the value in the input field OK, but I don't know how to set the value when the user changes it. I tried with <p:ajax listener> as mentioned here, where I set
<p:ajax listener="#{registerCandidateGradeBean.setGradeForCat1(gradingCat.pkCertGradeCategoryId)}"/>
and in the bean:
public void setGradeForCat1(int catID){
System.out.println(catID);
}
but whenever I change the input value I get a "javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation" exception. I tried to use a valueChangeListener on the inputText
<p:inputText id="cat" value="#registerCandidateGradeBean.getGradeForCat(gradingCat.pkCertGradeCategoryId)}"
valueChangeListener="#{registerCandidateGradeBean.setGradeForCat}"/>
and in the bean:
public void setGradeForCat(ValueChangeEvent e){
System.out.println("called");
//System.out.println(catID);
System.out.println(e.getNewValue());
}
but it never gets called. (I have tried both setGradeForCat(ValueChangeEvent e) and setGradeForCat(ValueChangeEvent e, int catID)).
Any ideas?
Forgot to mention: we are using primefaces 5.3.
The problem is, that you use value="#registerCandidateGradeBean.getGradeForCat(gradingCat.pkCertGradeCategoryId)}" in the input component.
This makes jsf looking for a getter and setter which is called getgetGradeForCat and setgetGradeForCat.

NullPointerException while displaying the same page after some taks in jsf

First I want to tell :
I saw How to use JSF's h:selectBooleanCheckbox with h:dataTable to create one object per row?
and my problem is like same but not solved problem.
Following is my code :
*.xhtml
<rich:column>
<h:selectBooleanCheckbox id="resolveTxn" value="#{verifyTransactionBean.checked[verifyTxnList.id]}"/>
</rich:column>
.
.//Some code here
.
<h:commandButton value="Resolve" action="#{verifyTransactionBean.resolveToTxn}" styleClass="btn" />
and following is my code
private Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
public void resolveToTxn() {
List<ToVerifyTxnDTO> list = new ArrayList<ToVerifyTxnDTO>();
for (ToVerifyTxnDTO dTO : toVerifyTxnDTOList) {
if(checked.get(dTO.getId())){//I got null pointer exception here
Long id=dTO.getId();
verifyTransactionSessionBeanLocal.updateResolvedflag(id);
}
}
}
What I want to do ?
I want to pass checked row id as parameter on following :
verifyTransactionSessionBeanLocal.updateResolvedflag(id);
And after clicking the button Resolve some operation should be done and refresh dataTable and display same page. Operation is done but getting null pointer exception while displaying (Reddering) the same page
Thanks
The if () test on a Boolean will throw NullPointerException if the Boolean itself is actually null instead of true or false. In other words, the checked.get(dTO.getId()) has unexpectedly returned null for some reason.
That can have several causes:
The JSF implementation hasn't properly updated the checked map with the value from <h:selectBooleanCheckbox> for some reason.
The EL implementation was using Boolean instead of boolean for some reason.
The toVerifyTxnDTOList has incompatibly changed during the process which caused that the currently iterated dTO isn't the one which was been displayed in the table at the moment checkboxes were clicked (perhaps because the bean is request scoped instead of view scoped).
The toVerifyTxnDTOList contains more items than present in the checked map because you're using pagination and displaying only a subset at once.
In any case, to fix the NullPointerException, just add an additional nullcheck:
Boolean dtoChecked = checked.get(dTO.getId());
if (dtoChecked != null && dtoChecked) {
// ...
}
This however doesn't fix the underlying cause of your problem. My best guess would be that the toVerifyTxnDTOList contains more items than actually being displayed in the table. Thus, it's one of the last mentioned two causes mentioned in the list. The first mentioned two causes are theoretically possible, but in practice I haven't seen this before.

Is this a bug in primefaces autocomplete?

I'm trying to put an autocomplete that fetches suggestions as a list of Entry<String, Integer>
<p:autoComplete completeMethod="#{suggester.suggestTopics}"
var="x1" itemLabel="#{x1.key}" itemValue="#{x1.value.toString()}"
value="#{topicController.selected}" />
Manged bean code is as follows:
private int selected;
public int getSelected() {
return selected;
}
public void setSelected(int selected) {
this.selected= selected;
}
But this fails saying the Integer class doesn't have method/property named key. If I remove the value attribute from autocomplete then it starts working properly. But when I put value attribute it starts expecting that the object inside var should be of the same type as that inside value attribute. I believe/expect it should be that the object inside itemValue should be of the same type as that inside value attribute.
I want to use POJOs for suggestions but pass just the entity Id to the value
Using :
Primefaces 3.1
JSF 2.1.6
I believe/expect it should be that the object inside itemValue should
be of the same type as that inside value attribute.
Yes this makes sense, and it is the same in the primefaces showcase:
<p:autoComplete value="#{autoCompleteBean.selectedPlayer1}"
id="basicPojo"
completeMethod="#{autoCompleteBean.completePlayer}"
var="p" itemLabel="#{p.name}" itemValue="#{p}"
converter="player" forceSelection="true"/>
As you see is var="p" and itemValue="#{p} where p is an instance of Player. And selectedPlayer1 is also an instance of Player.
I don't know if it works with a Map since the Primefaces example is called "Pojo support" and the suggestions should be a List of elements of the same type as in the value attribute.
I think you want to use the Simple auto complete , but instead you looked at the wrong example on the showcase of the Pojo Support
x1 refers to the int selected - while it expect to be referred to a POJO (with key and value properties.) , that's why you get the message
Integer class doesn't have method/property named key
Or simple use the Simple auto complete
As commented to Matt you dont need to rebuild Player(Pojo) from Db. You can set simply id property of Player(Pojo) and in action method may be utilize this id to fetch it from DB.
In your case in convertor you might do
Entry<String, Integer> e = new Entry<String, Integer>();
e.setId(value) // where value is passed in to convertor in method getAsObject.....
This value will be set to private Entry<String, Integer> selected
I have used Pojo autocomplete but not tried with generic classes.
Hope this helps.
I know the question is outdated but I've had the same problem.
The point is that you have to assign var to p (var="p"). I think it's terribly unobvious (documentation doesnot mention it has to be that way) 'cause I thought I can assign any var name I want.

Bind the value of an input component to a list item by index

here is an example :
<h:outputLabel for="category1" value="Cateogry"/>
<h:selectOneMenu id ="category1" value="#{articleManageBean.categoryId1}"
converter="categoryConverter">
<f:selectItems value="#{articleManageBean.categories}" var="category"
itemValue="#{category.id}" itemLabel="#{category.name}" />
</h:selectOneMenu>
and here is the managed bean that I have
#ManagedBean
#SessionScoped
public class ArticleManageBean {
private Long categoryId1;
private List<Category> categories;
//...
}
The categories list gets populated from db, and selectOneMenu gets populated with this list using a converter.
My First question:
If I want to create another selectOneMenu in my jsf page I would have to copy paste the entire thing and just change the value of selectOneMenu to say categoryId2 thus putting another attribute to managed bean called categoryId2. That is not practical. I want to map these values of selectMenu to list items, for instance to an attribute
List<Long> categoryIds;
if I use
<h:selectOneMenu id ="category1" value="#{articleManageBean.categoryIds.[0]}" >
I get an error
javax.el.PropertyNotFoundException: /createArticle.xhtml #47,68 value="#{articleManageBean.categoriesId[0]}": Target Unreachable, 'null' returned null
If I nitialize the Araylist then I get this exception
javax.el.PropertyNotFoundException: /createArticle.xhtml #47,68 value="#{articleManageBean.categoriesId[0]}": null
My second question:
Is there a way to dinamicly write selectOneMenu tags, by that I mean not to copy paste the entire tag, just somehow create a function that take the categoryId parameter and writes automaticaly the tag (somekind of custom tag maybe ?)
Hope you understood my questions
thanks in advance
Use the brace notation instead to specify the index.
<h:selectOneMenu id="category1" value="#{articleManageBean.categoryIds[0]}">
You only need to make sure that you have already prepared the values behind #{articleManageBean.categoryIds}. JSF won't do that for you. E.g.
private List<Long> categoryIds = new ArrayList<Long>();
public ArticleManageBean() {
categoryIds.add(null);
categoryIds.add(null);
categoryIds.add(null);
// So, now there are 3 items preserved.
}
an alternative is to use Long[] instead, this doesn't need to be prefilled.
private Long[] categoryIds = new Long[3]; // So, now there are 3 items preserved.

Using h:outputFormat to message-format the f:selectItems of a h:selectOneRadio

I am having some trouble with using h:selectOneRadio. I have a list of objects which is being returned which needs to be displayed. I am trying something like this:
<h:selectOneRadio id="selectPlan" layout="pageDirection">
<f:selectItems value="#{detailsHandler.planList}" />
</h:selectOneRadio>
and planList is a List of Plans. Plan is defined as:
public class Plan {
protected String id;
protected String partNumber;
protected String shortName;
protected String price;
protected boolean isService;
protected boolean isOption;
//With all getters/setters
}
The text that must appear for each radio button is actually in a properties file, and I need to insert params in the text to fill out some value in the bean. For example the text in my properties file is:
plan_price=The price of this plan is {0}.
I was hoping to do something like this:
<f:selectItems value="<h:outputFormat value="#{i18n.plan_price}">
<f:param value="#{planHandler.price}">
</h:outputFormat>" />
Usually if it's not a h:selectOneRadio component, if it's just text I use the h:outputFormat along with f:param tags to display the messages in my .property file called i18n above, and insert a param which is in the backing bean. here this does not work. Does anyone have any ideas how I can deal with this?
I am being returned a list of Plans each with their own prices and the text to be displayed is held in property file. Any help much appreciated.
Thanks!
I am now able to resolve the above issue following the recommendation below. But now I have another question.
Each radio button item must display like this:
Click **here** to see what is included. The cost is XX.
Now the above is what is displayed for each radio button. The "here" needs to be a hyperlink which the user can click and should bring up a dialog box with more info.I can display the sentence above but how do I make the "here" clickable?
Since the above is what is displayed it is the label for SelectItem(Object value, String label) which is returned.
Any ideas much appreciated.
The value passed to <f:selectItems /> must be a list or array of type javax.faces.model.SelectItem.
You can set the output label in the constructor of the SelectItem. I imagine you can access your properties file from the backing bean. The method to get the SelectItems would look something like this:
public List<SelectItem> getPlanItems() {
List<SelectItem> list = new ArrayList<SelectItem>();
for (Plan plan : planList) {
String label = buildPlanPriceLabel(plan.getPrice());
list.add(new SelectItem(plan, label));
}
return list;
}
Leaving buildPlanPriceLabel as an exercise for the reader.

Resources