Potential Primefaces Dialog Enter Submit Bug? - jsf-2

I have the exact same dialog form setup as the primefaces example below. When I put my cursor in the p:inputText on the below primefaces example and hit enter the window is closed automatically. On my example, I've even removed all links/buttons etc and just have a form and an input and it still closes the dialog when hitting enter. Any way around this?
http://www.primefaces.org/showcase/ui/dialogForm.jsf
mycode:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:dc="http://dc.dreamcatcher.com/facelet-taglib">
<ui:composition template="#{layoutBean.registeredTemplate}">
<ui:define name="content">
<h:form id="dreamModifyFrm">
<p:commandLink onclick="webSearchDlg.show();" value="open"/>
<p:dialog header="#{bundle['dreamSearch.HEADER']}"
widgetVar="webSearchDlg" modal="true" styleClass="dialog dialog2"
draggable="false" resizable="false" showEffect="fade" position="top"
hideEffect="fade">
<p:inputText id="searchText" value="#{dreamSearchBean.searchText}"/>
</p:dialog>
</h:form>
</ui:define>
</ui:composition>
</html>

My issues was fixed using the below:
There is a "feature" in IE where if you have only a single input element inside a form then hitting enter while focus in in the input element causes the form to submit (regardless of whether you even have a submit button). One way to prevent this is to add a second input element with style="display: none;".

Add the following onkeyup attrubute with a little JavaScript to the <h:form> or the <h:inputText> element to prevent the default action on enter press.
onkeyup="return event.keyCode != 13"
The enter key has a keycode of 13, so the above will return false when it is pressed and so the element's default action will be blocked.

Let me just wrap it up from a 2013 perspective:
When using newer PrimeFaces (3.2+?) versions, you can also use
<p:defaultCommand target="search-button" />
as described here:
http://blog.primefaces.org/?p=1787
ShowCase link:
http://www.primefaces.org/showcase-labs/ui/defaultCommand.jsf
Of course, this tag must be directly underneath the h:form tag, otherwise the tag isn't working.
When not using PrimeFaces, you must have something like
<h:inputText style="display: none;" />
on the form, as described in the earlier answer by c12.
Both of the above will cause IE browsers to behave like FF, Chrome, etc. When not using IE at all, BalusC's solution suffices.

I got the same Problem. I have a From with several Dozens InputTexts and several Buttons. When i pressed 'enter' in a inputText, the first Button was triggered and NOT the submit Button.
The hints above (onkeyup="return event.keyCode != 13" and p:commandButton with display:none) didn't work for me.
My solution was pretty simple and works. Just let your Submit-Button be the first button in your HTML-Code. The correct layout/arrangement of Button can be done via CSS, i.e. "float: left;"
Example:
<p:commandButton value="Save" ajax="true"
icon="ui-icon-disk"
update="myTable"
actionListener="#{myTableBean.save()}" />
<p:commandButton id="previousPeriod" update="myTable"
icon="ui-icon-triangle-1-w" ajax="true" type="push"
style="float: left;"
actionListener="#{myTableBean.scrollPrevious}"
value="Previous" />
After putting my Save-Button before my "Previous"-Button, everything worked fine! After pushing "enter" within a inputText, the Form gets submitted now and the "float:left" places the Prev-Button before the Save-Button in the visual Layout.

Related

Primefaces dynamic overlayPanel without internally rendering rest of page

We are using Primefaces 5.09 with JSF 2.1.2 on a Wildlfy 8.1.0 Final
We have a datatable with a lot of content which consumes quite an amount of time to load (which is ok as it is)
In every row we have a commandLink refering to a dynamically loaded overlayPanel which is defined in a composition:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:panelGroup>
<p:commandLink id="CID" title="#{messageId}" type="button" value="#{messageId}" ajax="true" actionListener="#{SyncClientPopupBean.setSyncClientById(messageId)}" update="grid" disabled="#{not Shiro.isPermitted('admin:syncclient:read')}" />
<p:overlayPanel for="CID" dynamic="true" at="right top" my="left bottom" appendTo="#(body)">
<p:panelGrid id="grid" columns="2" styleClass="ui-datatable-auto-width">
<...../>
</p:panelGrid>
</p:overlayPanel>
</h:panelGroup>
</ui:composition>
The Ajax request itself works fine, as the result only contains the content for the overlayPanel.
Our Problem now is, that the update on the overlayPanel also seems to internally render the rest of the page as it is loading the items for the datatable etc.
Therefore requesting this very small content for the panel takes about as long as loading the whole datatable.
The Backing Beans for the whole Page and the overlay are already separated.
Is there any possibility to get Primefaces to render only this single component?

