Trigger <cc:clientBehavior> event from <p:ajax> nested in composite - ajax

Is there any way to trigger an event in my composite component with clientBehavior and jQuery?
If not possible, what is the proper way to create custom events in composites?
Example:
ajaxTest.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:p="http://primefaces.org/ui">
<cc:interface>
<cc:clientBehavior name="myEvent" targets="myLabel" event="myEvent"/>
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<p:outputLabel id="myLabel" value="Test label" />
<p:commandLink value="trigger event"
onstart="$(PrimeFaces.escapeClientId('#{cc.clientId}:myLabel')).trigger('myEvent');"/>
</div>
</cc:implementation>
</html>
testPage.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:demo="http://xmlns.jcp.org/jsf/composite/component">
<h:body>
<h:form id="form-1">
<demo:ajaxTest>
<p:ajax event="myEvent" oncomplete="alert('Ajax called');" />
</demo:ajaxTest>
</h:form>
</h:body>
</html>

The <cc:clientBehavior event> must declare a valid event name as supported by the target component in question. In this context, it must thus be exactly the same event name as you would use when nesting <p:ajax> directly inside <p:commandLink>. You perhaps want action or click.
<cc:clientBehavior ... event="action" />
See also:
What values can I pass to the event attribute of the f:ajax tag?

Related

Dynamically populate options in a selectOneMenu by <ui:repeat>

I'm trying to populate some dropdown menus in primefaces with content depending on some choices from other selections in the GUI. This is a simplified example of what I'm trying to do:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core" >
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:form>
<c:set var="options" value="#{['1','2','3']}" />
<c:set var="currentValue" value="#{3}" />
<h:outputText value="${options}" />
<ui:repeat var="r" value="#{options}">
<h:outputText value="#{r}" />
</ui:repeat>
<c:set var="currentValue" value="#{currentValue}" />
<p:selectOneMenu id="selectValue"
value="${currentValue}"
class="pFieldSet_Template_Input200 r10">
<p:ajax event="change" />
<ui:repeat var="r" value="#{options}">
<f:selectItem itemLabel="Choice #{r} (20180101)" itemValue="#{r}" />
</ui:repeat>
</p:selectOneMenu>
</h:form>
</h:body>
</html>
When I visit the page it shows [1, 2, 3]123 and an empty selectOneMenu. I would have expected the selectOneMenu to contain the choices as well. The iteration obivously works in the above case so I don't know why it doesn't show the options in the menu. What am I doing wrong?
The <ui:repeat> is an UI component while <f:selectItem> is a taghandler (like JSTL). Taghandlers runs during view build time before UI components which runs during view render time. So at the moment the <ui:repeat> runs, there is no means of a <f:selectItem>.
A <c:forEach>, which is also a tag handler, would work:
<p:selectOneMenu id="selectValue"
value="${currentValue}"
class="pFieldSet_Template_Input200 r10">
<p:ajax event="change" />
<c:forEach items="#{options}" var="r">
<f:selectItem itemLabel="Choice #{r} (20180101)" itemValue="#{r}" />
</c:forEach>
</p:selectOneMenu>

Composite Component Binding is resolves to null

I am trying to bind a composite component to an ajax listener but the bind variable resolves to null. If I use the bind variable as part of the body, eg. #{bind} it does resolve properly. I assume it is a bug, but would like a second opinion before I report it. Thanks
page:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:composite="http://xmlns.jcp.org/jsf/composite"
xmlns:jstl="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:jfunc="http://xmlns.jcp.org/jsp/jstl/functions"
xmlns:jid1="http://mydomain.com/facelets">
<h:head></h:head>
<h:body>
<h:form id="commentBoxForm">
<jid1:confirmModal title="t" cssID="a" binding="#{bind}">
</jid1:confirmModal>
<h:commandLink value="click">
<f:ajax execute="#this" render="#form"
listener="#{bind.getFamily()}" />
</h:commandLink>
</h:form>
</h:body>
</html>
component:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:composite="http://xmlns.jcp.org/jsf/composite"
xmlns:jstl="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:jfunc="http://xmlns.jcp.org/jsp/jstl/functions"
xmlns:jid1="http://mydomain.com/facelets">
<composite:interface>
<composite:attribute name="cssID" required="true" />
<composite:attribute name="title" required="true" />
</composite:interface>
<composite:implementation>
<h:panelGroup >
......
</h:panelGroup>
</composite:implementation>
</ui:composition>
This is a bug. See here for details.
A composite component binding attribute will not work properly for Ajax calls.

