Init method is not filled in even with parameters - jsf

I have lost a few hours trying to figure out why I can not retrieve the parameters of my link. Following this question, I did my link with passing parameters. My problem is relatively easy, if I can get the parameters in the popup that opens when the user clicks the link. Except that I can not get them.
My class has a method annotated with #Create that every time the object is initialized it executes this method.
The only way I can get the idsess_ parameter is in the URL, but I can not pass any parameters I want the URL.
In short, by clicking on my <a:commandLink> wish the <f:param>'s were passed to the bean in a matter and the same to process according to these parameters.
Edit: changed my code and created my own action. In this case I was reusing an action of another view. I recreated my action and used the method described in the answer that was accepted

Not sure what your <a:commandLink/> component is? (Im assumed you re-mapped a4j:commandLink somehow?)
I think the problem you are having is that the #RequestParameter variables are only populated when the page first renders, when you click the commandLink you are performing a postback so the values are lost.
You should try doing a redirect instead (ie. using <s:link> with <f:param> rather than commandLink) or you can pass the parameters using pages.xml to bind the request params, using this markup:
<page view-id="/your-page.xhtml">
<param name="pId" value="#{bean.variable}" required="false" />
<action execute="#{bean.action}" />
</page>

Related

Getting a null value passed to a Java function via BootsFaces datatable

I am trying to create a modal to send user-selected requests to an email address; however, I am having trouble getting the user-selected requests. I keep getting the null value passed through fooBean.setSelected(id).
Versions:
BootsFaces: 1.3.0
Java: 1.8.0
JSF: 2.0
Browser: Internet Explorer 11.2x
MCVE of thisThing.xhtml:
<b:dataTable value="#{fooBean.newRequests}"
var="foo"
onselect="ajax:fooBean.setSelected(id)"
ondeselect="ajax:fooBean.setSelected(id)"
selectedItems="row"
selection-mode="multiple"
selectedRows="#{foo.selected}"
saveState="false">
<b:dataTableColumn label="Select">
<b:selectBooleanCheckbox value="#{foo.selected}" />
</b:dataTableColumn>
<b:dataTableColumn label="Status" value="#{foo.status}" />
<b:dataTableColumn label="Request Number"
value="#{foo.requestNumber}"
data-type="string" />
<b:dataTableColumn label="ID" value="#{foo.id}" />
<b:dataTableColumn value="#{foo.storeName}"
label="Store Name" />
</b:dataTable>
MCVE of fooBean.java:
#ManagedBean(name="fooBean")
#ViewScoped
public class fooBean extends BeanBase implements Serializable {
private List<FooRecord> fooRecords = new ArrayList<FooRecord>();
private List<FooRecord> selectedFooRecords = new ArrayList<FooRecord>();
// ...
public void setSelected(String requestId) {
// This is not how I really do it, but it gives an idea
// with what I intend to do.
this.fooRecords.stream().filter(...).toggleSelection();
this.selectedFooRecords.stream().filter(...).toggleSelection();
}
}
Update:
I found out that I had the method called as getSelect instead of getSelected, so I fixed it and that part is done. I just remembered the real issue which is why a null parameter is being passed instead of the requestId. When I debug through the fooBean.getSelected(String requestId), it shows null being passed through as parameter. I have even tried:
<!-- Using varName.property -->
onselect="ajax:fooBean.setSelected(foo.id)"
<!-- Using just the property name -->
onselect="ajax:fooBean.setSelected(id)"
<!-- Using the loop variable -->
onselect="ajax:fooBean.setSelected(foo)"
Update 2:
How do I pass foo.id to the function?
There are only three parameters you can pass to the bean method:
The loop variable. In your example, that's foo. This parameter only works if the attribute selected-items is set to rows. Caveat: if you activate column or cell select mode, this parameter is still passed to the server, and it seems to be valid. Only that every attribute of this object is null.
typeOfSelection. This is either "row", "column" or "item". It determines what the user has selected. That, in turn, is determined by the attribute selected-items, so you hardly ever have to use this parameter. Just omit it from the parameter list.
indexes tells the JSF bean which rows, columns or cells have been selected. Note that in the first two cases this is either an individual number or - if multiple items have been selected - a comma separated list. If you've set selected-items="cell", indexes is a comma-separated list of objects containing the row and column index.
I suppose indexes or foo is the most useful parameter in your case.
Final remark: we'd like to add more flexibility, but this requires much more understanding of the internal API of JSF than even we have. Truth to tell, I'm not even sure we can pass arbitrary bean values without modifying the JSF engine itself. If anybody knows how to do that, please leave a message at our bug tracker.
Update:
Maybe the problem is caused by the modal. The modal is rendered at load time, but shown later, when the user has selected a row. Thing is, the modal isn't re-rendered automatically unless you add the content of the modal to the update attribute.

jsf get disabled field values in requestscoped bean