Redirect to XHTML file in a JSF Composite Component

I have a requirement to add a button in one of the xhtml component. When a user clicks the button, a new window should open redirecting the user to another xhtml file which is also in the same component project.
This is what I have in my component project,
|->src
|-> main
|->java
|->META-INF
|->faces-config.xml
|->resources
|->components
|->A.xhtml
|->B.xhtml
I need to add a button in A.xhtml file which redirects the user to B.xhtml opening a new window. This component is being used in other projects. I tried commandButton with target=_blank, a new window opens but doesn't redirect to B.xhtml.
I observed that if I use ui:include src="B.xhtml" tag in A.xhtml file, then the content of B appears in A. But couldn't find why it is not able to redirect in a new window. Not sure what I am missing and would like to know how this can be achieved.
#Sanjay you can easily achieve this by using primefaces commandbutton component by setting target as '_blank' and ajax as 'false'.
<h:form prependId="false" id="form" target="_blank" >
<p:commandButton value="Click me to open new url" ajax="false" action="B.xhtml"/>
</h:form>
Hope this helps .
you can't redirect to a component, you have to redirect to a PAGE that contains that component.
imagine you have
application
resources
components
A.xhtml
B.xhtml
pages
page1.xhtml
page2.xhtml
and
page1.xhtml contains component A
page2.xhtml contains component B
page1.xhtml contains
<!DOCTYPE html>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:p="http://primefaces.org/ui"
xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions"
xmlns:cc="http://java.sun.com/jsf/composite/components">
<ui:composition template="/WEB-INF/templates/template.xhtml">
<ui:define name="content">
<cc:a value="someValue" foo="someBar"/>
</ui:define>
</ui:composition>
</html>
and A.xtml is
<h:form prependId="false" id="form" target="_blank" >
<p:commandButton value="open" ajax="false" action="page2.xhtml"/>
</h:form>
so, upvote for #Java, since your answer is almost correct, just change action to address a page and not a component in resources

commandLink does not invoke action listener, but commandButton works fine

