p:remoteCommand only update="#all" PF5 - spring

On below code <p:remoteCommand> just update whole view when I use #all, but I've tried update #this,#form or wizardEventContainer without success. Even though #all work as I wish I would prefer just update the specific container wizardEventContainer
In the PrimeFaces website the example works using id attribute therefore I don't know why I can't get it too.
I work with PF5, JSF 2.2 and SWF 2.4. I changed JSF separator char to - instead of :
<h:form id="formEditor" styleClass="eventEditorForm" prependId="true">
<p:editor id="editorEvent" height="150" width="900" maxlength="500" onchange="writeTextonPanel()" widgetVar="editorWidget" />
<h:panelGroup layout="block" id="eventEditorButtons" styleClass="eventEditorButtons">
<h:commandButton value="#{msg['saveLayer.btn']}" actionListener="#{eventProvider.saveTextLayer()}" alt="#{msg['saveLayer.btn.alt']}" title="#{msg['saveLayer.btn.title']}" onclick="showEditor('save')">
<f:ajax execute="#form" render="-formBotones-wizardEventContainer" />
</h:commandButton>
<h:commandButton value="#{msg['omitLayer.btn']}" alt="#{msg['omitLayer.btn.alt']}" title="#{msg['omitLayer.btn.title']}" onclick="showEditor('delete')">
<f:ajax execute="#form" render="-formBotones-wizardEventContainer" />
</h:commandButton>
</h:panelGroup>
<h:inputHidden id="tempCSS" value="#{eventProvider.tempCSS}" />
<h:inputHidden id="tempHTML" value="#{eventProvider.tempHTML}" />
</h:form>
<h:form id="formBotones" prependId="true">
<p:remoteCommand name="omitTextLayer" process="#this" update="formBotones-wizardEventContainer" actionListener="#{eventProvider.omitTextLayer()}" />
<p:remoteCommand name="modifyTextLayer" actionListener="#{eventProvider.modifyTextLayer()}" />
<h:inputHidden id="tempCSSforModify" value="#{eventProvider.tempCSSModified}" />
<h:panelGroup layout="block" id="wizardEventContainer" styleClass="wizardEventContainer">
<h:inputHidden id="tempTextIdLayer" value="#{eventProvider.tempTextIdLayer}" />
</h:panelGroup>
</h:form>
JS code linked with JAVA method
function showEditor(mode){
if(mode=='save')
saveLayer();
if(mode=='delete')
deleteLayer();
if($('#eventEditorContainer').css('visibility')=="hidden"){
$('#eventEditorContainer').css('visibility','visible');
$('#formControl-textLayerBtn').prop("disabled",true);
}
else{
$('#eventEditorContainer').css('visibility','hidden');
$('#formControl-textLayerBtn').prop("disabled",false);
}
}
function deleteLayer(layer){
if(layer==null){
var idLayer='formBotones-' + $('#formBotones-tempTextIdLayer').val();
$('#' + idLayer).remove();
$('#formEditor-tempCSS').val('');
$('#formEditor-tempHTML').val('');
}
else{
var idLayer=layer.parent().attr('id');
layer.parent().remove();
$('#formBotones-tempTextIdLayer').val(idLayer.substring(idLayer.indexOf("-")+1));
$('#formEditor-tempCSS').val('');
$('#formEditor-tempHTML').val('');
}
omitTextLayer(); // p:remoteCommand function
}
P.D: I'v edited adding full code sample and js code which link to java method on p:remoteCommand
Thanks!

Update works right using IDs if p:remoteCommad if thrown from p:commandButton instead of h:commandButton.
So, code must change to
<p:commandButton value="#{msg['omitLayer.btn']}" alt="#{msg['omitLayer.btn.alt']}" title="#{msg['omitLayer.btn.title']}" onclick="showEditor('delete')" />

Related

jsf ajax request recreates viewscoped bean