h:selectManyChexkbox`s <f:ajax event="click" listener doesn't fire and gives an error

I want to fire an event change listener when the user selects / deselects something in the h:selectManyCheckbox, if it leaves it alone nothing should happen.
My xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" 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">
<h:head>
<link rel="stylesheet" type="text/css"
href="/juritest/resources/css/style.css" />
<script type="text/javascript"
src="/juritest/resources/js/jquery-1.8.2.js"></script>
<script type="text/javascript" src="/juritest/resources/js/menu.js"></script>
</h:head>
<h:body>
<ui:composition template="../../templates/gridsTemplate.xhtml">
<ui:define name="content">
...
<h:panelGroup style="text-align: left">
<hr />
<h:selectManyCheckbox
value="#{gridPopUpBean.oneQuestionUserAnswers}"
layout="pageDirection">
<f:selectItem itemValue="a"
itemLabel="#{gridPopUpBean.currentQuestion.a}" />
<f:selectItem itemValue="b"
itemLabel="#{gridPopUpBean.currentQuestion.b}" />
<f:selectItem itemValue="c"
itemLabel="#{gridPopUpBean.currentQuestion.c}" />
<f:ajax event="click" listener="#{gridPopUpBean.changeListener()}"/>
</h:selectManyCheckbox>
</h:panelGroup>
...
I get an error saying "One or more resources have the target of 'head', but no 'head' component has been defined within the view." I have < h:head> not just < head>, I read that this was a possible problem.
And the snippet from the bean:
public void changeListener(ValueChangeEvent e) {
change = true;
}
I have tried without < f:ajax like
<h:selectManyCheckbox
value="#{gridPopUpBean.oneQuestionUserAnswers}" valueChangeListener="#{gridPopUpBean.changeListener()}" onclick="submit()"
layout="pageDirection">
<f:selectItem itemValue="a"
itemLabel="#{gridPopUpBean.currentQuestion.a}" />
<f:selectItem itemValue="b"
itemLabel="#{gridPopUpBean.currentQuestion.b}" />
<f:selectItem itemValue="c"
itemLabel="#{gridPopUpBean.currentQuestion.c}" />
<f:ajax event="click" listener="#{gridPopUpBean.changeListener()}"/>
</h:selectManyCheckbox>
but with no luck...
One or more resources have the target of 'head', but no 'head' component has been defined within the view." I have < h:head> not just < head>, I read that this was a possible problem.
Anything outside <ui:composition> is ignored. If you need a <h:head>, it needs to go in the master template, the gridsTemplate.xhtml (or any of its parent templates).
Further, if you aren't using a visual editor for your XHTML files (like Dreamweaver), then I strongly recommend to stop putting any content outside <ui:composition>, otherwise you keep confusing yourself.
See also:
How to include another XHTML in XHTML using JSF 2.0 Facelets?
<f:ajax event="click" listener="#{gridPopUpBean.changeListener()}"/>
public void changeListener(ValueChangeEvent e) {
You're confusing valueChangeListener with <f:ajax listener>. The ValueChangeEvent argument is only applicable to valueChangeListener attribute of an UIInput component. Get rid of that argument.
public void changeListener() {
See also:
When to use valueChangeListener or f:ajax listener?
Unrelated to the concrete problem, you correctly used click (although you could safely omit it altogether), but your question title mentions change and that is indeed the wrong event for a checkbox and radio button.
See also:
What values can I pass to the event attribute of the f:ajax tag?

<f:ajax> contains an unknown id when switching from PrimeFaces to jsf/html

this is my 1st question here :)
My code is as follows:
<?xml version="1.0"?>
<f:view 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"
>
<h:head />
<h:body>
<h:form id="filterForm">
<h:outputStylesheet library="css" name="main.css" />
<div id="filterPane">
<h:panelGroup rendered="#{not empty filters.categories}">
<div class="filter">
<div class="filterCategories" style="width: 100%;">
<h4>Kategorien</h4>
<p />
<h:selectManyCheckbox layout="pageDirection"
value="#{filters.selectedCategories}"
valueChangeListener="#{filters.categoryValueChanged}">
<f:selectItems value="#{filters.categories}" var="category"
itemLabel="#{category.displayName} (#{category.count})"
itemValue="#{category.name}" />
<f:ajax render="#form" />
</h:selectManyCheckbox>
</div>
</div>
</h:panelGroup>
</div>
</h:form>
</h:body>
</f:view>
I get the same error as some others before me here #stackoverflow - but none of the suggested solutions worked for me.:
<f:ajax> contains an unknown id 'A5539:filterForm:j_idt9' - cannot locate it in the context of the component j_idt9
Before my switch from <p:selectManyCheckbox to <h:selectManyCheckbox the code was working fine.
We need to change to <h:selectedManyCheckbox, because the PrimeFaces variant is not selectable for a non-JavaScript user. I need the form <h:form id="filterForm"> to be re-rendered as a consequence of my AJaX request via the <f:ajax> element.
Beside the initial <f:ajax render="#form" /> I unsuccessfully tried to reference the <h:form id="filterForm"> element with the following variants:
<f:ajax render=":filterForm" />
<f:ajax render=":#{component.parent.parent}" />
I also tried some more stupid ones.
Any hint, anybody!? :)

ui:repeat + AJAX

We have a list to be displayed under a panel of the screen where all the code in which the fields are repeatable are kept under a different Facelet file. While I am trying to render an image based on the listener's action for an ajax event I am getting some problem to update the image with ID as JSF is generating an ID with the index in the middle due to the use of <ui:repeat> like so repeatForm:repeat:2:redimage.
This is the main page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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">
<h:head>
<title>Repeat Test Demo</title>
</h:head>
<h:body>
<h:form id="repeatForm">
<ui:repeat id ="repeat" value="#{listBean.xyzList}" var="repeatListVar">
<p:panel id="genLiabPanelRender">
<ui:include src="MyScreen.xhtml" />
</p:panel>
</ui:repeat>
</h:form>
</h:body>
</html>
This Facelet is repeatable based on the list size within the panel.
MyScreen.xhtml this is the include Facelet file:
<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">
<h:body class="body">
<h:panelGrid columns="4" border="0" width="90%">
<h:panelGroup style="display:block;text-align:left;width: 320px">
<h:selectBooleanCheckbox value="#{repeatListVar.primaryPolicyInd}" />
<h:outputText value="#{label.primaryCov}" />
</h:panelGroup>
<h:panelGroup style="display:block;text-align:left;width: 240px">
<h:selectBooleanCheckbox value="#{repeatListVar.abcInd1}" />
<h:outputText value="#{label.commGenLiab}" />
</h:panelGroup>
<h:panelGroup style="display:block;text-align:left;width: 180px">
<h:outputText value=" #{label.eachOccur}" style="text-align:left" />
</h:panelGroup>
<h:panelGroup style="display:block;text-align:left;width: 130px">
<p:inputMask mask="#{label.limitAmtMask}" id="genLiabEachOccAmt"
value="#{repeatListVar.a25GLEOAmt}" required="true"
style="width: 90px">
<f:ajax event="blur" render="redimage" listener="#{repeatListVar.testA25GLEOAmt}"/>
</p:inputMask>
<h:graphicImage id="redimage" url="/images/icons/redIcon.png" rendered="#{repeatListVar.testA25GLEOAmtInd}" />
</h:panelGroup>
This ends up generating IDs for the <h:outputText> that look like: repeatForm:repeat:2:redimage. But because we're using the <f:ajax> tag, we only need to specify "redimage". The tag takes care of the work of finding out what the real ID is.
We are calling a method in the listener and set the value of boolean indicator to either true or false which is false by default. The indicator is used to render the image.
But when we are using this <f:ajax> to render the image based on the indicator value, I am getting the error
malformedXML: During update repeatForm:repeat:2:redimage not found
How is this caused and how can I solve this?
This should work. I see only 2 possible causes:
Your bean is request scoped and does not preserve the <ui:repeat> value. Fix the bean constructor's job and/or put the bean in the view scope.
Your HTML output is syntactically invalid and is therefore confusing the JavaScript code who is responsible for updating the HTML DOM tree. You should not use <html> and <h:body> in the include file. It would be duplicated in the HTML output. You should only use it in the master page. The include page should look like this:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:panelGrid columns="4" border="0" width="90%">
...
</h:panelGrid>
</ui:composition>
Do not duplicate <html>, <h:head> and/or <h:body> in there.

Resources