I want to invoke one method through a link from Facelets:
My Facelets code is like:
<h:commandButton value="A" actionListener="#{customerData.searchedCustomerListA}" />
<h:commandLink value="A" actionListener="#{customerData.searchedCustomerListA}"/>
Backing bean code is like:
public void searchedCustomerListA(ActionEvent ae){
customerName = "A";
leftCustomerListAvailable.clear();
if(customerDataBean.getSearchedCustomerList(customerName)!= null)
leftCustomerListAvailable =customerDataBean.getSearchedCustomerList("A");
}
The same code is working for <h:commandButton> but not working for <h:commandLink>. How is this caused and how can I solve it?
The technical difference between <h:commandLink> and <h:commandButton> is that the link uses JavaScript to submit the parent form. So if it doesn't work while a syntactically equivalent button works fine, then that can only mean that either JavaScript is disabled in browser, or that the jsf.js file containing the mandatory helper functions isn't included in the page (which you should easily have noticed by seeing JS errors in the JS console of browser's builtin developer toolset).
So, to fix this problem, you need to verify if JS is enabled in browser and that you've a <h:head> component instead of plain HTML <head> in the template, so that JSF will be able to auto-include the jsf.js file.
Or, if your application's business requirements requires that the application functions as designed with JS disabled, then you should stick to <h:commandButton> and throw in some CSS to make it to look like a link (e.g. remove background, padding, border, inset, etc).
Try this, This sould work.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:form>
<h:commandLink type="button" action="#{testBean.tsetLink}">
<h:outputText value="A" />
</h:commandLink>
</h:form>
</html>
ManagedBean
#ManagedBean
#RequestScoped
public class TestBean {
public void tsetLink(){
System.out.println("Link clicked!!!!!!!!!!!!");
}
}
I my case the cause of this issue was a poorly configured url rewriting filter. One of the filters patterns unintentionally matched http://localhost:8080/mysite/javax.faces.resource/jsf.js.xhtml?ln=javax.faces which prevented jsf.js from being loaded. Check this answer: Clicking h:commandLink causes Uncaught ReferenceError: mojarra is not defined.

UI Repeat varStatus not working in CompositeComponent

I use JSF 2.0 (Apache myFaces) on WebSphere Application Server 8.
I have a bean which contains a list of charts (data for jquery HighCharts).
For each chart I need some JSF components + one Highchart Wrapper written as CompositeCompoent (look here)
So I use the ui:repeat function of jsf 2 like this:
<?xml version="1.0" encoding="UTF-8" ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:hc="http://java.sun.com/jsf/composite/chartComponents"
template="/template/mytemplate.xhtml">
<ui:define name="content">
<ui:repeat value="#{chartCtrl.charts }" var="chart" id="chartrepeat" varStatus="chartStatus">
#{chartStatus.index }
<h:form id="chartform_#{chartStatus.index }">
<!-- some jsf select stuff-->
</h:form>
#{chartStatus.index }
<hc:Chart title="Statistics" id="hcchart_#{chartStatus.index }"
<!-- here's the problem-->
<ui:repeat value="#{chart.series }" var="serie">
<hc:ChartSeries series="#{serie.data }" />
</ui:repeat>
</hc:Chart>
#{chartStatus.index }
</p:panel>
</ui:repeat>
<h:outputScript library="js" name="highcharts.js" />
<h:outputScript library="js/modules" name="exporting.js" />
<h:outputScript library="js" name="jquery-1.9.1.min.js" target="head" />
</ui:define>
</ui:composition>
The #{chartStatus.index } works every where but not in hc:Chart id="".
The generated js and div by this CC contains the id 'hcchart_chartdiv'. The index of the current repeat left.
How can I pass the correct number to the id attribute?
EDIT: Composite Component
Here is a part of the hc:Chart where the ID should be used
<cc:implementation>
<div id="#{cc.id}_chartDiv" />
<!-- Highcharts -_>
<script type="text/javascript">
$(function() {
// Data must be defined WITHIN the function. This prevents
// different charts using the same data variables.
var options = {
credits : {
enabled : false
},
chart : {
renderTo : '#{cc.id}_chartDiv',
....
</script>
When I leave the attribute id in hc:Chart empty, then the generated ID is something like "j_id568185923_1_5f9521d0_chartDiv". But still without :row:.
EDIT 2: IndexOf Approach
I tested another approach to set the ID of my chart.
id="hc_#{chartCtrl.charts.indexOf(chart) }"
I tried to use the IndexOf method of my ArrayList. I implemented HashCode und Equals method in all Classes. When I test it, it works fine.
But when I use it with EL I get -1 returned.
Solution
Just as BalusC said I cant use the ID tag for EL. So I simple created a new attribute in my CC. That works fine (just so easy).
Thanks BalusC.
Does someone has another idea?
The id attribute is evaluated during view build time. The <ui:repeat varStatus> is set during view render time which is after view build time. Essentially, you've the same problem as explained in detail here: JSTL in JSF2 Facelets... makes sense?
Any EL expression in the id attribute must be available during view build time. If you replace <ui:repeat> by <c:forEach> which runs during view build time, then the id must be properly set. An alternative is to just get rid of EL in those id attributes based on <ui:repeat varStatus>. JSF will already automatically suffix the IDs of <ui:repeat> child components with the row index.
Note that the <c:forEach> may have unforeseen side effects when used in combination with view scoped beans and partial state saving enabled. See the aforelinked answer for details.

JSF2.0 Composite Component actionListener

I am in need of some assistance in getting my Composite Component to behave. I am still learning the ropes in JSF, so please excuse any ignorance that might be displayed in this post.
So, I am working with JSF 2.0 and decided to build a composite component to make this particular code snippet reusable. The component displays everything perfectly, but will not behave at all when trying to add the actionListener.
Here is the code for my component
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface displayName="columnUpdate">
<composite:attribute name="id"
required="true"
displayName="id"
shortDescription="Id to apply to this control and its child components">
</composite:attribute>
<composite:attribute
name="value"
displayName="value"
required="true"
shortDescription="Field that will hold the new updated value.">
</composite:attribute>
<composite:attribute
name="columnName"
displayName="columnName"
required="true"
shortDescription="Value that will be applied as the column header">
</composite:attribute>
<composite:attribute
name="text"
displayName="text"
shortDescription="Text to be displayed above the field">
</composite:attribute>
<composite:actionSource name="actionEvent" targets="saveEvent"></composite:actionSource>
</composite:interface>
<composite:implementation>
<h:outputLabel value="#{cc.attrs.columnName}" onclick="showWindow('#{cc.attrs.id}')"></h:outputLabel>
<div id="#{cc.attrs.id}" class="ccColumnUpdate">
<div id="windowClose" onclick="closeWindow('#{cc.attrs.id}');" style="top: -10px;" title="Close this window">CLOSE</div>
<div>
<h:outputLabel id="lblTitle" value="#{cc.attrs.text}"></h:outputLabel>
</div>
<div>
<h:inputText id="txtValue" value="#{cc.attrs.value}"></h:inputText>
</div>
<div style="text-align:right;">
<h:commandButton id="saveEvent" value="Save"></h:commandButton>
</div>
</div>
</composite:implementation>
</ui:composition>
Here is the code in my page that uses the component:
<al:columnUpdate id="cuExpenseAmount" value="#{expense.columnValue}" columnName="Expense Amount" text="Set Expense Amount to:">
<f:actionListener for="actionEvent" binding="#{expense.updateColumnValue}">
<f:ajax execute="#form"></f:ajax>
</f:actionListener>
</al:columnUpdate>
and here is my code on the Backing Bean:
public void updateColumnValue(ActionEvent event) throws ParseException{
//Got HERE
}
I am not receiving any errors or hit any breakpoints I set on the backing bean. Any help, or pointers in the right direction would be appreciated.
Regards,
Mike
I found the answer after playing around a little bit and more searching.
Changes to the composite component:
FROM:
<composite:actionSource name="actionEvent" targets="saveEvent"></composite:actionSource>
<h:commandButton id="saveEvent" value="Save"></h:commandButton>
TO:
<composite:attribute name="registerButtonActionListener" method-signature="void actionListener(javax.faces.event.ActionEvent)" />
<h:commandButton id="saveEvent" value="Save" actionListener="#{cc.attrs.registerButtonActionListener}">
<f:ajax execute="#this" event="click"></f:ajax>
</h:commandButton>
Changes to the page using the composite component:
<al:columnUpdate id="cuExpenseAmount" value="#{expense.columnValue}" registerButtonActionListener="#{expense.updateColumnValue}" columnName="Expense Amount">
</al:columnUpdate>
The big change was defining the method signature in the composite attribute.
Regards,
Mike
I found an alternative solution to yours. A drawback of your solution is that you can only register one listener: the actionListener attribute can only point to one method.
The way to add listeners is as follows (you almost had it right in the first piece of code you wrote):
<al:columnUpdate id="cuExpenseAmount" value="#{expense.columnValue}" columnName="Expense Amount" text="Set Expense Amount to:">
<f:actionListener for="actionEvent" binding="#{expense.updateColumnValue(ActionEvent)}">
<f:ajax execute="#form"></f:ajax>
</f:actionListener> </al:columnUpdate>
Notice how the method pointed to by binding takes an ActionEvent parameter. This is a requirement of using <f:actionlistener/>.
Using this method, multiple listeners can be registered to the action source made available by the composite component.

Resources