How to create a picklist in JSF? Tried moving items using JS/jQuery, but submit errors with “Validation Error: Value is not valid”

后端 未结 1 455
無奈伤痛
無奈伤痛 2020-12-21 11:43

I am creating web application using JSF 2.0 where I am assigning users to view projects. For that I have two list. First list that have users who are not assigned that proje

相关标签:
1条回答
  • 2020-12-21 12:27

    To the point, your concrete problem is caused by the mistake that you filled listbox items using JavaScript/jQuery instead of JSF. This way JSF is never been made aware of the new items added by JavaScript. You need to fill the listbox items using JSF instead of JavaScript/jQuery.

    When you submit a form with an UISelectOne/UISelectMany component, then JSF will always compare the submitted value to the list of available items from <f:selectItem(s)>. If the submitted value is not contained in the list of available items, then you will get exactly this Validation Error: Value is not valid error. This is part of builtin safeguard against tampered/attacked requests. The client should not be able to submit a item which the server has not specified.

    Changing the available items in JavaScript/jQuery side does not automagically also change the available items in JSF <f:selectItems> side as well. You really need to change the available items in JSF side. You can easily use the JSF 2.x ajax powers for this. Here's a concrete kickoff example:

    <h:form>
        <h:panelGrid columns="3">
            <h:selectManyListbox id="left" value="#{bean.leftSelected}">
                <f:selectItems value="#{bean.leftAvailable}" />
                <f:ajax event="dblclick" render="left right" listener="#{bean.leftToRight}" />
            </h:selectManyListbox>
            <h:panelGroup>
                <h:commandButton value="left to right">
                    <f:ajax execute="left" render="left right" listener="#{bean.leftToRight}" />
                </h:commandButton>
                <br/>
                <h:commandButton value="right to left">
                    <f:ajax execute="right" render="left right" listener="#{bean.rightToLeft}" />
                </h:commandButton>
            </h:panelGroup>
            <h:selectManyListbox id="right" value="#{bean.rightSelected}">
                <f:selectItems value="#{bean.rightAvailable}" />
                <f:ajax event="dblclick" render="left right" listener="#{bean.rightToLeft}" />
            </h:selectManyListbox>
        </h:panelGrid>
    </h:form>
    

    with

    @ManagedBean
    @ViewScoped
    public class Bean {
    
        private List<String> leftSelected;
        private List<String> leftAvailable;
        private List<String> rightSelected;
        private List<String> rightAvailable;
    
        @PostConstruct
        public void init() {
            leftAvailable = new ArrayList<String>(Arrays.asList("one", "two", "three", "four", "five"));
            rightAvailable = new ArrayList<String>();
        }
    
        public void leftToRight() {
            leftAvailable.removeAll(leftSelected);
            rightAvailable.addAll(leftSelected);
            leftSelected = null;
        }
    
        public void rightToLeft() {
            rightAvailable.removeAll(rightSelected);
            leftAvailable.addAll(rightSelected);
            rightSelected = null;
        }
    
        // Add/generate getters+setters. Note: the "available" lists doesn't need setters.
    }
    

    That's all. No JS/jQuery mess necessary. When using custom non-string objects don't forget to provide a proper converter and equals() method.

    See also:

    • What is the need of JSF, when UI can be achieved from CSS, HTML, JavaScript, jQuery?
    • Jsf : Validation error value is not valid for SelectOneMenu
    • JSF Validation Error While Using Custom Converter
    0 讨论(0)
提交回复
热议问题