Passing value from javascript prompt to managed bean - cdi

Is it possible to pass a value from a popup prompt to a CDI managed bean somehow like this:
h:commandButton image="/resources/images/editButton.png" onclick='mytext = prompt("Enter text: ")' action='#{myBean.foo(mytext)}'
The prompt opens, the foo method is called, but how do I pass the mytext value?

You would need to create a hidden input, change your JS to set the value of that input on the hidden field and send that to the server.

Related

Problem with Primefaces Autocomplete Component

I have a local Web Application developed with JDK 8, JSF 2.2 (implementation provided by JBoss), Spring 4.2 and Primefaces 6.2
In the application, I have one XHTML page for edit some fields of an object that is instance of a class named SiepRoEncabezado. One of those fields is an instance of SiepRpaPescador.
Until yesterday, I had one <p:selectOneMenu> contained in a form that is contained in a modal dialog in order to select one SiepRpaPescador object. The modal itself has 2 submit <p:commandButton> (one for save the changes and one for clean the form) and some aditional input fields.
The modal is developed in such manner that it closes automatiquely when the data is successfully edited after I push the save button.
The modal with the <p:selectOneMenu> worked fine, but due to the fact that there are too many select items to be handled in terms of memory usage, I was forced to replace the <p:selectOneMenu> by the following component:
<p:autoComplete dropdown="true"
id="rpaAutoComplete"
value="#{correccionROBean.tmpPescador}"
var="itemRpa"
itemLabel="#{itemRpa.nmPescador.concat(' ').concat(itemRpa.nmPaterno).concat(' ').concat(itemRpa.nmMaterno)}"
itemValue="#{itemRpa}"
completeMethod="#{correccionROBean.filtrarRpa}"
minQueryLength="4"
maxResults="10"
forceSelection="true" />
There, tmpPescador is a bean in the Managed Bean CorreccionROBean.
The complete method there works fine and the selection items are displayed as desired.
However, after I select one item in the <p:autoComplete> component and push the button to save the changes, it does nothing at all. Also, it does not display an error message and it does not throw any exception. What is worst, if I try to debug the action listener method in the button to save changes, it does nothing, it's like the action listener method is not called at all.
I put an <p:ajax> tag hoping to solve the problem with no avail:
<p:autoComplete dropdown="true"
id="rpaAutoComplete"
value="#{correccionROBean.tmpPescador}"
var="itemRpa"
itemLabel="#{itemRpa.nmPescador.concat(' ').concat(itemRpa.nmPaterno).concat(' ').concat(itemRpa.nmMaterno)}"
itemValue="#{itemRpa}"
completeMethod="#{correccionROBean.filtrarRpa}"
minQueryLength="4"
maxResults="10"
forceSelection="true">
<p:ajax event="itemSelect" listener="#{correccionROBean.onRpaSelect}" update="rpaAutoComplete"/>
</p:autoComplete>
Here, when I select one item, the listener method is not triggered. When I try to debug the method, it's like the method is not called at all.
Finally, when I push the save button without selecting an item in the <p:autoComplete>, then and only then, the action listener method in the save <p:commandButton> is triggered.
What may cause this behaviour?
Thanks in advance.
EDIT
I added the field immediate="true" to the autocomplete component and that triggered the ajax submit method, but still cannot execute the save button action listener method
SOLVED.
Refeer to Melloware's answer and my reply to that answer for more details.
For those that are unfamiliar with Converters:
The interface Converter, defined in JSF's API, allows to convert the data inputted and outputted to a Auto Complete component (and some other JSF UI components as well and their sub-classes). This interface has two methods:
public Object getAsObject(FacesContext context, UIComponent component, String value): This method must return an Object that is instance of the same class as the value defined in the value field of the Auto Complete component (in my case, it returns a SiepRpaPescador object). You must handle exceptions in this method as it is called automatiquely in two situations:
When you input characters in the Auto Complete text field and the number of inputted characters are equal or greater than the value defined in the minQueryLength field of the Auto Complete component or it's default value if not specified (in my case, when I input 4 characters or more). In this case, the value parameter in this method will be the String you inputted. Notice that if you enabled dropdown (dropdown="true")as in my case and you push the dropdown button, this method is NOT called.
When you submit the form. In this case, the value will be the value of the labelValue field in the Auto Complete component (in my case, #{itemRpa.nrFolio}) converted to String using the toString method defined in the class that value is instance of (#{itemRpa.nrFolio} is an Integer, so the value will be converted using the Integer class' own implementation of toString()) or in the Object class if no implementation of toString() is defined.
public String getAsString(FacesContext context, UIComponent component, Object value): This method must return a String representation of the label value of each item to be displayed in the Auto Complete component. The parameter value is an instance of the same class as the value defined in the labelValue field of the Auto Complete component. This method is called automatiquely when the items are displayed (it doesn't matter if you inputted characters in the Auto Complete's text field or pressed the dropdown button if present) and it's called as many times as defined in the field maxResults (in my case, 10) in the Auto Complete, using the objects obtained from the returned list of the completeMethod (in my case, from each object in the list obtained from #{correccionROBean.filtrarRpa}, this method obtains it's nrFolio, as I stablished in the labelValue field of the AutoComplete).
I hope this helps to you all

