Disable/enable commandButton depending on required fields of current form? - java

What is the best approach to disable a commandButton if the fields with required=true are not filled with values?
The button should be disabled on first page load, and only be enabled in case all required fields are fields with values.
By best approach i mean no javascript and minimum-code :-)
In addition it would be excellent if the commandButton is only enabled when all validators evaluate to true.
Using PF 3.2
EDIT
by best approach i also mean, it should only be evaluate on client-side

This is not possible for two reasons.
For client side validation, you would definitely require javascript.
The required attribute of components is stored server side ONLY, the client has no idea of which fields are required by default.
Without using required, you could achieve this in client-side as following. validateContent should contain the logic to disable the commandButton.
<h:inputText value="#{bean.text}" >
<pe:javascript event="keyup" execute="validateContent();"/>
</h:inputText>
If going to server is okay, then you could do this:
<h:inputText id="test1" value="#{bean.text}" required="true" immediate="true">
<f:ajax listener="#{bean.makeDisable()}" render="test2" />
</h:inputText>
</h:commandButton id="test2" value="commandButton1" disabled="#{bean.disable}" />
And in the bean:
private String text;
private boolean disable;
// setter & getter of text
public boolean isDisable()
{
return disable;
}
public void makeDisable(AjaxBehaviorEvent event)
{
if(text == null || text.equals(""))
this.disable=true;
else
this.disable=false;
}
This basically will load the commandButton disabled on initial load and it will only be enabled on entering any value in text field.

It is possible but I would hardly call it the "best way".
You would need to supply an ajax tag for change events on each field. Each field would have to be immediate to skip initial validation and process will need to be set to #this.
In an event listener you can check if values exist for each of the required fields and if so then set a boolean field that determines if the commandButton is disabled or not.
These ajax tags will need to render #this as well as the commandButton.
But even then there is a LOT of Javascript actually going on, just none that you would have to write directly.

Related

Set a dynamic value for the "disabled" parameter of the struts radio

