voyent
Messages posted by: edykory  XML
Profile for edykory -> Messages posted by edykory [319] Go to Page: Previous  1, 2, 3 , 4, 5 ... 20, 21, 22 Next 
Author Message
Hello,
According to the component's documentation, the bean implementing the progressListener should be session-scoped.
Also it states that progressRender="true" will take care of all the plumbing code of implementing the Renderable interface for that bean. In this case (when using progressRender="true"), is it still necessary for the bean to be session-scoped? I checked with a request scoped bean, and it seams to be OK, but I'd like to hear the official answer.

Thanks a lot

Eduard Korenschi
Here's a piece of code you could use:
Code:
 package ro.ascenta.faces.converter;
 
 import java.text.ParsePosition;
 import javax.faces.application.FacesMessage;
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 import javax.faces.convert.Converter;
 import javax.faces.convert.ConverterException;
 import org.apache.commons.lang.StringUtils;
 import ro.ascenta.faces.Messages;
 import ro.ascenta.util.ThreadSafeDecimalFormat;
 
 public class DoubleConverter implements Converter {
 	public final Object getAsObject(FacesContext context, UIComponent component, String value)
 			throws ConverterException {
 		if (context == null || component == null)
 			throw new NullPointerException();
 		if (StringUtils.isBlank(value))
 			return null;
 		ParsePosition parsePosition = new ParsePosition(0);
 		Number n = ThreadSafeDecimalFormat.getDoubleFormatter().parse(value, parsePosition);
 		if (n == null || parsePosition.getIndex() != value.length())
 			throw new ConverterException(Messages.getMessage(context, FacesMessage.SEVERITY_ERROR, null,
 				"javax.faces.converter.DoubleConverter.DOUBLE", new Object[] { value, "23.564", Messages.getLabel(context,
 							component) }));
 		return n instanceof Double ? n : new Double(n.doubleValue());
 	}
 
 	public final String getAsString(FacesContext context, UIComponent component, Object value)
 			throws ConverterException {
 		if (context == null || component == null)
 			throw new NullPointerException();
 		if (value == null)
 			return null;
 		if (value instanceof String)
 			return (String) value;
 		try {
 			return ThreadSafeDecimalFormat.getDoubleFormatter().format(((Number) value).doubleValue());
 		} catch (Exception e) {
 			throw new ConverterException(Messages.getMessage(context, FacesMessage.SEVERITY_ERROR, null,
 					"javax.faces.converter.STRING", new Object[] { value, Messages.getLabel(context, component) }));
 		}
 	}
 }
 
 

