I have a h:commandButton calling some action="#{bean.do}". And also some ajax request for that button which should restyle a part of the website. This restyling should take place before the action is executed. How can I do this?
<h:commandButton action="#{bean.do}">
<f:ajax execute="#form" render="specificId" />
</h:commandButton>
As the action do sometimes takes a long time, I want the page first to display a message/image or likewise. And after that frist execute the action. But how?
You can use the onclick attribute to execute some JavaScript code right before the action is invoked.
E.g.:
<h:commandButton ... onclick="document.body.style.background='pink'">
It's however better to use onevent attribute of <f:ajax> for this, so that you can revert the change:
<h:commandButton ...>
<f:ajax ... onevent="handleDo" />
</h:commandButton>
<img id="progress" src="progress.gif" class="hidden" />
with e.g. this which disables/enables the button and displays/hides the progress image:
function handleDo(data) {
var status = data.status; // Can be 'begin', 'complete' and 'success'.
var button = data.source; // The HTML element which triggered the ajax.
var image = document.getElementById("progress"); // Ajax loading gif?
switch (status) {
case 'begin': // This is called right before ajax request is been sent.
button.disabled = true;
image.style.display = "block";
break;
case 'complete': // This is called right after ajax response is received.
image.style.display = "none";
break;
case 'success': // This is called when ajax response is successfully processed.
button.disabled = false;
break;
}
}
Related
My objective is to save the current cursor position and append new values to it for every new button we enter.To achive it i am trying to send a ajax request and update my back end coordinated every time is focus out of the input field.
I am succesfull i calling the java script function before calling by backing bean action method.But for some reason i am unable to see my request param values when ever i make a ajax request.
<p:inputText id="testing1" value="#{dropDownView.city}">
<p:ajax event="keyup" onstart="callOnAjax();" listener="#{dropDownView.assignCity()}" execute="#this" update="out1" >
<f:param value="test" name="#{articlePromo.promocionArticuloId}"/>
<h:inputHidden id="x" value="#{bean.x}" />
</p:ajax>
<script type="text/javascript">
function callOnAjax(){
$("#detailsPanel").bind("keydown keypress mousemove", function() {
var $form = jQuery(this).closest("form");
$form.find("input[id$=':x']").val($(this).caret().start);
alert("Current position: " + $(this).caret().start);
});
}
</script>
And in my dropDownView Controller
public void assignCity()
{
System.out.println("positon of x"+getX()+"position of y"+y);
FacesContext context = FacesContext.getCurrentInstance();
String id = context.getApplication().evaluateExpressionGet(context, "#{articlePromo.promocionArticuloId}", String.class);
city =country;
}
I tried all different approaches using hidden as well.But i dont see the value in my controller.I even hard coded the request param value and hidden attribute value.But still not succesfull.Any help is much appreciated.
I have something like this :
<h:commandButton action="#{MyBean.action()}">
<f:ajax render ="#all"/>
</h:commandButton>
Is it possible to replace the "#all" in the ajax render to refresh the page?
With this code my page doesn't refresh like if I press F5
That's not possible with ajax. Just remove <f:ajax> and send a redirect to self in action method.
<h:commandButton value="Submit and refresh" action="#{bean.action}" />
public String action() {
// ...
FacesContext context = FacesContext.getCurrentInstance();
return context.getViewRoot().getViewId() + "?faces-redirect=true";
}
Or if you actually don't need to perform a business action, just use <h:button> without an outcome.
<h:button value="Refresh only" />
I have set up a basic testcase in which I'm experience some (to me) weird behaviour. When using the setup below, the typed value in the editor will only be visible by h:outputText on the second submit. E.g.
Change value in editor to "myvalue"
Send Ajax-request
h:outputText shows "test" (default value from bean)
Change value in editor to "anothervalue"
Send Ajax-request
h:outputText shows "myvalue"
Send Ajax-request
h:outputText shows "anothervalue"
Note: there's a custom composite, please ask for code if needed (it simply creates textarea for TinyMCE and loads .js file from below)
index.xhtml
<h:body>
<h:form>
<mh:editor id="tinymceEditor"
value="#{bean.value}" />
<h:commandButton value="Ajax">
<f:ajax execute="tinymceEditor"
render="show" />
</h:commandButton>
<h:outputText id="show" value="#{bean.value}" />
</h:form>
</h:body>
jsfhandler.js -> included on header in custom composite mh:editor
jsf.ajax.addOnEvent(function(data) {
switch(data.status) {
case "begin":
tinyMCE.execCommand('mceRemoveControl',true,"tinymceEditor");
tinyMCE.triggerSave();
break;
case "complete":
tinyMCE.execCommand('mceAddControl',true,"tinymceEditor");
break;
case "success":
break;
}
});
Bean.java
#Named
#RequestScoped
public class Bean {
private String value = "test";
}
The JSF ajax begin event is too late in order to take changes in form data into account. The ajax request is already prepared based on form data before this event.
Effectively, the sequence is as follows:
User enters input (and leaves field).
HTML DOM "change" event is triggered on input field.
User clicks submit button.
HTML DOM "click" event is triggered on submit button.
JSF prepares ajax request.
JSF ajax "begin" event is triggered on ajax request.
JSF sends ajax request.
...
Basically, you should be doing tinyMCE.triggerSave() during the HTML DOM "click" event.
<h:commandButton ... onclick="tinyMCE.triggerSave()">
Or, better, during the HTML DOM "change" event of the tinyMCE textarea.
I'm trying to select and focus to choosed component ID after submit a form (ajax call).
<script>
var myFunc = function() {
document.getElementById('form:#{bean.componentId}').focus();
document.getElementById('form:#{bean.componentId}').select();
};
$(document).ready(function() {
myFunc();
});
</script>
<h:form id="form">
<h:commandButton action="#{bean.save}" onclick="return myFunc();" ...>
<f:ajax execute="#form" render="#form"/>
</h:commandButton>
...
</h:form>
This solution is working, but problem is, that <f:ajax> is called AFTER onclick, so the the form is rendered after component selection, and focus is cleared.
How can I call my function AFTER the form is rendered?
update: (I've tried for example)
add onevent="myFunc();" to f:ajax => leads to refreshing page
add onevent="myFunc()" to f:ajax => same behaviour as onclick attribute
next f:ajax with onevent attr. => still the same
update2 (how it should works):
submit button is ajax called
form is cleaned as needed
appropriate field is focused (depended on some user choosed factors)
The onevent handler will actually be invoked three times and it should point to a function name, not the function itself. One time before the ajax request is been sent, one time after the ajax response is been arrived and one time when the HTML DOM is successfully updated. You should be checking the status property of the given data argument for that.
function listener(data) {
var status = data.status; // Can be "begin", "complete" or "success".
switch (status) {
case "begin": // Before the ajax request is sent.
// ...
break;
case "complete": // After the ajax response is arrived.
// ...
break;
case "success": // After update of HTML DOM based on ajax response..
// ...
break;
}
}
In your particular case, you thus just need to add a check if the status is success.
function myFunc(data) {
if (data.status == "success") {
var element = document.getElementById('form:#{bean.componentId}');
element.focus();
element.select();
}
}
And you need to reference the function by its name:
<f:ajax ... onevent="myFunc" />
I want to be able to disable the commandbutton below once it's hit and enable it once the event listener runs and msg1 is rendered.
<h:commandButton value="Submit">
<f:ajax execute="#form" render="msg1" listener="{bean.method}" />
</h:commandButton>
How could I do this?
UPDATE: I found out that I can attach onclick event to the commandButton element itself to disable it. How can I detect the listener method has returned so I can enable the button again?
You could do it with help of the onevent attribute of <f:ajax> which points to a JavaScript function which handles the JSF Ajax events.
E.g.:
<h:commandButton value="Submit">
<f:ajax execute="#form" render="msg1" listener="#{bean.method}" onevent="handleDisableButton" />
</h:commandButton>
(note that I fixed the wrong EL in listener as well)
with this JS:
function handleDisableButton(data) {
var buttonElement = data.source; // The HTML DOM element which invoked the ajax event.
var ajaxStatus = data.status; // Can be "begin", "complete" and "success".
switch (ajaxStatus) {
case "begin": // This is called right before ajax request is been sent.
buttonElement.disabled = true;
break;
case "complete": // This is called right after ajax response is received.
// We don't want to enable it yet here, right?
break;
case "success": // This is called when ajax response is successfully processed.
buttonElement.disabled = false;
break;
}
}
If you use richfaces, the a4j:commandButton has the status attribute which prevent this.