Reload page from backing bean - jsf

In my code, I'm expanding treeNode in left frame that is selected through navigation links present in right frame. It works but everytime I click the link on right frame, I have to refresh the right frame manually. I tried to reload the page from backing bean using javascript code but it's not working. Can anyone please help me to figure out why it's not getting executed.
Thanks in advance for helping me out.
Below is the code I'm using.
public void expandTreeView( TreeNode selectedNode )
{
if ( selectedNode != null )
{
selectedNode.getParent().setExpanded( true );
}
RequestContext rc = RequestContext.getCurrentInstance();
rc.execute("window.location.reload(true)");
}

You need to combine a JS Function with remoteCommand, it will look like this :
myHTML.xhtml
<p:commandLink id="commandLink" onclick="myFunction(nodeSelected)" >
...
</p:commandLink>
Also add a JS function
<script type="text/javascript">
function myFunction(x) {
...
}
</script>
and finally combine it with a p:remoteCommand it allows you to call a managedBean method from your JS function
You can see Primefaces remoteCommand Example or simply look to this SO post Invoking a p:remoteCommand via a JavaScript function passing a message local to that function to another function through the “oncomplete” handler
Hope that helped you.

Related

PrimeFaces.current().focus Not working on commandButton

PrimeFaces.current().focus method works with inputTexts but with a commandButton I see no results, alternative I can use executeScript but the idea is to use focus for this kind of requeriment:
This works:
PrimeFaces.current().executeScript("document.getElementById('frmAperturaCajaMasiva:btnAceptarAperturaCajaMasiva').focus();");
This works on inputTexts but not working on button:
PrimeFaces.current().focus("frmAperturaCajaMasiva:btnAceptarAperturaCajaMasiva");
Any idea why? its the same thing but different in both commands
This is the code of the button on the xhtml nothing fancy :)
<p:commandButton id="btnAceptarAperturaCajaMasiva"
value="#{etiquetasMsg.cerrar_caja}" styleClass="cds-icon-button"
icon="cds-icon aprobar"
disabled="#{aperturaMasivaMB.blBtnProcesar}"
title="#{tooltipsMsg.cierrecaja_masiva_cerrar}"
onclick="if(!confirmarSeleccionTabla(PF('dtbFrmCajaWv'),null)){ return false; }"
actionListener="#{aperturaMasivaMB.validarCierreCajaMasivo}"
rendered="#{adminRestriccionMB.validarRestriccion('BTN_CERRAR_CAJAMASIVO')}" />
Yes I know why. The focus method in PrimeFaces specifically excludes buttons it was intended to focus input fields. Here is the source code.
focus: function(id, context) {
var selector = ':not(:submit):not(:button):input:visible:enabled[name]';
Notice the "not(:submit):not(:button)" in the Jquery selector.
Source code:
https://github.com/primefaces/primefaces/blob/master/primefaces/src/main/resources/META-INF/resources/primefaces/core/core.js#L699-L728

Primefaces blockUi trigger by boolean value

How to trigger primefaces <p:blockUI> using boolean in backing bean? In this showcase, it requires a commandButton to trigger the the blockUI. What I want is block some part of the page base on a boolean in the backing bean. Is this possible? I tried setting the rendered attribute in the <p:blockUI> tag but it still won't work.
Here is my code:
<p:blockUI block="grid" rendered="#{bean.trueValue}"></p:blockUI>
<p:panelGrid id="grid">
-- content
</p:panelGrid>
One way is to call hide() and show() method of BlockUI from Managed Bean.
You can do that by using RequestContext:
RequestContext.getCurrentInstance().execute("widgetVar.show()");
Another is you can pass the variable to JavaScript function and then let the Javascript function take care of that for you.
onClick="func(#{elvariable})"
<script type="text/javascript">
function func(value)
{
if(value==something){
widgetVar.show();
}else{
widgetVar.hide();
}
}

p:remoteCommand returns <eval> twice in ajax response

I try to render a new page in a new window (or tab) with the link I get from a selected page object in an autoComplete component.
After trying multiple options the only chance in my opinion is to use javascript to catch the submit, trigger a remote command, that gives me a javascript call with the link attribute from the page object.
JSF-Snipplet (with reduced attributes in autoComplete)
<h:form id="autoCompleteForm">
<p:autoComplete id="autoComplete" widgetVar="autoCompleteWidget" value="#{pageBean.selectedPage}" />
<p:remoteCommand action="#{pageBean.showPage}" name="showPage" />
</h:form>
some JS:
// form submit
('#autoCompleteForm').on('submit', function(e) {
e.preventDefault();
showPage();
});
// open link
var openLink = function(pageLink) {
window.open(pageLink, '_blank');
};
Bean part for action
public void showPage() {
RequestContext context = RequestContext.getCurrentInstance();
context.execute("openLink('" + selectedPage.getLink() + ".xhtml')");
}
Everything works nice together, but the response contains the eval tag twice.
<partial-response>
<changes>
<update id="javax.faces.ViewState"><![CDATA[2851816213645347690:-2276123702509360418]]></update>
<eval><![CDATA[openLink('target.xhtml');]]></eval>
<eval><![CDATA[openLink('target.xhtml');]]></eval>
</changes>
</partial-response>
I tried different approaches with redirects or returning view names, but that all leads to no satisfying solutions (e.g. URL not changing or no new window).
Problem solved:
I had defined PrimePartialViewContextFactoryin my faces-config before:
<factory>
<partial-view-context-factory>org.primefaces.context.PrimePartialViewContextFactory</partial-view-context-factory>
</factory>
By removing it the application acts like expected.
This also solves a problem (JSON.parse: unexpected non-whitespace character after JSON data) with pagination and sorting in DataTables.

How to apply Primefaces effect when component is rendered

i have drag panel and drop panel, and when component is dropped in the drop panel i show a new panel and hide the old panel based on render boolean attribute as follows:
1- xhtml:
<p:outputPanel id="oldPanel" rendered=#{myBean.old_panel_rendered}> .... </p:outputPanel>
<p:outputPanel id="newPanel" rendered=#{myBean.new_panel_rendered}> .... </p:outputPanel>
2- bean:
old_panel_rendered=true;
new_panel_rendered=false;
public void onComponentDrop(DragDropEvent ddEvent) {
old_panel_rendered=false;
new_panel_rendered=true;
}
how to execute an effect for newPanel when it gets rendered and execute an effect for oldPanel when it gets unrendered.
please advise, thanks.
Call js function which will apply the effects when a new item droppped:
<p:ajax listener="#{bean.onDrop}" onstart="applyEffects();" update="newPanel" />
Function is:
function applyEffects() {
var oldPanel = $(document.getElementById('oldPanel'));
var newPanel = $(document.getElementById('newPanel'));
oldPanel.css({"display":"none"});//or oldPanel.fadeOut(500) which looks fancy
newPanel.css({"display":"inline"});
newPanel.effect("highlight",
{color:"#87FF7A"}, 1500);
}
Don't forget to give exact client id of components when calling document.getElementById. You can detect it via your browser's developer settings. If there will be a problem, you can drop update="newPanel" or maybe you can try update="oldpanel newpanel".
To be able to apply it for specific panel:
public void onComponentDrop(DragDropEvent ddEvent) {
int id = event.getData();//or sth.similar to getId
RequestContext.getCurrentInstance().addCallbackParam("index", id);
}
Upper code adds a parameter to ajax response it can be retrieved by:
function applyEffects(xhr,status,args) {
var oldPanel = $(document.getElementById('oldPanel'));
var newPanel = $(document.getElementById('newPanel'));
if(args.id=='oldPanel') {//oldPanel or whatever which equals to eventID
oldPanel.css({"display":"none"});//or oldPanel.fadeOut(500) which looks fancy
}
newPanel.css({"display":"inline"});
newPanel.effect("highlight",
{color:"#87FF7A"}, 1500);
}
You should call this from p:ajax oncomplete="applyEffects(xhr,status,args);". I am coding directly here, therefore can be few mistakes which can be seen on IDE easily.

Disable commandButton in JSF

This seems like it should be pretty straightforward but I'm not feeling it.
I have a JSF CommandButton that executes a long running serverside task (10-15 seconds). I've seen forms where the button context changes after it's been clicked (The label on the button changes and the button becomes disabled until the processing is complete).
I'm using ICEFaces and have the disabled property set to a boolean on the underlying page code.
The action listener bound to the button changes that boolean to disable it but alas, no changes on the JSP.
Anyone?
What you can do is to change the status of the button using Javascript:
<h:commandButton ... onclick="this.disabled=true"/>
Edit regarding the comment:
If the previous code does not submit the form, then you have to disable the button a little time after the click, not "during" the click itself. You can do that using the following code:
<h:commandButton ... onclick="setTimeout('this.disabled=true', 100);"/>
I'm not sure if the fact to use the this keyword directly in the setTimeout method will work correctly. If not, you can use another way to do that:
<h:commandButton ... onclick="disableButton(this.id);"/>
with the following Javascript function:
function disableButton(buttonId) {
setTimeout("subDisableButton(" + buttonId + ")", 100);
}
function subDisableButton(buttonId) {
var obj = document.getElementById(buttonId);
if (obj) {
obj.disabled = true;
}
}
(I'm sure this code can be enhanced, thus)
You should use an ice:commandButton instead of h:commandButton, since it has the partialSubmit property, which will perform the action as an AJAX call. This should refresh your button's state, so if the property on the server has been set to false, your button should be disabled.
do a javascript submit(); first and then disable the button
Similar to the solution from romaintaz
For a Firefox specific solution, the following works (it does not work in IE):
<h:commandButton ... onclick="disableButton(this.id);" />
Using Javascript function:
function disableButton(buttonId) {
var obj = document.getElementById(buttonId);
if (obj) {
setTimeout(function(thisObj) { thisObj.disabled=true; }, 50, obj);
}
}
do it after icefaces has updated the DOM. you can use ice.onAfterUpdate(callback):
Here with jQuery
ice.onAfterUpdate(function(){
updateButtons();
});
function updateButtons(){
if(!isButtonEnabled()){
jQuery(".myButton").attr('disabled', true);
jQuery(".myButton").removeClass("iceCmdBtn").addClass("iceCmdBtn-dis");
}else{
jQuery(".myButton").removeAttr('disabled');
jQuery(".myButton").removeClass("iceCmdBtn-dis").addClass("iceCmdBtn");
}
}

Resources