| Author |
Message |
|
|
Ok, I do somewhat understand why the selectInputDate would alter the model without an explicit submit.
But why are other form values being submit as well without doing validation ?
For example:
I have two components, a selectInputDate wich has a value binding to 'person.birthDate' and a selectOneMenu wich has a value binding to 'person.birthLocation'. The selectOneMenu has the 'required' attribute being set to 'true'. so, whenever I submit the form without selecting a birthLocation from the selectOneMenu, I get a validation error.
Now, when I enter something in the date field and I jump out the field (without having selected a birthLocation in the selectOneMenu) two things happen:
- The value of the entered date is set in the model so person.setBirthDate is executed (ok for me)
- The value of the selectOneMenu is being set in the model, so person.setBirthLocation is executed, but with its value being "NULL" (which is NOT ok for me)
Now, in most situations this will not be a problem, since the form is not yet 'officially' submitted and no action has been executed on it. If I submit the form it will complain that I did not select a birthLocation in the selectOneMenu.
But there are cases where this could be a problem. To name a few:
- I could have a 'not null' check in the 'setBirthLocation' (since I never want it to be null)
- I have other components which depend on 'getBirthLocation'. For example, if I add an outputText component with a binding on 'person.birthLocation.city' , and I fill 'birthLocation' with a default value, then entering something in the datefield will suddenly make the default birthlocation dissapear (the value will simply disappear from the screen)
....
|
 |
|
|
This is in regard to a previous topic; http://www.icefaces.org/JForum/posts/list/8968.page
I have a form with two selectInputDate's. The first selectInputDate is a "from date" and the second selectInputDate is a "untill date". So, the "untill date" may never be, before the "from date".
So make this work, I have a (custom) validator which is placed on the first selectInputDate. As an attribute I pass the id of the second selectInputDate. So, when the form is submitted, the validator is fired and it willl obtain the values from selectInputDate 1 and selectInputDate 2 (by looking up the component using its id)
The problem is that ICEfaces will NOT trigger validation for these components upon FORM SUBMISSION. This is what happens:
- I Enter something 'wrong' in the first selectInputDate (from date)
- Select the other field
=> Due to partial submit, the validator of the first selectInputDate is fired and you get the message "date format not correct"
So far so good
- I enter '2000/01/01' in the second (untill date) selectInputDate
- I enter '2007/01/01' in the first (from date) selectInputDate
- I click out the first selectInputDate
=> Due to partial submit, the validator of the first selectInputDate is fired and you get the message "from date should be, before untill date'
So far so good
- I enter '2007/01/01' in the first (from date) selectInputDate
- I enter '2000/01/01' in the second (untill date) selectInputDate
- I click out the first selectInputDate
=> No validation fault happens, since the first entry in the first selectInputDate is ok (the second has not been filled in yet). The second selectInputDate has no validator set, so nothing gets validated at that time.
Now, when I submit the form, I would expet to get a validation fault since the validator of the first selectInputDate should be triggered. And, this will detect that the untill date is before the from date. But the validator is not triggered.
I know the validators have allready been triggered by partial submit, so when resending the form its somewhat normal they are not triggered again. But as in this example the validator impacts multiple fields. So they must be re-executed on form submission.
Is there a way to fix this ?
|
 |
|
|
philip.breau wrote:
Any partialSubmit will always post the whole form. On the first partialSubmit of the calendar, empty strings are being posted for the other fields. So what you're probably seeing is the value change from null to "". Try pre-setting your String properties to an empty String to avoid this unnecessary value change.
Philip
The problem is bigger then that; supose the user has allready entered some text in the textfields? In that case, entering something in the datepicker will automatically submit these values. So, the model gets updated with all the form values without doing a explicit submit.
This is very anoying if you have a 'cancel' or 'clear' button.
This means you can never trust the model in case there is a datepicker on the form, you must then keep 2 versions of the model. 1 'temporary' version which is discarded if the user hits 'cancel' or 'clear' and one version which is the 'actual' model. When you hit 'submit' you replace the actual model with the temporary. This gets dirty very fast.
I would propose that icefaces does not update the model without an explicit submit using a control component....
|
 |
