p:selectOneButton suddenly stops working, first button is not clickable anymore - jsf

I have been successfully been using the PrimeFaces selectOneButton - using PF 3.5.
Suddenly, it has stopped working, and the first button is always not clickable - there has been no changes to the webpage code nor the backing bean code (which would affect it).
<p:selectOneButton value="#{bean.result}">
<f:selectItems value="#{bean.options}" />
<p:ajax event="change" process="popupPanel"
update="Grid"
listener="#{myBackingBean.submitItem(bean.itemId)}" />
</p:selectOneButton>
I have a theory to why the first button is not clickable.
From PrimeFaces SelectOneButton showcase:
SelectOneButton is an input component to select options using regular buttons instead of radio buttons
So, SelectOneButton is really radio buttons, but displayed with a nice touch ;)
Now, the rendered HTML of selectOneButton with two options is as follows;
<div class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left ui-state-active">
<input id="mainForm:Grid:0:j_idt64:0" name="mainForm:Grid:0:j_idt64" type="radio" value="Yes" class="ui-helper-hidden" checked="checked">
<span class="ui-button-text ui-c">Yes</span>
</div>
<div class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-right">
<input id="mainForm:Grid:0:j_idt64:1" name="mainForm:Grid:0:j_idt64" type="radio" value="No" class="ui-helper-hidden">
<span class="ui-button-text ui-c">No</span>
</div>
I notice two differences...
1) The div classes are different.
2) First option has checked="checked"
1) Checking the CSS of the div class, I cannot see anything major to which would make the button unclickable.
2) Obviously, since its really a radio button, the first option is "checked".
Now, when clicking a plain-old-standard radio button, you can't click on it to "release it" - once its clicked its clicked, and other radio buttons need to be clicked to change the option.
Since my first option is always "checked" would this block the button to be "clickable"? Has any one else ever experienced something similar? Having looked around I seem to be the only one who has had this issue.
I can do workarounds, but I can not find out why it has suddenly stopped working, and would rather find a solution!
Any help is appreciated!
UPDATE
Luckily, I found an old previous version of my webapp and I checked the rendered HTML.
Heres the following HTML of the first button (which is unclickable on my current version).
<div class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left">
<input id="mainForm:Grid:0:j_idt63:0" name="mainForm:Grid:0:j_idt63" type="radio" value="Yes" class="ui-helper-hidden">
<span class="ui-button-text ui-c">Yes</span>
</div>
The two differences I described above, are not rendered in my previous version - there is no "ui-state-active" in the div class, nor "checked='checked'" in my <input />
I edited the HTML manually on my current (unclickable) version, and removed "checked='checked'" - this had no effect. I then removed the "ui-state-active" from my div class - and the button is now clickable.
I am still puzzled to why the HTML is now rendered differently, what could I of changed which would make this happen?
Thanks again.

After many hours, I finally figured out why...
As I said in my question,
SelectOneButton is an input component to select options using regular
buttons instead of radio buttons
SelectOneButtons are radio buttons.
In the same webpage, I also use radio buttons as on option using pretty similar code...
<p:selectOneRadio value="#{bean.result}">
<f:selectItems value="#{bean.options}" />
</p:selectOneRadio>
Now, I had trouble that when the user was presented with these radio buttons, none were selected. This allowed the user to return null. Now, I didn't want the user to be able to return null, hence the need for radio buttons - one or the other. So, I set #{bean.result} to the first element in #{bean.options} before the page is rendered, so when the user is presented with the buttons, the first is selected by default.
Hence, when the selectOneButton's were rendered, the first "button" was selected, and you couldn't press it.

Related

Bootsfaces modal not working inside <h:form>

I am new to JSF and I am currently building a web-auction type of application, based on it. I have also used multiple elements from Bootsfaces. What I would like to do is have an inputText where bidders can type their bids and then press a button that will trigger a Bootsfaces modal. Inside the modal, the bidder will have to confirm that he actually wants to bid, by pressing a commandButton that will eventually "submit" his bid. In order for this to work (if I have understood correctly how JSF works), I need the inputText and the commandButton inside the same h:form element. The only problem is that, whenever I put the code of the modal inside the form, the modal doesn't show up when I press the button that triggers it. My code is the following:
<h:form>
<b:inputText class="bid1" value="#{detailedViewBean.current}" placeholder="Type the amount you would like to bid..." style="width: 90%" onfocus="enableButton('atrigger1')" onblur="bidAmount(this.value, '#{detailedViewBean.previous}')"> <!--current highest bid-->
<f:facet name="prepend">
<h:outputText value="$" />
</f:facet>
<f:facet name="append">
<b:buttonGroup>
<a id="atrigger1" class="btn btn-primary" href="#amodal1" data-toggle="modal">Bid!</a>
</b:buttonGroup>
</f:facet>
</b:inputText>
<b:modal id="amodal1" title="Warning!" styleClass="modalPseudoClass">
<p id="amodal1body"> Are you sure ?</p>
<f:facet name="footer">
<b:button value="Close" dismiss="modal" onclick="return false;"/>
<b:commandButton value="Yes, submit my bid!" id="modalbidbutton" type="button" class="btn btn-primary" data-dismiss="modal" data-toggle="modal" data-target="#amodal2"/>
</f:facet>
</b:modal>
<h:form>
Does anyone know why this might happen or how I can correct it?
Moving the <b:modal /> into a form modifies its id. That's an annoying property of the JSF framework: it sees to it that ids are always unique - and of of the measures to achieve that goal is to prepend the form's id to the id of <b:modal >. Most of the time, this works just great, but sometimes you need the HTML id. Your button uses a jQuery expression, so this is one of those times. Adding insult to injury, JSF uses the colon as a separator, and jQuery doesn't cope well with the colon.
Cutting a long story short, I suggest to use the CSS class of the modal dialog instead of the id. You already gave it a pseudo CSS class. This class doesn't bear any layout information. Instead, you can use it in the button:
<a id="atrigger1" class="btn btn-primary disabled"
href=".modalPseudoClass" data-toggle="modal">Bid!</a>
TL;DR: If you run into trouble with id, replace your jQuery expression ("#id") with a CSS pseudo class expression (".pseudoClass").

