4 Replies Latest reply on Oct 12, 2010 11:11 AM by sheriffpony

    rich:pickList does not revert after failed validation

    sheriffpony

      Hi. I am using RichFaces 3.3.3 and JSF 2.0 and am having an issue with the rich:pickList facelet not re-rendering properly after validation fails.

       

      I am trying to limit the number of selections to no more than 4 entries. I have a custom validator class that is being called and validation is indeed failing.

       

      If I select one, two, three or four items from the source (left) list, they appear in the target list. If I select a fifth item, it appears in the target list, and the validation error message is displayed. However, the five items are still on the target (right) list. If I refresh the page, the original four items will be there. For some reason, using a4j:support to re-render the picklist does not do this.

       

      I am using a4j:support event="onlistchanged" to rerender the pickList. I have tried wrapping the component in a a4j:region and re-rendering that too, but it still shows 5 items.

       

      Here is my code:

       

      [JSF]

       

      <h:form>

          <rich:messages for="picklist" />

          <rich:pickList id="picklist"

                         value="#{multiPickListBean.targetList}"

                         validator="#{multiSelectValidator.validate}">

            <f:attribute name="maxSelections" value="4"/>

            <f:selectItems value="#{multiPickListBean.sourceList}" />

            <a4j:support event="onlistchanged" reRender="picklist"/>

          </rich:pickList>

        </h:form>

       

       

      [Java Lists Bean]

       

      public class MultiPickListBean {

        private List<SelectItem> sourceItemList = new ArrayList<SelectItem>();

        private List<SelectItem> targetItemList = new ArrayList<SelectItem>();

       

        public MultiPickListBean() {

          sourceItemList.add(new SelectItem("value1", "item1"));

          sourceItemList.add(new SelectItem("value2", "item2"));

          sourceItemList.add(new SelectItem("value3", "item3"));

          sourceItemList.add(new SelectItem("value4", "item4"));

          sourceItemList.add(new SelectItem("value5", "item5"));

          sourceItemList.add(new SelectItem("value6", "item6"));

        }

       

        public List<SelectItem> getSourceList() {

          return this.sourceItemList;

        }

       

        public List<SelectItem> getTargetList() {

          return this.targetItemList;

        }

       

        public void setTargetList(List <SelectItem> list) {

          this.targetItemList = list;

        }

      }

       

       

      [Java Validator]

       

      public class MultiSelectRangeValidator implements Validator {

        @Override

        public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {

          int maxSelections = Integer.parseInt((String) component.getAttributes().get("maxSelections"));

          if (((List<String>) value).size() > maxSelections) {

            FacesMessage message = new FacesMessage("Cannot exceed " + maxSelections + " selections.");

            throw new ValidatorException(message);

          }

        }

      }

       

       

      I have attached a screenshot of what it looks like. Is there some other way to make the picklist re-render itself after failing validation?

       

      Edit: I forgot to mention that this was working fine for me in 3.3.1.GA and JSF 1.2.

        • 1. Re: rich:pickList does not revert after failed validation
          ilya_shaikovsky

          validation message added and further lifecycle execution aborted except render responce. But the component itself - already has it applied. And there is nothing about pickList and reRender'ing in general. Just component - shows latest input.

           

          Check with simple inputTExt. Add length validator. Check that in case when validation failed (length more than defined) input still contains last entered value.

          • 2. Re: rich:pickList does not revert after failed validation
            sheriffpony

            inputText seems to work the same way. I entered "123", it validated. I entered "123456", it failed with the validation message and the box still contained "123456".

             

            Should it not revert to show the last valid input of "123"?

             

            In the first example, after the validation fails, the targetList contains the last valid input (item2, item3, item4, and item5 only, NOT item6), but the pickList shows 5 items (item2 - item6). If I refresh the page, it will revert to the last valid input.

            • 3. Re: rich:pickList does not revert after failed validation
              ilya_shaikovsky

              No IMO(and it's the same as JSF specification implementors) it not looks good from end-user point of view. You entered wrong information but getting error and in the same time looking to normal input,. Moreover - maybe your prev input contains just simple typing mistake and you could change it erasing one erroneous symbol.. But if you will implement as you want - the user will have to repeat typing to correct it.

               

              So I think that it's pretty fine that error message in sync with current state of any input.

              • 4. Re: rich:pickList does not revert after failed validation
                sheriffpony

                That makes more sense for inputText. But I would like for when the user selects a fifth item, for it to move back to the left after validation fails. Right now, if I refresh the page, I get the last valid input (not the wrong input). Is there any way to refresh the component without refreshing the entire page?

                 

                Also, why did this work differently in RichFaces 3.3.1?