I use JSF 2.2 and Primefaces 3.5, and I have a problem with ajax request when I update parent component:
<h:panelGroup id="PAG_CARTELERA" layout="block">
<h:form id="FRM_CARTELERA">
<h:panelGroup rendered="#{!carteleraController.existeCookieCinePref}">
<ui:include src="/paginas/cartelera/cinePreferidoIn.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{carteleraController.existeCookieCinePref}">
<ui:include src="/paginas/cartelera/carteleraOut.xhtml" />
</h:panelGroup>
</h:form>
</h:panelGroup>
In the page carteleraOut.xhtml I have:
<p:calendar id="CART_FECHA" value="#{carteleraController.fechaConsulta}"
maxlength="10"
size="10"
locale="es"
pattern="dd/MM/yyyy"
navigator="true"
showOn="button"
showButtonPanel="true">
<f:converter converterId="calendarConverter" />
<p:ajax process="#this" update=":PAG_CARTELERA" event="dateSelect" listener="#{carteleraController.consultarOtroDiaAction}" />
In the "consultarOtroDiaAction" listener I set the "existeCookieCinePref" boolean field and return void to stay in the same view ("carteleraController" is a ViewScoped a bean).
However the first ajax request when I change the value of the p:calendar component works fine, but the following requests recreates the ViewScoped bean.
Why is this?
Thank you.
NOTE: If in the p:calendar ajax request I update a component of the carteleraOut.xhtml itself, it works, but if I update the whole PAG_CARTELERA panelgroup, it recreates the bean.
can you try h:panelGroup inside of h:form
<h:form id="FRM_CARTELERA">
<h:panelGroup id="PAG_CARTELERA" layout="block">
<h:panelGroup rendered="#{!carteleraController.existeCookieCinePref}">
<ui:include src="/paginas/cartelera/cinePreferidoIn.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{carteleraController.existeCookieCinePref}">
<ui:include src="/paginas/cartelera/carteleraOut.xhtml" />
</h:panelGroup>
</h:panelGroup>
</h:form>

rich:calendar not triggering f:ajax