JSF too many commandLinks (h:form) lead to ViewExpiredException

I am having a JSF application which creates and presents about 50 reports. These reports are rendered PNGs and under the pictures a table is displayed.
This table uses a RichFaces 4 togglePanel with switchType="client". The togglePanel is just for collapsing and expanding the table.
<h:form>
<rich:togglePanel id="#{param.reportWrapper}_togglePanel"
stateOrder="opened,closed" activeItem="opened" switchType="client">
<rich:togglePanelItem name="closed">
<h:panelGroup>
<div class="myclass">
<ul class="container-icons">
<li>
<h:commandLink styleClass="container-max" value="maximieren">
<rich:toggleControl targetPanel="#{param.reportWrapper}_togglePanel" targetItem="#next" />
</h:commandLink>
</li>
</ul>
<h3>My Heading</h3>
</div>
</h:panelGroup>
</rich:togglePanelItem>
<rich:togglePanelItem name="opened">
<h:panelGroup>
<div class="myclass">
<ul class="container-icons">
<li>
<h:commandLink styleClass="container-min" value="minimieren">
<rich:toggleControl targetPanel="#{param.reportWrapper}_togglePanel" targetItem="#prev" />
</h:commandLink>
</li>
</ul>
<h3>Another Heading</h3>
<div class="scrolling-table-content">
<rich:dataTable>
// ...
</rich:dataTable>
</div>
</div>
</h:panelGroup>
</rich:togglePanelItem>
</rich:togglePanel>
</h:form>
The problem is, that I sometimes get a ViewExpiredExceptions when the reports are loaded. My numberOfLogicalViews and numberOfViewsInSession is 14. I dont want to set it to 50, because of memory issues and because it should not be necessary as only one report is really shown at the same time.
I tried to remove the h:form tags, which are seen as logicalView. In my opinion the togglePanel is not the item, which needs the form because it's switch type is client (not server and ajax, which need form tags). But the command link does need the form tag, because if I remove it, an error occurs saying "this link is disabled as it is not nested within a jsf form".
So I tried to replace the commandLink with a commandButton. This worked fine first and the form wasnt necessary anymore. But somehow the behaviour is completely random now. Sometimes the tables can be expanded, sometimes nothing happens when i click the expand button. When i add form tags again, it works fine, but doesnt solve my ViewExpiredException.
Hope, somebody can help me out here...
Thanks for your help!
Buntspecht
If you only need to switch the panel you can use <a4j:commandLink> that lets you limit the execution scope (so it won't submit the whole form). Or you can remove the command components altogether and just use JavaScript API of the togglePanel:
<a onclick="#{rich:component('panelId')}.switchToItem(#{rich:component('panelId')}.nextItem())">Next</a>
Thank you very much for your help Makhiel. I finally managed to solve the problem with the commandButtons solution. I can't explain why, but the IDs of my togglePanelItems got duplicated in the different reports.
Giving every togglePanelItem a unique ID like
<rich:togglePanelItem name="closed" id="#{param.reportWrapper}_opened">
and
<rich:togglePanelItem name="opened" id="#{param.reportWrapper}_closed">
solved the problem...
So now we got rid of all the h:form tags and thus have about 50 logical views less! :)

SelectOneMenu label is "covered"

