<p:pickList> not clearing after RemoveAll button - jsf

I am encountering a strange problem with <p:pickList>. When I open a dialog having this pickList and clear all items from target list using the RemoveAll button and submit using <p:commandButton> the old items in the target list still appear. I have given the attribute required=true for the pickList. The strange behaviour is when I submit it, a tooltip appears saying that the field is mandatory.
So if the items are clearing and required attribute is working fine, why are the old items reappearing? What is the solution for this?
<p:pickList id="selectedId" value="#{someDialog.selectedItem}"
var="item" itemValue="#{item}" required="true"
converter="pickListConverter" requiredMessage="#{msg.required_message}"
styleClass="#{component.valid ? '': 'ui-state-error'}">
</p:pickList>
EDIT: Backing Bean - I am posting only the relevant method.
SomeDialog.java
private DualListModel<Item> selectedItem = new DualListModel<Item>();
//Its getters and setters
public final void afterSave(final ParamObject pObject) {
pObject.getRelevantData().clear();
pObject.getRelevantData().addAll(selectedItem.getTarget());
}
ParamObject .java
private List<Item> relevantData = new ArrayList<Item>();
//Setters and Getters

As #Xtreme Biker mentioned its in your backing bean.
When first time you submit list, you set it in backing bean. Second time you open dialog, it is already there. Even if you press RemoveAll, it removes only in your browser, it doesn't work with backing bean. And your submit will not work, because you have required=true.
So you can choose one of this options:
remove required=true and after every submit you will need press RemoveAll and submit again empty list (its not an option).
after doing all required tasks in backing bean, clear someDialog.selectedItem value, update and close dialog.
every time you open dialog clear someDialog.selectedItem value in backing bean.
I hope it will help as I am new in here too.

Related

Bean initialization JSF (Primefaces)