Could you please give me some directions on how to pass values from disabled or readonly input fields in xhtml page to requestscoped bean?
I thought that I can bypass jsf checking the field state by disabling
fields in javascipt code on form open and then submit form, but that
did not help too.
I cannot use view scope, because I would have to set then almost
every page in my application in view scope.
It is very inconvenient to use hidden fields for this purpose,
because it would double the number of fields on the page.
Maybe I have missed some clean solution?
Thank you in advance for any help.
Disabling fields using JavaScript didn't work probably because you didn't enable them just before sending a form. Values of disabled fields are not sent (see input documentation).
For example the following code works perfectly well:
<h:form>
<h:inputText id="disabledinput" styleClass="disabled"
value="#{someBean.property}"></h:inputText>
<h:outputScript>
$('.disabled').attr('disabled', 'disabled');
</h:outputScript>
<h:commandButton action="#{someBean.action}"
onclick="$('.disabled').removeAttr('disabled'); return true;"
value="Submit" />
</h:form>
onclick attribute executes JavaScript code that enables input just before sending the form.
If you use AJAX request you have to restore disabled state using oncomplete or similar.
The problem with this solution is that user can manipulate the value. E.g. she/he can use javascript console in a browser to change the input to enabled or use some tool (e.g. curl) to prepare or tamper request. So if the value is sensitive or should never be changed by the user consider storing the value in the session.
IMHO if the value was provided by the user in one of the previous steps then it doesn't matter that much. However, if value is calculated (like total value or something) you should not depend on its value as users could change it. Personally I would prefer to store the value on server side (in session or in flash).

JSF: Bookmarkability with ViewScoped

I am trying to make my app "Bookmarkable", and i am using view parameters to achieve it.
And i think i still do not get the right way to do it right in JSF, even after reading this, and many others.
My problem is that the get parameters get lost after any non-ajax postback, i mean, the parameter value is still set in the bean and the app works correctly, but it gets removed from the URL making the URL invalid.
For instance, having an URL like http://company.com/users?id=4, as soon as that page executes a non-ajax postback (for uploading data, for instance) the URL becomes just http://company.com/users. The app continues to work correctly, but the link is not any more "Bookmarkable".
Is there any way to prevent the non-ajax postbacks removing the viewParams from the URL?
My use case is to be able to bookmark a page to EDIT an object, and there i need to be able to upload data (if not i would not use non-ajax postbacks). I know i would not need any postback if i would want to bookmark the page to only VIEW the data of the object, but that is not my case.
I could also do a redirect to the same page with the same params, and let the app to recreate the view scoped bean, but then i really do not see any benefit over request scoped beans...
Any suggestion is very appreciated.
This behaviour is "by design". The <h:form> generates a HTML <form> element with an action URL without any view parameters. The synchronous POST request just submits to exactly that URL which thus get reflected as-is in browser's address bar. If you intend to keep the view parameters in the URL, while using ajax is not an option, then you basically need to create a custom ViewHandler which has the getActionURL() overridden to include the view parameters. This method is used by <h:form> to generate the action URL.
public String getActionURL(FacesContext context, String viewId) {
String originalActionURL = super.getActionURL(context, viewId);
String newActionURL = includeViewParamsIfNecessary(context, originalActionURL);
return newActionURL;
}
Or, as you're based on the comments already using OmniFaces, you could also use its <o:form> component which basically extends the <h:form> with the includeViewParams attribute which works much like the same as in <h:link> and <h:button>.
<o:form includeViewParams="true">
...
</o:form>
This way all <f:viewParam> values will end up in the form action URL.
See also:
Handling view parameters in JSF after post

How to set struts ActionForm attributes using <html:link>?

I need to do the thing like this (setting ActionForm attribute):
<html:form action="Link.do?method=editNews">
<html:hidden property="idNews" value="${news.newsMessage.idNews}" />
<html:submit value="EDIT"/>
</html:form>
But in <html:link> or regular a-href tag. So I don't want this parameter to apear in my link as a request parameter. Is it possible?
P.S. idNews is the parameter in my ActionForm class and it has setter and getter.
No, it's not possible. A link performs a GET request, and the only way for a GET request to send information to the server is to use request parameters, which appear in the URL.
The only thing you can do is to have your link invoke a JavaSCript function which submits a hidden form using POST. But it's ugly.
Why do you fear by making the parameter visible in the URL? Are you aware that anybody can view the source of your HTML page and see the hidden field here?

JSF: bean scope; session vs request

I have a managed bean called UserSearchHandler, it has a doSearch method that populates UserSearchHandler.searchResults which are displayed in a table on the userSearch.xhtml page.
I have another managed bean called UserHandler, it has a showUser method and so on.
In the search results table, the user name is a link that, when clicked, is supposed to show user details on a userView.xhtml page. The table and link looks like this:
<p:dataTable var="user" value="#{userSearchHandler.searchResults" >
// ... and so on ... then
<h:commandLink value="#{user.firstName}" action="#{userHandler.showUser}">
<f:setPropertyActionListener target="#{userHandler.userIdToShow}" value="#{profile.id}"/>
</h:commandLink>
Everything works fine when the managed beans are set to session scope.
However, when I change the scope on the beans to request, the search works and the table gets populated, but when I click on the name link nothing happens. I put a break point on the userHandler.showUser method and it never gets hit when the userSearchHandler is set to "request" scope.
Can anyone help explain why this is, or what I'm doing wrong?
That's because the #{userSearchHandler.searchResults} is empty during the new request and therefore JSF is unable to locate the associated row where the commandlink is been invoked in order invoke the action (and to pass/set properties if any).
You need to ensure that the same #{userSearchHandler.searchResults} is precreated during bean's construction/initialization. If it's to be created based on a specific set of parameters, then you've to pass them along with the form as well.
That's exactly the reason why solutions like Tomahawk's <t:saveState /> and new JSF 2.0 view scope exist.
See also:
What are the main disadvantages of JSF 2.0?
I have a couple of ideas. If you're using a in your navigation you can try taking that out. Doing so would mean the browser will not make a new HTTP request when it renders the second window. It is the new HTTP request which clears the request scoped beans by. If that is not an option, you may be able to pass a parameter in your link such as a record id, which could allow you to pull data from your data source matching that id.

Resources