Basically, what it does is what I wrote in the previous post: It will convert to Double (always) and is not fault tolerant (it will not accept 12.3p as input for example, something f:convertNumber doesn't).
The only unknown part is
ThreadSafeDecimalFormat.getDoubleFormatter()
which is just a thread safe way to get a DecimalFormat object (I recycle them in one thread) customized to your formatting needs.
If extreme performance is not what you need, you can replace it with
new DecimalFormat("#,###.##")
(which is what my ThreadSafeDecimalFormat does, it just stores one instance per thread using ThreadLocal)

PS: this works on JSF 1.2. For 1.1 you'll have to change the error message key.
Cheers!

Eduard
The fact that it works doesn't mean that it's the right way to do it:

1. According to JSF specification, if you use f:convertNumber, the type of the result depends on the input: if the user enters 0 you will get a Long, if he enters 0.1 you'll get a Double, no matter what you have on your bean. So the correct way to work with f:convertNumber (no matter what other attributes you use, like pattern, or so) is to use a Number on the backing bean, not Integer, or int, or float, or Float, or Double or anything like that.
2. If you use f:convert id="javax.faces.Double" or the converter attribute in the input controls you will always get a Double, but then you cannot specify any formatting.

If neither of these two situations suits you, try to write your own converter (in which case by the way you will also be able to make it non lenient) ... it's not that difficult and much more flexible.

Eduard
Before closing the body tag I have a
Code:
 <script>
 	document.forms.mainFrm['mainFrm:username'].focus();
 </script>
 
piece of code ... For me it works nice enough. Just pay attention to replace "mainFrm" with the id you gave to your form and "username" with the id you gave to you username field.

But don't forget, this piece of code will be executed during the first load of the page ... on subsequent refreshes (like after something gets executed on the server) you should use some JavascriptContext call or the focus requesting api (It used to be documented in the IceFaces documentation).

Eduard
Man, this is killing me.
A attach here two screenshots with the application. The first one (screenshot1) is the one looking right, the second one is the one messed up by IE 7.
All this time, the log console (CTRL+SHIFT+T) showed nothing.

And what's more scarry:
After the page gets blank, I press ALT (highlighting the menubar) and the application get's shown again correctly. Then it disappears again. And all this without any JS code from my side.

The only fishy thing could be the fact that I have more than one form per page (on the same level of course).

Eduard.
Hi again, patrick
Could you recommend me any javascript debugger for IE 6, just in case I'm crazy enough to check debugging the client side Javascript code? I'm sure the problem is in there, and it could also save you some time.

Thanks,

Eduard
Hi patrick,
thanks a lot for the fast answer,

As you could see from my post, I did the CTRL+SHIFT+T thing, but the click only generated the "Interup pressed " message and the page turned blank. No server side action whatsoever.

Anyway, some addition info:
The behavior happens only on 2 pages like this:
1. If I expand a panelCollapsible and then click anywhere on the page
2. If I select a row with a rowSelector and then click anywhere on the page.
And still, I have lots of pages with similar content and it doesn't behave like that, otherwise I could have isolated some portion and send it to you for analyse.
Also, the blank stuff happens only on one portion of the page. The facelets template generates also some header and a navigation bar which don't get blank-ed.

I will double check about using the outputDeclaration on all pages.

God, I just love Microsoft, don't you?

Eduard
Hello there,

We are now developing an application using IceFaces 1.7.1, Facelets and JBoss 4.2.2.
On some pages we have met the following strange behavior:
When one user click in the page (be it a panelCollapsible, an inputText, the background, etc) a portion of the page turns blank. The behavior happens only on IE 7.0 (I checked on Opera, FireFox 2/3 and IE 6.0 and cannot reproduce it at all, while on IE 7.0 it happens all the time).

The pages are built by instantiating a facelets template (something like <ui:composition template="/WEB-INF/templates/administration.xhtml">) and redefining some content which in the template was inserted with <ui:insert>.

The logs generated by icefaces during this time (from the moment the application worked normally until the page turned blank) is the following:

[window] : Interup pressed
[window.Pclp#5.async-connection.heartbeat] : ping
[window.Pclp#5.async-connection.ui] : [158362] : send asynchronous POST
[window.Pclp#5.async-connection.ui] : [158362] : receive [200] OK
[window.Pclp#5.async-connection.blocking] : [672573] : receive [200] OK
[window.Pclp#5.async-connection] : closing previous connection...
[window.Pclp#5.async-connection.blocking] : [672573] : connection closed
[window.Pclp#5.async-connection] : connect...
[window.Pclp#5.async-connection.blocking] : [5829607] : send asynchronous POST
[window.Pclp#5.async-connection.ui] : [2372783] : send asynchronous POST
[window.Pclp#5.async-connection.ui] : [2372783] : receive [200] OK
[window.Pclp#5.async-connection.heartbeat] : pong
[window.Pclp#5.async-connection.ui] : [2372783] : connection closed
[window] : Interup pressed
 

So nothing interesting here.
If anyone has any idea, or if anyone met this kind of behavior ... I'd be more than delighted to hear.

Eduard


Hmmm .... looks different now ...
Actually the problem is not that the validation kicks in, but the validation messages are saved between 2 partial submits (why only 2?).
After a deeper thinking ... this looks ok, on a form with many fields ... you want the validation messages to be saved and seen even after navigating from one field to the other ... but in my case ... I have a panelStack ... where a panel can get rendered after it was previously unrendered. And still ... the validation messages are saved ... which is not good, at least for me :)...

Eduard.
No anwer to this one?

I started meeting this kind of strange behavior consistently, also when some commandButton get's involved:

Say I have a selectOneMenu partialSubmit-able and a panelStack whose rendered panel depends on the selected value. In one of the panel of the stack there is a required inputText.

Now, everything works ok, until I try to submit the form with this specific panel rendered. When I do that, required validation kicks in (normally), but then this validation kicks in also when I just change the value of the selectOneMenu on this particular panel.
Here is the xhtml code
Code:
 		<ice:selectOneMenu value="#{myController.selectedPanel}" partialSubmit="true" valueChangeListener="#{myController.selectPanel}">
 			<f:selectItem itemValue="preaccepted" itemLabel="Preacepted OK" />
 			<f:selectItem itemValue="resent" itemLabel="Resend to V1" />
 		</ice:selectOneMenu>
 
 		<ice:panelStack selectedPanel="#{myController.selectedPanel}">
 			<ice:panelGrid columns="1" id="preaccepted">
 				<ice:outputText value="Comment: " />
 				<ice:inputTextarea value="#{myController.comment1}" rows="3" cols="60" label="Comment">
 					<f:validateLength maximum="1200"/>
 				</ice:inputTextarea>
 			</ice:panelGrid>
 			<ice:panelGrid columns="1" id="resent">
 				<ice:outputText value="Comment: *" />
 				<ice:inputTextarea value="#{myController.comment2}" rows="3" cols="60" required="true" label="Comment">
 					<f:validateLength maximum="1200"/>
 				</ice:inputTextarea>
 			</ice:panelGrid>
 		</ice:panelStack>
 		<ice:commandButton value="Save answer" action="#{myController.saveAnswer}" />
 
 

in myController.selectPanel I just update the selectedPanel property to the new one and I force renderResponse().

Now a workaround would be to take away the required attribute from the inputTextarea and do the validation by hand ... but hey ... this is not in the spirit of JSF.

Again, the problem in my opinion is that after a failed validation (because of validator or required), the validation kicks in even on partialSubmits.

Eduard
you don't define the converter on the bean. You just declare it inside the <ice:inputText value="#{bean.value#}"> and </ice:inputText> and the control will call the validator when asked to validate itself.
Then try to have a look at ice:panelPopup combined with a immediate="true" on the buttons ... In this way you don't leave the page (so the component tree remains the same) ....
Hi man,
I didn't want to offend you in any way :D

Still, for your problem, if I got it right, what you could do is the following: instead of using <h:commandButton> use a plain <input type=button> whose onclick should show a popup where the user could choose the desired value. Then, instead of submitting the value the user selected in this mini-window, just populate the main page's field.

Code:
 <input type="button"  value="..." onclick="window.open('path/to/your/servlet/generating/values', 
 'secondWindow', 'location=0,menubar=0,resizable=0,width=500,height=450,scrollbars=1')" />
 

In my case, the path is actually a path to a servlet which generates a table of values (there are about 600 possible values). Inside the servlet I have the following methods:
Code:
 	private void outputFileHeader(PrintWriter out) {
 		out.println("<html><head>");
 		out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
 		out.println("<title>Possible values</title>");
 		out.println("<link href=\"/OTPProject/css/general.css\" rel=\"stylesheet\" type=\"text/css\"></link>");
 		out.println("<script>function setChosenValue(newValue) {");
 		out.println("window.opener.document.forms.id_form['id_form:id_of_your_control'].value=newValue;");
 		out.println("window.close();}</script>");
 		out.println("</head><body>");
 	}
 
 

and when I generate values in the table I use:
Code:
 	private void outputTableRow(PrintWriter out, String cod, String description) {
 		out.println("<tr style=\"background-color: white;\"" + 
 				"onmouseover=\"javascript: this.style.backgroundColor='#CCDDCC';\"" + 
 				"onmouseout=\"javascript: this.style.backgroundColor='#FFFFFF';\">");
 		out.println("<td valign=\"top\" style=\"border-bottom: solid 1px #E0E0E0;\">" + 
 				"<a href=\"javascript:void(setChosenValue('" + cod + "'))\">" + 
 				cod + "</a></td><td style=\"border-bottom: solid 1px #E0E0E0;\">" + description + "</td>");
 		out.println("</tr>");
 	}
 


In this way, the popup window will populate its parent window's field. You can develop based on this, and pass the ids of the form and of the input control as parameters to the servlet and use just one servlet for all the possible inputs.

I hope this helps


Eduard
Well that warning tells you that you validation failed, which is natural. It doesn't show on the screen because you don't have any h:messages control. By default, the number converter will consider "." the decimal separator, not the ",". "," is a group separator at best, like in "12,345,678.20".
I guess the locale attribute of the "f:convertNumber" should do the trick, but read the documentation to see valid values.

Eduard
Man, your complains have nothing to do with IceFaces, but with JSF. In order to solve that, get your hands on a good JSF book and start reading.
You will understand then that JSF is a framework based on a very well defined life-cycle, and that that life cycle is based on certain contracts which have to be obeyed.

So you cannot in any way turn off validation. Not even with immediate=true. That will only move certain things a little bit earlier in the life cycle, but will not avoid validation unless you require a forced renderResponse with facesContext.renderResponse().

I guess what you need is indeed the "immediate=true" stuff on your buttons, but then the values the user input will not be on your beans (because validation didn't take place yet, and what if user entered "adfg" in a date field?). You will get them as strings directly from the UIInput control with getSubmittedValue / getValue (check which works in your context)(for that you need binding the html control to a controller field). Then, if you try to populate the other fields of the form by setting values on the bean, you will also need to force the controls to refresh.
For this, you need this static method in a utility class
Code:
public static final void forceRefresh(UIInput control) {
 		control.setSubmittedValue(null);
 		control.setValue(null);
 		control.setLocalValueSet(false);
 	}

And then call it for each bound control.

It's dirty, but I think it's the only "proper" way to achieve your goal.
If it sounds too difficult ... get that book and start reading :)

Good luck!

Eduard
 
Profile for edykory -> Messages posted by edykory [319] Go to Page: Previous  1, 2, 3 , 4, 5 ... 20, 21, 22 Next 
Go to:   
Powered by JForum 2.1.7ice © JForum Team