This question already has an answer here:
How to monitor asynchronous/background thread status and get notifications in a JSF component
(1 answer)
Closed 6 years ago.
I want a inputTextarea to display lines appended to some text file. I imagine it like this: The user clicks a commandButton that does a AJAX call.
My problem is: The text will only be rendered when the action returns. However, my action should look like this:
while(true) {
String newData = getSomeMoreDataFromServer();
// append the new data to a textarea and the user should see it immediately
if(blabla) { break; }
}
Is this even possible? The part that's commented out is the part that bothers me.
Can the user even set the break condition in the form somehow?
I'm using JSF 2 (MyFaces) + Tomahawk.
That's not possible from inside the backing bean action method. Also having a while(true) is very CPU-inefficient, you'd rather like to avoid that in a multi-user environment. What you're looking for is ajax poll/push. This is not provided in the standard JSF implementation and also not in Tomahawk. PrimeFaces for example, supports ajax poll/push components <p:poll> and <p:push>.
Related
I have an JSF application with Primefaces 5.1 components and I have a problem regarding the Primefaces ajax calls.
On the view, there is a hidden <p:commandButton> that every x seconds it is triggered(by event="click") and a web-service call is done. Now, the problem is that when this ajax call is executing, the whole UI it gets blocked and the user can't interact with the application anymore.This is a huge problem for me since this call can take up to 1 second.
For example, if the user types something in an input field, and in the same time the ajax call is done, everything the user typed is displayed after the call is completed.
My question is the following: Does anyone experienced the same problem? If yes do you find a way of doing things as the ajax call won't block the UI? Thank you.
I must add that the commandButton component have an async attribute. I have set the attribute to true, but the problem persists.
I want to implement a "typeahead" type of functionality but for effiency reasons to avoid return a list of possibly thousands of entries, I only want to fire the request to the server when the user has entered at least three characters. I.E. on the 3rd keypress, I want to call my server side search via ajax.
I'm not looking for a full runnable example, just a sketch of how this might be possible, as I'm a bit stumped by it.
I do have a generic ajax handler js file in my app to render the ajax "spinner" so I thought I might be able to hook into event method for status="begin" and somehow abort the request if the input field has less than 3 characters but I don't see how that's possible.
I'm hoping a certain JSF guru might be able to point me in the right direction :)
I'm using standard reference JSF2, no 3rd party libraries...
How about adding a onkeyup="myFunction(event)" to your input
<input type="text" onkeyup="myFunction(event)">
and in js add the following
function myFunction(e){
if (e.target.value && e.target.value.length > 2) {
alert('do some ajax with the value: ' + e.target.value);
}
}
In jsf you can add some hidden input with f:ajax and trigger it from js with somethign like this document.getElementById("myButtonId").click();
Online example
I've got a wicket dropdown choice, and when I select something, I want to update some components within the form. This is working fine using wicket (1.4) ajax. However, it's updating the whole form including the dropdownchoice itself. There are quite a lot of items in the dropdown list (maybe 2000) so it's not great from a performance point of view.
Here's the page hierarchy:
form (Form)
|----packageDDC (DropDownChoice)
|----pptview (RefreshingView)
|----buy (Button)
packageDDC.add(new AjaxFormComponentUpdatingBehavior("onchange") {
protected void onUpdate(AjaxRequestTarget target) {
//--snip-- update pricepoints which back up the pptview
target.addComponent(form); //ie the form
}
}
In the ajax debug window I can see all the dropdown choice options being re-sent every time
What I want to do is only update the pptview and the Button via ajax, not the contents of the dropdownchoice.
I tried adding pptview to the target, but it complains that RefreshgViews can't be updated via ajax.
I tried wrapping the pptview with an EnclosureContainer, but wicket didn't like that either (something about setRenderBodyOnly)
So I tried using an WebMarkupContainer (called 'pptcontainer') and setting pptview to be a child of that - but now the pptview is not updated. Instead it says (in Ajax debug):
"ERROR: Wicket.Ajax.Call.processComponent: Component with id [[purchaseButton2f]] was not found while trying to perform markup update. Make sure you called component.setOutputMarkupId(true) on the component whose markup you are trying to update."
"ERROR: Wicket.Ajax.Call.processComponent: Component with id [[pptcontainer2e]] was not found while trying to perform markup update. Make sure you called component.setOutputMarkupId(true) on the component whose markup you are trying to update."
well these objects definitely do have this set to true:
buy.setOutputMarkupId(true);
pptcontainer.setOutputMarkupId(true);
pptcontainer.setOutputMarkupPlaceholderTag(true);
So the page is not updated correctly.
What am I doing wrong?
The new hierarchy is:
form (Form)
|----packageDDC (DropDownChoice)
|----pptcontainer (WebMarkupContainer)
| |----pptview (RefreshingView)
|----buy (Button)
I faced same problem with popup window which content is provided by ajax call. In my case the problem was solved by changing html placeholder "wicket:container" to "div" element as proposed in this article: http://sha.nnoncarey.com/blog/archives/36
After this change generated html has correct id and wicket do not have problem to find it and replace content with AJAX response.
In respose to Infragile's request in another thread, I am asking this as a separate question rather than a followup.
Here is the problem I am attempting to address:
I'm migrating from JSF1.2 to JSF2. Everything worked fine in JSF1.2.
I have rewritten a critical item to be a composite component which is basically a panel created in my backing bean by adding components in code.
In particular, I have h:inputText and h:selectOneMenu components that I create in code along with an "Apply" h:commandButton.
The "Apply" button has an action listener that checks for the values in the h:inputText and h:selectOneMenu components. All this works fine, but when I fetch the values in the h:inputText or h:selectOneMenu components I get the original values, not the new values that were entered by the user. Like I said, this worked fine in JSF1.2 (i got the new values), but not in JSF2 for some reason.
I have tried several things to get around this that haven't worked, so I figured I would add ajax behavior to the h:inputText and h:selectOneMenu items and when the values in these components change, I could call another backing bean listener for the ajax behavior to fetch the new values.
I am trying to add ajax behavior to a component I create in code (not bound to a page component). I can create the component with no problem. However, the problem that I am having is how to add the ajax behavior to the component.
Could someone post sample code to add an ajax behavior for a value change or blur event? Here is the code I use to create the component in code - how would I need to modify it to add the ajax behavior?
hpg = new HtmlPanelGrid();
children = hpg.getChildren();
children.clear();
....
input = new HtmlInputText();
....
children.add(input);
What code would I have to add to replace the "add ajax behavior here" line, and what would the arguement for the listener method be (arguement for the method to replace the ????? below)?
public void myAjaxListener(?????) { ...... {
I have been trying to get a handle on this for some time now. I feel that I am pretty close, but don't know the syntax I need. I can provide more information on how I am fetching the component Ids and searching for the values in my action listener if that will help.
Thanks
This is how you can add dynamically AjaxBehaviorListener to yor component:
...
HtmlInputText inpuText = new HtmlInputText();
AjaxBehavior blurBehavior = new AjaxBehavior();
blurBehavior.addAjaxBehaviorListener(new BlurListener());
blurBehavior.setTransient(true);
inputText.addClientBehavior("blur", blurBehavior)
...
public class BlurListener implements AjaxBehaviorListener {
public BlurListener() {
}
#Override
public void processAjaxBehavior(AjaxBehaviorEvent event) {
// do your job
HtmlInputText inputText = event.getComponent(); // your input text component
...
}
}
"blur" represents event when this listener will be triggered. Remember that JSF Component must support this event, otherwise it won't work.
(Here you can see under covers and how to build custom AJAX component http://weblogs.java.net/blog/driscoll/archive/2009/10/09/jsf-2-custom-java-components-and-ajax-behaviors?force=670 )
However in your case I think problem is that buttons ActionListener is triggered before actual component values are submited. You can solve it by moving your ActionListener logic to button action, by aformentioned AJAX, maybe by findinng actual values in UIComponents (HtmlInputText, UISelectOne), not sure but immediate attribute can also influence it.
I'm requesting an ASP.net MVC view into a live box and the view contains form fields that have been marked up with attributes to be used by JQuery's unobtrusive validators plug-in.
The client script is not however working and my theory is that its because the validation framework is only being triggered on page load which has long since passed by the time the MVC view has been loaded into the live box.
Thus how can I let the validation framework know that it has new form fields to fix up?
Cheers, Ian.
var $form = $("form");
$form.unbind();
$form.data("validator", null);
$.validator.unobtrusive.parse(document);
// Re add validation with changes
$form.validate($form.data("unobtrusiveValidation").options);
You may take a look at the following blog post. And here's another one.
Another option, rather trick, which worked for me. Just add following line in the beginning of the partial view which is being returned by ajax call
this.ViewContext.FormContext = new FormContext();
Reference
For some reason I had to combine bjan and dfortun's answers...
So I put this in my view:
#{
this.ViewContext.FormContext = new FormContext();
}
And this execute this after the ajax call finishes:
var form = $("#EnrollmentForm");
form.unbind();
form.data("validator", null);
$.validator.unobtrusive.parse(document);
form.validate(form.data("unobtrusiveValidation").options);
I had a similar issue. I had a form that was using Ajax requests to re-display a part of the form with different form fields. I used unobtrusive validation by manually doing it on the client side using the
#Html.TextBoxFor
for my text boxes. For some reason the validation works when attempting to submit with invalid fields (i.e., the text boxes get outlined in red and the appropriate error messages display with the content I put in the
data_val_required
attribute, for example.
However, after I click a button that makes an Ajax request to modify the form with different fields and then submit again, only the red outline on the invalid fields display, but no error messages are rendered.
bjan's trick worked for me, but I still can't see what was causing the issue. All the HTML necessary to carry out the client-side validation was there I just can't figure out why the error message attribute values wouldn't display.
All I can think of is that the jQuery validation code doesn't make a second attempt to check the form fields after a submit was made.