I'm new to jsf, and I'm writing my first application using richfaces. I'm having trouble with the ajax tag that I use to update the associated managed bean property on server for rich:calendar components. This is the code:
<rich:panel header="Computing Options">
<h4>Time Interval</h4>
<h:panelGrid columns="4" width="100%">
<h:outputText value="From" />
<rich:calendar id="intervalFrom" value="#{scenarioEditor.intervalFrom}" popup="true" showApplyButton="true" datePattern="yyy-MM-ddTHH:mm">
<a4j:ajax execute="#this" event="change" render="outFrom" />
</rich:calendar>
<h:outputText value="To" />
<rich:calendar id="intervalTo" value="#{scenarioEditor.intervalTo}" popup="true" showApplyButton="true" datePattern="yyy-MM-ddTHH:mm">
<a4j:ajax execute="#this" event="change" render="outTo" />
</rich:calendar>
<h:outputText id="outFrom" value="From: #{scenarioEditor.intervalFrom}" />
<h:outputText id="outTo" value="To: #{scenarioEditor.intervalTo}" />
</h:panelGrid>
<h4>Algorithms</h4>
<h:panelGrid columns="2">
<h:selectBooleanCheckbox value="#{scenarioEditor.visibilityClashes}" id="clash" >
<f:ajax execute="#this"/>
</h:selectBooleanCheckbox>
<h:outputLabel value="Visibility Clashes Evaluator" for="clash" style="width:170px" />
<h:selectBooleanCheckbox value="#{scenarioEditor.xBandInterference}" id="xband" >
<f:ajax execute="#this"/>
</h:selectBooleanCheckbox>
<h:outputLabel value="X-Band Interferences Evaluator" for="xband" style="width:170px"/>
</h:panelGrid>
</rich:panel>
checkboxes works fine, but the calendars do not. Why? I`ve tried both f:ajax and a4j:ajax without luck.
To better clarify, I want that right after the user has finished entering a value into the calendar, an ajax request is made that call the setter method for the associated property. And this, for the calendar does not happen while for the checkboxes, it does.
The ajax event is failing because of T in datePattern="yyy-MM-ddTHH:mm" is not a valid date formatting pattern. If you add a <rich:messages/> component to your field, you'll see that a conversion error is occurring on each ajax request. Remove the T and you'll be fine

selectBooleanCheckbox ajax event fires but the listener is never executed

The selectBooleanCheckbox ajax event fires but the listener is never executed.
If I remove the c:forEach and just call the first one in the list it works.
<p:selectBooleanCheckbox value="#{Controller.graphFilter.get(0).checked}" >
<p:ajax listener="#{Controller.addMessage}" />
</p:selectBooleanCheckbox>
notes:
graphFilter is a list where container has the sets/gets for checked and description.
controller is a viewscoped managed bean.
addMessage public function that puts a message for the growl.
Everything is in the same form.
<h:form id="form" prependId="false">
<p:growl id="growl" showDetail="true"/>
<c:forEach items="#{Controller.graphFilter}" var="Gc">
<h:outputText value="#{Gc.description}" />
<p:selectBooleanCheckbox value="#{Gc.checked}" >
<p:ajax listener="#{Controller.addMessage}"/>
</p:selectBooleanCheckbox>
</c:forEach>
</h:form>
You should wrap your components with a p:column:
<p:column>
<h:outputText value="#{Gc.description}" />
<p:selectBooleanCheckbox value="#{Gc.checked}" >
<p:ajax listener="#{Controller.addMessage}"/>
</p:selectBooleanCheckbox>
</p:column>
But replacing the whole structure with a p:dataList would be more elegant.

Ajax not working with primefaces

In my JSF page I have form when I click submit button in the same page I need to show an static content. But When I click <p:commandbutton> nothing appears in the page. When I put ajax="false" then only action taken place but the Static content display in new page.
In my Backing bean I have used Session scoped. I am using JSF 2.0 and Primefaces 3.2.
My JSF Page.
<h:form>
<h:panelGroup rendered="#{not license.showForm}">
<p:panel header="License Key Request" >
<h:panelGrid columns="2" >
..
<h:outputText value="Bla bla"/>
..
<h:outputText value="Bla Bla" />
</h:panelGrid>
<TABLE>
..
<h:outputLabel for="name" value="Requestor Name : *" />
..
<p:inputText id="name" value="#{license.name}" required="true" requiredMessage="Name is required."/>
..
<h:outputLabel for="company" value="Company : * " />
..
<p:inputText id="company" value="#{license.company}" required="true" requiredMessage="Company is required."/>
..
</table>
<p:commandButton value="Form" id="btnAdd" process="#form"
action="#{license.add}" />
..
</table>
</p:panel>
</h:panelGroup>
<h:panelGroup rendered="#{license.showForm}" >
<h:outputText value="Bla Bla"/>
</h:panelGroup>
</h:form>
Your source code is somewhat confusing (e.g. you have two closing table tags). But I assume that you want to show the panelGroup at the bottom if the button is clicked.
The easiest way would be to add an update ="#form" to your commandButton:
<p:commandButton value="Form" id="btnAdd"
process="#form" update="#form"
action="#{license.add}" />
You don't need to update the whole form but only the specific component. Then you need to give the panelGroup an id attribute and use this attribute instead of #form. However, since it is not clear for me how your naming containers are organized, it could be puzzling to find the correct relative id.

Rendering other form by ajax causes its view state to be lost, how do I add this back?

I have
<h:form>
<h:commandLink action="#{my_fake_ajax_link}">
<h:outputText value="Link" />
<f:ajax render=":mydiv" />
</h:commandLink>
</h:form>
<h:panelGroup layout="block" id="mydiv">
<h:form>
<h:commandLink action="#{mybean.delete(0)}">
<h:outputText value="Here" />
<f:ajax render="#form" />
</h:commandLink>
</h:form>
</h:panelGroup>
When I click once on "my_fake_ajax_link", then I have to click twice on "delete" link. This is only an example. I don't have this real case. I have multiple forms on a page and I can't just add all of them in a single form.
I checked what the problem is and it is:
When you click on "my_fake_ajax_link", the mydiv refreshs with ajax as it should.
ViewState of the refreshed form on ajax is missing.
How can I add the ViewState? How can I make it work without using only one form? This looks like an JSF bug to me. I don't want to refresh that div automatically with
jQuery("#mydiv").load(document.location.href);
but I will in my worst case possible.
This is a known problem in the auto-included jsf.js library of JSF which handles ajax responses. See also JSF spec issue 790 which is fixed in the upcoming JSF 2.3. In the meanwhile, with JSF 2.0/2.1/2.2, you have to explicitly specify the ID of the other <h:form> inside the render attribtue to trigger proper addition of the view state.
<h:form>
<h:commandLink action="#{my_fake_ajax_link}">
<h:outputText value="Link" />
<f:ajax render=":mydiv :mydivForm" />
</h:commandLink>
</h:form>
<h:panelGroup layout="block" id="mydiv">
<h:form id="mydivForm">
<h:commandLink action="#{mybean.delete(0)}">
<h:outputText value="Here" />
<f:ajax render="#form" />
</h:commandLink>
</h:form>
</h:panelGroup>
No, this does not cause any overhead or markup duplication in the ajax response. Alternatively, use OmniFaces fixviewstate.js.
See also:
Communication in JSF 2.0 - Ajax rendering of content which contains another form
h:commandButton/h:commandLink does not work on first click, works only on second click
Workaround for that:
First you need to set an onevent handler for the button that sends the ajax request:
<h:form id="newComment">
<h:commandButton id="saveNewComment" action="#{postBean.actionSaveNewCommentAjax}" value="#{rb['speichern']}">
<f:ajax execute="#form" render=":commentsBox" onevent="function(data) { fixOtherFormsViewState(data, 'newComment') }" />
</h:commandButton>
</h:form>
Then you need to declare this javascript methods that will take the correct viewState value and add it to all forms which doesn't have it:
<h:outputScript>
function fixOtherFormsViewState(data, goodFormId) {
if (data.status != "success") {
return;
}
var viewState = jQuery("#" + goodFormId + " input[name='javax.faces.ViewState']").val();
jQuery("form:not(:contains(input[name='javax.faces.ViewState']))").each(function (idx, elem) {
var form = jQuery(elem);
var input = jQuery("<input type='hidden' name='javax.faces.ViewState' />").val(viewState);
form.append(input);
});
}
</h:outputScript>

Resources