|
|
I have one form with two components on one page:
Code:
<ice:form id="searchForm">
<ice:selectInputDate value="#{testAction.day}" renderAsPopup="true" />
<ice:inputText value="#{testAction.textField}"/>
<ice:inputText value="#{testAction.textFieldTwo}"/>
<ice:commandButton action="#{testAction.submit}"/>
</ice:form>
Now, when I type a date (I don't even use the button next to the selectInputDate) both the values of the inputText's as the selectInputDate are being submit (ok this far) but it ALSO triggers a model update.
So the 'setDate, setTextField and setTextFieldTwo' are being executed the moment I lose focus on the selectInputDate field.
This is very undesired in many case.
Is there a way this behavior can be disabled? It only seems to be this way when a selectInputDate is in the form. A form with only inputText's does not seem to have this problem....
|
 |
|
|
In the mean time; you could also use tomcat 6.0.14 which does not have this problem. I compared sources with 6.0.16 and the EL class responsible for the coercing does not exist in .14. So probably they use some other implementation which does not cause this problem.
But you are probably right; it should be fixed in the JSF RI impl.
|
 |
|
|
|
It seems to be a problem in our custom renderer. With the original ice:selectOneMenu there is no problem, so this can be ignored.
|
 |
|
|
I have two components on a page. Both of them are selectOneMenu. The first selectOneMenu is displaying car brands, the second selectOneMenu is empty; it will display the car models once you have choosen a car brand.
Now, I allready enabled partialsubmit and bound a valuechangeListener to the first selectOneMenu. The model is updated (with the selected car) and the valueChangeListener is fired. However, the view doesn't seem to be rerendering. The second selectOneMenu remains empty.
Do I need to do something special so that the second selectOneMenu will rerender itselfves when the value of the first selectOneMenu has changed ?
|
 |
|
|
Hmm, on glasfish I do not have this problem, its only on tomcat. After some close inspection I saw that the class "org.apache.el.lang.ELSupport" is doing this;
Code:
public final static Number coerceToNumber(final Object obj, final Class type)
if (obj == null || "".equals(obj)) {
return coerceToNumber(ZERO, type);
}
Whereas ZERO is defined as:
Code:
private final static Long ZERO = new Long(0L);
So, whenever the target type is an instance of Number it will yield to: 0.
I think this is an issue rather with tomcat then ICEfaces....
|
 |
|
|
I created a small test with one form in which I have an inputText and submit button:
Code:
<html>
<ice:form>
<ice:messages/>
<ice:inputText value="#{backingBean.test}"/>
<ice:commandButton value="test">Test</ice:commandButton>
</ice:form>
</html>
After submitting the form while leaving the inputText empty, the value in the inputBox becomes '0'.
The 'IntegerConverter' is working as expected, its returning 'null', but somewhere along the line the 'null' value gets replaced by a Integer with value 0 (when the 'setTest(Integer i)' is executed on the backingbean it is actually getting an Integer with value 0.
How do I solve this ? I want that the inputTest remains empty if I did not enter a number....
|
 |
|
|
Consider the case when you supply two f:selectItem's to a selectOneMenu:
Code:
f:selectItem itemLabel='Volkswagen' itemValue='#{list[0]}'
f:selectItem itemLabel='Mercedes' itemValue='#{list[1]}'
The itemValue's ('Car' objects in this case) are stored somewhere in the component. The component uses the itemLabel text to fill the items in the HTML select, and the toString (or converted value if I'm not mistaking) of the 'itemValue' as the 'value' attribute of the HTML option within the HTML select.
Now, on submit, why can't we use the value of the selected option to correlate it to the original object from which the value was generated in the first place ? For example; it could store the string representation of the 'itemValue' and the original object of 'itemValue' in a map.
So, when I would select 'Volkswagen' I want that the same object as the first element on the list is being set on my backing action.
A converter is (IMHO) completely foolish. Why do you want to convert something to a String (which isn't even displayed, since the string representation of the itemValue is just used in the option 'value') and then , upon selection, convert the same string back to (the same) object when you allready have the object ?
For a large application you would endup with several converters, which can be error-prone and add totally no value.
But maybe I'm missing something here, feel free to point this out :)
|
 |
|
|
Ok, we did a workaround by using an html iframe icm a javascript onclick event which is triggering the download.
The value of the outputLink becomes '#'. The javascript can be put in the 'onclick' attribute of the outputLink, or extend (like we did) the original component adding this behavior to the renderer and an additional attrbiute to the component ('targetUrl' for example)
This way the components on the page remain working (the iframe is simulating a new window, but you don't see it) and a proper 'save as...' dialog is triggered (only tested on IE).
|
 |
|
|
hildo wrote:
When a page is encoded, objects are converted to strings. When the page is decoded, strings are converted to objects. This happens all the time.
Where I've used this successfully, the itemValue had been ordinal values, and the labels Strings. To react when it's been changed, I get the value from the ValueChangeEvent that's passed to the event handler. Something like this.
Code:
public void runSearchValueChanged(ValueChangeEvent event) {
Object o = ((UISelectOne) event.getComponent()).getValue();
if (o != null) {
Long searchKey = Long.valueOf((String) o);
If you look at the HTML that's rendered, it's not going to pass the full object (#{someValue}) down to the browser. It's got the String representation of that. HTML wouldn't know how to store the full object. You have to be able to convert the String itemValue to whatever it is. Typically, the itemValue is a unique key that can be used to load an object. You're better off storing the key of the custom object in the itemValue. And, it's usually a good idea of define converters for the custom objects.
Hope this helps
Yes, towards the view the values are indeed converted to String otherwise they would not be rendered in HTML. But thats not what I'm trying to say.
When the component contacts the model, it should use the original object value and not the string representation. The string representation might be used as a key to find the original value associated with it.
Ex. I haven an object "PersonName" which is rendered in the selectOneMenu. On the view I would endup with a toString representation of the object ex "My Name". When I submit the form its the original value associated with that key which is set on the model and not the toString value itself.
|
 |
|
|
I created an icefaces popup in which I display an ice:outputLink and two commandButtons with value "yes" and "no". The idea is that the user clicks "yes" when the file download was successfull (after clicking the download link and saving the file) . In that case the user is returned to a certain page and some processing occurs. If the user clicks "no" the popup is simply closed without further processing.
To do this I created a custom servlet (since hijacking the response inside the backingbean is discouraged with icefaces).
The servlet does this:
Code:
response.setContentType("aplication/pdf");
response.setHeader("Content-Disposition", "inline;filename=\"test.pdf\"");
response.setHeader("Cache-Control", "private"); //HTTP 1.1
response.setHeader("Pragma", "private"); //HTTP 1.0
response.setDateHeader("Expires", 0); //prevents caching at the proxy server
outputStream.write(b);
outputStream.flush();
outputStream.close();
Everything goes as expected, a download 'save as' popup appears after clicking the link and the file can be downloaded. However, the yes and no buttons do NOT work anymore ! (they keep working if the user right clicks and choses 'save as...' but there is no way to enforce this)
I tried about everything;
1. replace the ice:outputLink by a normal HTML anchor, but that doesn't help either. It seems that icefaces invalidates the page somehow.
2. Put the <ice:outputlink> on another page, not inside the popup: same problem; alle components invalidated
3. Put the ice:outputlink in another form : same problem all components invalidated
4. Use the unofficial download component from 'pbreau'; doesn't trigger a download dialog, so I cant use this.
5. I also tried other suggestions found on the forum to add a "target=blank" on the ice:outputLink. Doing this the buttons on the popup remain working, but now I get a new browser window that remains open and I don't want that.
The last point is however the closest thing I found thus far, just the fact that the browser remains open (even after triggering the download "save as...")
Can someone from icefaces please advice how a download must be done while having the "download save as..." dialog and keep all components on the page working after the download, this seems to be an issue for many of the users here. Thanks.
|
 |
|
|
|
Yes, there are various ways I can solve this, but they all 'submit'. When I click a row, the 'loading' bar underneeth IE appaers but nothing happens so it appaers as something is wrong (but there isn't, its the backing bean which decides that no action needs to be taken)
|
 |
|
|
|
Yes, there are various ways I can solve this, but they all 'submit'. When I click a row, the 'loading' bar underneeth IE appaers but nothing happens so it appaers as something is wrong (but there isn't, its the backing bean which decides that no action needs to be taken)
|
 |
|
|