so i am tring to create a struts radio that will show elements (throught a list passed into the parameters "list" and "listKey".
What i am trying to add to that is that some radios will be read-only (based on some field declared on a server-side bean).
So struts radio is like this in the jsp :
<s:radio id="radioStatutType"
name="radioStatutType"
theme="extend"
templateDir="template"
list="statList"
listKey="myId"
listValue="label"
onclick="checkType();"
disabled="disabRgt" />
So the fields "myId" and "label" are declared in the same bean and they both work perfectly (so the scope is correct i think).
Same as these two fields, i declared a String named "disabRgt" (in the bean) that is filled with true/false (with a toString on a boolean calculated with some code). I declared the setter and getter but when displaying the jsp (and the radio) this field is not used (i verified throught debug watchpoint access/modification).
So i changed this field into boolean (primitive) and it did not work. Finally, i changed the getter into "isDisabRgt" instead of "getDisabRgt" => Same result ..
So it seems that the field "disabRgt" is never evaluated and that the "disabled" parameter in the radio is always filled with the default value (which is false).
Hope i explained it well ! Any ideas ?
Since disabled="%{myBoolean}" doesn't evaluate the expression, you must do it in some other way:
Using <s:if> on the variable to display the radio enabled or disabled:
<s:if test="%{disabRgt}">
<s:radio ... disabled="true" >
</s:if>
<s:else>
<s:radio ... >
</s:else>
Disabling it with Javascript:
<script>
$(function() {
if (<s:property value="%{disabRgt}"/>){
$("#radioStatutType").prop( "disabled", true );
}
});
</script>
Just remember to always use booleans, never voodoos like Boolean's toString()s ;)

How to get the value of disabled check box in Spring MVC

I am working on Spring MVC application and I am having a problem of getting the value of the check box when it is disabled.
in report.jsp page :
<form:checkbox type="checkbox" path="corporateColumn" id="corporateColumn" value="true" checked="checked" disabled="true" />
in ReportForm.java :
boolean corporateColumn ;
public boolean isCorporateColumn() {
return corporateColumn;
}
public void setCorporateColumn(boolean corporateColumn) {
this.corporateColumn = corporateColumn;
}
In ReportController.java ;
boolean corporateColumn = reportDTO.isCorporateColumn(); // this evaluates to false
//Which expected as true when corporateColumn checkbox is checked
Everything works fine unless it is used as disabled="true" (/ disabled="${'true'}") for checkbox field.
I had the similar issue previously also when getting the value of a disabled textfield and overcome it by making the field readonly.
So I am not sure in Spring MVC whether it is not possible to get the value of input field when it is disabled.
Any guidance would be really appreciated.
Thanks!
It's sorry to say that but that's impossible.
Use developer tool(like in Chrome) to check posted data, you can confirm browser will not send your checkbox's data if it's disabled or unchecked.
Why don't you simply use 'readonly' instead of 'disabled'?
Disabled field data is not passed on to server.

JSF Link not working (with Primefaces)

Sorry, really really basic question...
I've got a list of 'messageboard threads' that I display on a page. I want to be able to click on one of them and redirect to a page which displays the details for that thread. I'm struggling despite googling it for a while...
(I'm using PrimeFaces by the way)
Here's the relevant code from my 'list' page:
<p:commandLink value="#{thread.title}" action="#{messageboardBean.showThread()}">
<f:param name="threadId" value="#{thread.id}" />
</p:commandLink>
(it's in an h:form element)
This is part of my named bean (other methods work fine)
...
#ManagedProperty(value="#{param.threadId}")
private Long threadId;
...
public String showThread() {
System.out.println("id is " + getThreadId());
return "messageboard/list";
}
...
As you can see my method isn't implemented yet, but it's not even being called. Please can someone tell me why?
I tried with an h:link too by the way, same (or similar) problem.
Thanks!
UPDATE - Solved
Thanks to the help below, here is my solution (I've renamed 'messageboard' to 'discussion').
The link is generated using this code
value: what to display on the page, in my case the title of my discussion
outcome: refers to edit.xhtml, the faces file I want to go to
...and the [request] param is going to be called 'threadId' and has a value of the id attribute in my 'thread' object.
In the edit.xhtml page, I've got this
<f:metadata>
<f:viewParam name="threadId" value="#{viewDiscussionBean.threadId}" />
<f:event type="preRenderView" listener="#{viewDiscussionBean.loadDiscussion}" />
</f:metadata>
Note that 'threadId' is the same as the param name in the first page, and it is bound to my viewDiscussionBean's threadId property.
Then once the params are all set on my bean, I call the loadDiscussion method of my viewDiscussionBean. Since it now has the threadId property, it's able to do this (see below)
My viewDiscussionBean has the following managed property (I think the viewParam tag sets this, rather than the other way around).
#ManagedProperty(value="#{param.threadId}")
private Long threadId;
private Discussion thread;
So once that's set, this method is able to run (because it now has an ID)
public String loadDiscussion() {
thread = mbDao.find(threadId);
return "edit";
}
This just uses a DAO (using Hibernate) to look up the discussion thread with that ID, and set it in the bean. And then...
In my edit.xhtml page, I can access values in the discussion thread using things like
<h:outputText value="#{viewDiscussionBean.thread.message}" />
Voila! Thanks.
There are many possible caused for an UICommand action not being invoked. You can find them all here: commandButton/commandLink/ajax action/listener method not invoked or input value not updated Among others a missing form, a nested form, or a conversion/validation error elsewhere in the form, being in a datatable whose datamodel is not properly preserved, etcetera.
As to your particular functional requirement, better is to use a <h:link>. A command link issues a POST request which does in your particular case not end up with a bookmarkable URL with the thread ID in the URL. A <h:link> creates a fullworthy link which is bookmarkable and searchbot-indexable.
E.g.
<h:link value="#{thread.title}" outcome="messageboard/list">
<f:param name="threadId" value="#{thread.id}" />
</h:link>
This doesn't require a form nor an action method. You only need to move that #ManagedProperty to the bean associated with messageboard/list, or maybe replace it by <f:viewParam> in the messageboard/list view which allows for finer-grained validation/conversion.
See also:
Communication in JSF2 - Processing GET request parameters
When should I use h:outputLink instead of h:commandLink?
ViewParam vs #ManagedProperty(value = "#{param.id}")
Your best bet it probably to go with BalusC's answer and use <h:link>. However, I have some thoughts about the behavior you're seeing.
Primefaces <p:commandLink> (like <p:commandButton>) uses ajax by default. Therefore, there won't be any actual navigation resulting from returning an outcome from your action. This could make it look like your action isn't being invoked. Try adding ajax=false to your <p:commandLink>.
When using <h:link>, navigation is resolved when the link is rendered rather than when it's clicked. Modifying your example:
<h:link value="#{thread.title}" outcome="#{messageboardBean.showThread()}">
<f:param name="threadId" value="#{thread.id}" />
</h:link>
showThread() will be called (I think) when the view containing the link is being rendered. If you're not checking at the right time, this may also make it look like the method is being called.
In both cases, this doesn't explain why you wouldn't see the message to System.out at all, but I know I've tried that thinking it was fail-safe and still not seen the output, which all depends on your container, configuration, how you launched it, etc.

In JSF - Trying to achieve something similar to "#{bean.run(3)}"

I would like to add buttons dynamically from a backing bean to a JSF page (supporting Rich Faces as well).
The value of the buttons needs to be determined in run time and returned to the backing bean when the button is pressed. (Hence the title - I am actually trying to be able to do something like "#{beans.run(3)}", i.e - set a fixed parameter to be used when clicking a button)
So for example, if the user creates a button (on run time) and gives the button a value. This value should be returned to the backing bean to be analysed.
My question - How do I assign a button (the button is a JSF component with a4j:support child) with a value at runtime? (I tried using a4j:actionParam, but couldn't manage to work it out)
P.S - I've overhauled this question to be shorter and more to the point from the original-too-long-question
There are a number of opions:
use JSF 2.0
use JBoss EL extension
use <f:setPropertyActionListener value="3" target="#{bean.propety>, where propety is later read by the run() method.
<h:commandButton action="#{bean.run}">
<f:setPropertyActionListener target="#{bean.property}"
value="#{pageVariable}" />
</h:commandButton>
<!-- pageVariable contains the number you are passing -->
public class Bean {
private int property; // with setters and getters
public void run() {
// do something with property
}
}
use Facelets functions (here's an example for such a function) (not applicable in all cases)

Passing data from request ManagedBeans in JSF

I'm somewhat confused about the lifecycle of ManagedBeans of type "request".
In this example i'm using one request bean "userBean" to fill this page and one request bean "userEditBean" to fill the following edit page.
<h:form>
<h:panelGrid border="1" columns="2">
<h:outputText value="Name" />
<h:outputText value="#{userBean.user.name}" />
...
</h:panelGrid>
<h:commandButton value="Edit" action="edit" actionListener="#{userEditBean.init}">
<f:attribute name="user" value="#{userBean.user}"/>
</h:commandButton>
</h:form>
When i press the Edit button a userEditBean is created but the attribute map resolves "user" to null.
Does this mean that the attribute EL is resolved after the userBean has already been destroyed? How can i pass values from incoming beans to outgoing beans?
You're setting the attribute value with an expression, not a static value. Whenever you request the value, the expression will be re-evaluated again. The userBean.user apparently isn't present in the subsequent request. You need to ensure that it is there (in other words, the constructor of the userBean should ensure that the user is been created and set.
There are however alternatives. One of the best is to use Tomahawk's <t:saveState> for that. Add it somewhere in the page:
<t:saveState value="#{userBean.user}" />
That said, I agree with Bozho that the whole approach is a bit strange, but that's another story. You may however get lot of useful ideas out either of the following articles: Communication in JSF and/or Using Datatables. Good luck.
request scope means the bean lives during one request. And you fill your edit page (1st request), and send the edited user (2nd request).
In addition to that, <f:attribute> sets tha attributes in the parent component, not in the request. So in your code the attributes will be found in the button.getAttributes() (if you have bound your button).
Furthermore, it is strange to have an actionListener method named init. Since you don't need the event, you can set the action to be the method which will do the editing operation, and make that method return the navigation-rule you want.

Categories

Resources