JSF Trouble with beans (scope)

So I was testing my JSF application and suddenly I can't pull the value I stored in the bean anymore. I switched from Request scope to Session scope and I was able to pull a value, but it seems to be the value of the last page I clicked.
File structure goes something like this:
About.xhtml sets a page number stored on the Bean and then calls Layout.xhtml which calls Bean.Method() to get Content_About.xhtml to load some text to the page depending on the page number declared in the About.xhtml file.
To my understanding the Request scope should work as long as I don't need to access the stored information past the page loading, but it is acting as if the page number hasn't been set.
With a Session scope declared, it loads the text, but it seems as if it is building the page, then changing the stored value in the bean. It requires that I click on the page I want twice to get the correct information on a page.
Any help appreciated.
Further investigation: I am able to do the following, but it shows the correct page number before and after the method call to load the content.
Page Number: #{MainBean.getPage()}
<h:form>
<ui:include src="#{MainBean.Content()}"></ui:include>
</h:form>
Page Number: #{MainBean.getPage()}
Accepting that the ui is built first, using the default value of the stored variable, I proceeded to set the value in the ui declaration when layout is called.
I had something like:
#{MainBean.setLevel(0)}
#{MainBean.setPage(1)}
<ui:include src="Layout.xhtml"></ui:include>
and changed it to:
<ui:include src="#{MainBean.setLayout(0,1)}"></ui:include>
public String setLayout(int lvl, int pg)
{
setLevel(lvl);
setPage(pg);
return GetPath()+"Layout.xhtml";
}
This allows the bean's variable to be set during the construction of the ui and carry forward through the rest of the request.

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).

adf managed bean retrieving a value from input text

I'm trying to retrieve a value from an input text in my jsf page, but when I change its value it doesn't change in the managed bean.
here's the input text:
<af:inputText label="Código:" id="codigo" value="#{tipoBaixaBean.codigo}"/>
and my managed bean is annotated like this:
#ManagedBean
#RequestScoped
public class TipoBaixaBean {
private long codigo;
I have the getters and setters, but the value of the property "codigo" never changes,
What would be the problem??
Thank you
Change your Bean scope to 'pageFlowScope' or 'viewScope' in adfc-config.xml . That should do.
You don't say when you are trying to get the value...on page submit or when you tab out of the field. If you want the value when you tab out (lose focus) then set the autoSubmit property on the input text field to true.
I would also suggest using a print statement in set method to make sure it's being called. The scope issue only arises if you are trying to retain the value between page requests.
Not sure how can you bind an inputText to a long object in backing bean.
Ideally it should be something like
private RichInputText codigo;
you can get the value of codigo using the getter.
getCodigo.inputValue();
I don't think scope will cause any problem. It works for the least life scope i.e. backing bean scope.
It really depends on the exact moment in which you are getting/setting the value, but if you need to do it automatically every time a change occurs, then you'll need to implement the Value Change Listener. Check this out: Value Change Listener example

How to call an action method of a UICommand Component which was rendered conditionally?

action method is not called Please refer to this question - , One of my UICommand Component is rendered conditionally , it was said in the answer of the linked question - point 5 - that if the Component's or any of its parents rendered or disabled attributes are false - then the action method will not be called ? If thats the case- How do i achieve the same functionality? Is there a work around ? or a trick ? or any other approach ?
Thanks!
To the point, you'd like to retain the property responsible for the rendered condition in the subsequent request. There are several solutions for this problem:
Put bean in session scope. It's easy, but it hurts. It's bad for user experience since changes will be reflected in all tabs/windows the user has open in the same session.
Use <h:inputHidden> to transfer the property. In theory easy, but in practice it hurts as well. The value will namely get lost whenever a validation/conversion error has occurred in any of other inputs in the same form. This is an odditity in how JSF handles hidden input elements. A workaround is to use <h:inputHidden binding="#{bean.hidden}"> and do a hidden.getValue() and hidden.setValue() in bean.
If you're using <h:commandLink> instead of <h:commandButton>, then you can use <f:param> to transfer the property. It will be available as request parameter, you can check for it in bean's (post)constructor.
Use Tomahawk's <t:saveState>. The perfect solution as far. This will retain the value (or even a complete bean) in the subsequent request.
If you're already on JSF 2.0, the #ViewScoped would have solved this all. It behaves like the <t:saveState>.
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated
The trick is to have 'rendered' evaluate to true when it is time to run the action and then change the condition to false in the action method.
Let's say you have a link rendering based on a boolean in your bean called 'editing'. Then your action would look something like this:
public String myAction() {
// whatever you want your action to do
editing = false;
}
Edit: this assumes that the bean is either session scoped or the boolean get propagated between requests.
In my case, Javascript came for rescue, Which means, whatever was to be displayed conditionally , put them in a HTML Portion and don't display them display: none until the desired event occurs.
HTML Portion can have any JSF Tags(including CommandButtons) as you wish and would work (invoking the action methods and the stuff )perfectly okay.

Resources