This is probably a CSS problem, but I cannot understand the reason by myself.
I often found some selectonemenus behaving like the one in picture:
The dropdown field is "covered".
Then I click it, select a value and... it starts displaying correctly.
I am using Cupertino theme.
If I analyze the generated source, here's what I find:
<div class="ui-helper-hidden-accessible">
<input id="carrello:formCarrello:j_idt165_focus" name="carrello:formCarrello:j_idt165_focus" type="text">
</div>
<label id="carrello:formCarrello:j_idt165_label" class="ui-selectonemenu-label ui-inputfield ui-corner-all" style="width: 0px;">
Seleziona...
</label>
The label has "width:0px;". If I remove it, the menu is displayed correctly.
Good but... I DID NOT add that attribute. Why is Primefaces adding it?
EDIT
The source of the first menu:
<p:selectOneMenu value="#{posController.rigaVendita.codiceIva}" effect="fade" converter="codiceIvaConverter">
<f:selectItem itemLabel="Seleziona..." itemValue="" />
<f:selectItems value="#{posController.codiciIva}" var="ci" itemLabel="#{ci.codice}" itemValue="#{ci}" />
</p:selectOneMenu>
The same problem in all browser.
It isn't a css compatibility issue, the fault is the "0px" width attribute!
Ok I finally found what caused the bug!
I had the same problem with selectOneMenu label.
It is because I used the default forward page navigation, that's why in some pages components were working and not in other pages.
Actually it's not working when the url is not matching the page.
Solution : concat view id with "?faces-redirect=true" in action attribute of commandLink or commandButton
This can help:
http://www.mkyong.com/jsf2/jsf-page-forward-vs-page-redirect/
http://www.mkyong.com/jsf2/implicit-navigation-in-jsf-2-0/
The same problem occurred with the PrimeFaces google map component <p:gmap> you need also to use redirection if you want to use it
( And there is another problem: if you are using a template you have to put
<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>in the template.xhtml, see (primefaces GMmap inside a dialog not rendering) )
EDIT
And apparently it's OK:
PrimeFaces does not support forward based navigations within an ajax request, you need to do redirect instead or set ajax to false.
http://primefaces.org/faq.html
I've just had the same problem. I guess it was a bug of primefaces. My solution is to override zero width of that element — just add this code into your CSS file:
.ui-selectonemenu-label{
width: 100%!important;
}
I had the same problem and the solution consists in over write the css of the selectOneMenu in this case, correspond to two selectors, that are the following:
.ui-selectonemenu .ui-selectonemenu-trigger{
width: auto !important;
padding-top: 0.4em;
}
.ui-selectonemenu{
padding-right: 0px !important;
}
See the image before correction
See the image after correction

Setting a command button to selected by default

I have a form in which I needed to have radio buttons that look like bootstrap toggle buttons. I achieved this by using command buttons in a button group, and setting the attribute data-toggle="buttons-radio", like so:
<div id="flightChoiceButtons" class="btn-group" data-toggle="buttons-radio">
<h:commandButton type="button" styleClass="btn btn-inverse" value="One Way"><f:ajax render="flexibleDates" listener="#{searchFlightsBean.setDirectionOneWay}"/></h:commandButton>
<h:commandButton type="button" styleClass="btn btn-inverse" value="Round Trip"><f:ajax render="flexibleDates" listener="#{searchFlightsBean.setDirectionRoundtrip}"/></h:commandButton>
</div>
The problem I'm stuck with right now is that I need the "Round Trip" button to be selected, or in the down state, when the page loads. I don't need the button's ajax call to be fired, because the data displayed on the page is already in the state it needs to be in.
Anyone have any ideas?
If any more information is needed I'd be glad to supply it.
The bootstrap button's active state is identified by presence of active style class. Knowing that, you can just let JSF print the style class conditionally. The way how your model is setup is unclear, so here's just a kickoff example provided that you've a #{searchFlightsBean.direction} property returning an enum.
<h:commandButton ... styleClass="btn btn-inverse #{searchFlightsBean.direction == 'ONE_WAY' ? 'active' : ''}">...</h:commandButton>
<h:commandButton ... styleClass="btn btn-inverse #{searchFlightsBean.direction == 'ROUND_TRIP' ? 'active' : ''}">...</h:commandButton>
You can replace the #{searchFlightsBean.direction == '...'} part by any other boolean condition. You can find examples in this answer: Conditionally displaying JSF components.

JSF Form Submit works in FF but not in IE

I have a simple Form with an inputText and a commandButton.
<h:form>
<h:inputText id="xyz" value="#{viewImpl.field}" onfocus="clearText(this)" onblur="setDefaultText(this)" />
<h:commandButton action="#{viewImpl.method}"/>
</h:form>
If I press on the commandButton the form is submitted correctly.
But if I hit enter, still being in the inputText-Field the page reloads, but the method is not called (server is in debug mode with activated breakpoints).
Important: This only happens in IE 8. It works perfectly fine in Firefox.
Any clue on how I can fix this?
Thanks alot!
This is a known problem with one-field forms in IE. Pressing the enter key won't trigger the first-next button of the form and hence its name=value pair won't appear in the request parameter map and hence JSF can't identify the button in order to queue the action event.
One of the ways to fix this is to add a second but invisible input field to the very same form.
<input type="text" name="dummy" style="display: none;" />
This will cause IE to send the name=value pair of the first-next button as well.

Resources