when is a bean initialized? I used #RequestScoped managed bean annotation.
I have a page - products.xhtml and I am redirecting on the same page depending on the version a clicks.
For example, user clicks 2019.000, it redirects to the same page~
/products.xhtml?faces-redirect=true&ver=2019.000
My problem is I have a dialog that opens when a user clicks on a p:commandLink. The bean needed to populate the dialog's contents is DownloadView.java::getRoot().
Here's a snippet of my DownloadView.java.
#ManagedBean(name = "DownloadView")
#ViewScoped
public class DownloadView implements Serializable {
private TreeNode root;
private String path;
public TreeNode getRoot() {
DownloadBI downloadBI = new DownloadBI(modifyPath(this.path));
this.root = downloadBI.getFilesTreeNode();
if (root.getChildCount() != 0)
this.root.getChildren().get(0).setExpanded(true);
return this.root;
}
. . .
The default selection when page loads is 2020.000. The dialog works perfectly fine with the correct target links when loaded from the default selection 2020.000. But, when I redirect to 2019.000 and try to open a dialog, it seems that the bean retained the data from 2020.000.
Here is a snippet of my p:commmandLink calling the dialog from products.xhtml.
<p:commandLink value="#{startup.name}" title="#{startup.name}"
process="#form" update=":download-form:downloadPanel"
oncomplete="PF('downloadDialog').show()" >
<f:setPropertyActionListener target="#{DownloadView.path}" value="#{startup.url}"/>
</p:commandLink>
I was assuming that the value of startup.url should change every time the commandlink is clicked. It does but, its the same value from 2020.000. While testing its behavior, I noticed that the form id is the same from 2020.000 and 2019.000.
From chrome source:
j_idt161:0:j_idt163:1:download-view
is the same when selecting from 2019.000. They should be different since they have different urls.
I thought that this is scoping issue, but I tried all scopes. But, it is still not working.
I am thinking that I should create my DownloadView.java bean only when the commandLink is clicked, and when the dialog is closed, it should also be destroyed. But, I am not sure how to do this as well. :(
I have been debugging this for days now and I'm stuck. I hope someone could give some ideas how to resolve this. I am new to JSF/Primefaces, by the way. Please help!

Why does returning empty string from action method not recreate view?

I have a JSF page with a form that contains multiple textfields (p:inputtext) and a submit button. The page is backed by a ViewScoped backing bean. When the submit button is hit, an action method is called that returns an empty String ("").
According to this answer of BalusC, returning an empty string will refresh the view and recreate the ViewScoped backing bean.
However, when I submit my filled out form, the reloaded page still retains all my text input. How is this possible? Shouldn't the form be empty since the backing bean and view have been recreated?
#dmatob is right. When you have a JSF page backed by a ViewScoped bean:
If the method returns null, the bean won't be recreated (the values stay the same) but the page is reloaded.
If the method returns the same or another page, the bean will be recreated (it resets the values) and the page is reloaded.
I was facing the same few hours ago: trying to reset the values when the method is successfully executed. So after reading around and around, I found something that finally worked out:
You have to use action instead of actionListener (Differences here)
<p:commandButton value="Save" action="#{backingBean.save()}" />
So the method must return a String
public String save(){
if(validations==true){
return "currentpage.xhtml?faces-redirect=true";
}
return null;
}
When everything is okay, it will recreate the bean, refresh the page and reset the values. Otherwise the method returns null so it will refresh the page but the bean.
[EDITED]
If the method is returning null or empty String, the bean isn't recreated: the PostConstruct (init event) isn't being triggered, so that means the values stay the same. On the other case, if it returns a String (redirecting to some page), the init event is called so the values are initialized.
The JSF page is reloaded in both cases: when returning null/empty String or not.
Hope it helps you... Let me know ;-)
In a view scoped bean, only when your action method returns null, the bean doesn't initialize again.
If you want the action method to go back to the submitted form and reload the bean, your method must return the name of the page that contains the form.

Cancel button jsf not resetting entity

I'm trying to implement a cancel button to clear the fields from my entity.
Though, when I'm setting the entity to null my fields still keep their value.
Code:
The EntityBB's cancel method (note that the debugger can reach the cancel method):
public void cancelAddStandardLetter() {
setEntity(null);
standardLetterInit();
}
this method really sets all the values from the entity back to null and the standardLetterInit method sets some default values that are needed (tried the same method without the standardLetterInit -> same result).
The xhtml page (other inputfields are left out):
<o:form includeRequestParams="true" id="addStandardLetterForm">
<h:inputTextvalue="#{entityBB.entity.fileName}" styleClass="rInput"/>
<h:commandButton value="Cancel" immediate="true"
styleClass="floatRight"
action="#{entityBB.cancelAddStandardLetter()}" />
</o:form>
After pressing the "cancel" button, the values being typed in the "fileName" field are still there. How can that be?
Make sure that the bean is view scoped and use a plain GET button.
<h:button value="Cancel" />
This basically refreshes the page. It'll recreate the view scoped bean instance. No need to submit the whole form. If the input values still appear, then it's either the browser cache or autocomplete/autofill which you in turn can control with respectively a servlet filter and autocomplete="off".

JSF binding with setValueExpression read-only?

I try to create an InputField in the backing bean and add it to the view, but the databinding seems to work just read-only.
I create a UIInput in the Backing-Bean like this:
UIComponent textInput = new UIInput();
textInput.setId("operandInputText");
textInput.setValueExpression("value", ef.createValueExpression(elCtx, "#{row.operandValues[0]}", String.class));
textInput.setValueExpression("rendered", ef.createValueExpression(elCtx, "#{row.inputType == 'text'}", Boolean.class));
mInputPanelGroup.getChildren().add(textInput);
The panelGroup is inside a column of a dataTable and bound to the bean:
<p:column id="operandColumn">
<h:panelGroup id="inputPanelGroup" binding="#{locateEmployeeBean.inputPanelGroup}" >
<h:inputText id="testInput" value="#{row.operandValues[0]}" />
</h:panelGroup>
</p:column>
The <h:inputText/> inside the PanelGroup is just for testing and this is where I found out that the binding I did with setValueExpression(...) works at least read-only.
In the browser I now have 2 inputFields, first the 'testInput' and then 'operandInputText'.
When I enter a value in 'operandInputText' and submit, the value does not get saved, but when I enter a value in the 'testInput'-Field, it get's submitted and in addition the value gets displayed in BOTH inputFields.
The operandValues is a simpe object array:
private Object[] mOperandValues = new Object[2];
Could this have anything to do with the dataType I pass to setValueExpression(...)?
I tried Object, but that didn't change anything.
Any idea why this happens?
Thanks in advance!
I found the solution to my problem. Honestly it was an article by #BalusC Using Datatables: Populate datatable what took me on the right path.
Previously I added the components during PreRenderView-Phase, then I saw in your example that you populate the bound component ONCE in the getter (which is then obviously way earlier during RestoreView-Phase). That is how I've done it now and it works flawlessly, the Inputfields now work both ways (read+write).
Thanks alot for your work #BalusC!

Data in <h:inputText readonly="true"> disappears when command button is clicked

I am using JSF 1.1. I have a JSF page with a request scoped bean and a readonly input field.
<h:inputText id="dt" value="#{bean.sdate}" readonly="#{bean.disable}" />
<a onclick="cal('dt');"><img src="fr.gif" border="0"></a>
When I set the input value using JavaScript and click on command button, then the data in input field disappears.
How is this caused and how can I solve it.
That's because the property is set to readonly. If this evaluates true, then JSF won't process the submitted value and hence the model won't be updated. If you want to set it to readonly on rendering the view and have JSF to process the submitted value, then you'd need to make it to evaluate true on render response phase only. You can use FacesContext#getRenderResponse() for this. You'd need to do this in your isDisable() method.
public boolean isDisable() { // TODO: rename to isReadonly().
return FacesContext.getCurrentInstance().getRenderResponse();
}
Note: in JSF2 you could access FacesContext#getCurrentInstance() by #{facesContext} in the view as well, this saves some boilerplate in the model:
<h:inputText ... readonly="#{facesContext.renderResponse}" />
Also note that when you're using JSF2 <f:viewParam>, then this approach won't work on GET requests anymore. See also Make a p:calendar readonly for the explanation and workaround.

Resources