weixin_39899776
weixin_39899776
2020-12-02 05:03

b:selectOneMenu null itemValue

consider the following h:selectOneMenu code snippet:


<selectonemenu value="#{myBean.value}">
    <selectitem itemvalue="#{null}" itemlabel="Not selected"></selectitem>
    <selectitem itemvalue="choice1" itemlabel="choice1"></selectitem>
    <selectitem itemvalue="choice2" itemlabel="choice2"></selectitem>
</selectonemenu>

when Not selected is selected then myBean.value equals null


<selectonemenu label="Nice formatting" value="#{myBean.value}">
    <selectitem itemvalue="#{null}" itemlabel="Not selected"></selectitem>
    <selectitem itemvalue="choice1" itemlabel="choice1"></selectitem>
    <selectitem itemvalue="choice2" itemlabel="choice2"></selectitem>
</selectonemenu>

whereas with b:selectOneMenu when Not selected is selected then myBean.value equals Not selected

该提问来源于开源项目:TheCoder4eu/BootsFaces-OSP

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

8条回答

  • weixin_39949607 weixin_39949607 5月前

    I am not sure this is the correct way to do. Selectonemenu does not support null value. If it is empty then the bean has to convert as null.

    点赞 评论 复制链接分享
  • weixin_39768695 weixin_39768695 5月前

    It was a deliberate choice to use the label if the value is missing, but probably it wasn't a wise choice. I've removed it because we've never documented the feature. Still, it's a breaking change.

    Passing null values to the bean is difficult. During my test the null value has always been replaced by an empty string. To avoid that, you probably have to set the parameter javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL to true.

    Can you review and test my changes, please?

    点赞 评论 复制链接分享
  • weixin_39949607 weixin_39949607 5月前

    Null is not an value. It means empty. JSF treats everything as string and the converters to the rest of the work to convert it to objects. There is no "null" object. This will fail always.

    点赞 评论 复制链接分享
  • weixin_39899776 weixin_39899776 5月前

    I have been passing nulls for a long time with (usually) no problem. But looking at this answer by it seems that is correct and that the preferred method is to pass an empty string. Not sure why null always worked for me before https://stackoverflow.com/questions/17052503/using-a-please-select-fselectitem-with-null-empty-value-inside-a-pselectonem?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

    点赞 评论 复制链接分享
  • weixin_39768695 weixin_39768695 5月前

    You are right... mostly. Have a look at Bauke's well-researched article.

    点赞 评论 复制链接分享
  • weixin_39768695 weixin_39768695 5月前

    I'll close this ticket. If anyone of your finds a bug in my bugfix, don't hesitate to re-open the ticket.

    点赞 评论 复制链接分享
  • weixin_39949607 weixin_39949607 5月前

    Don"t close it yet. You have to give an option as f:selectitems noSelectionOption="true", it means empty string and if required=true, it should not be submitted. JSF automatically converts empty as null, if I am correct. Please look at the Primefaces selectonemenu.

    点赞 评论 复制链接分享
  • weixin_39768695 weixin_39768695 5月前

    There are several references to noSelectionOption in our source code, so I assume we've already implemented it. For example, have a look at this one:

    java
    private SelectItemAndComponent determineSelectedItem(FacesContext context, SelectOneMenu menu, List<selectitemandcomponent> items, Converter converter) {
            Object submittedValue = menu.getSubmittedValue();
            Object selectedOption;
            if (submittedValue != null) {
                selectedOption = submittedValue;
            } else {
                selectedOption = menu.getValue();
            }
    
            for (int index = 0; index < items.size(); index++) {
                SelectItemAndComponent option = items.get(index);
    
    
                if (option.getSelectItem().isNoSelectionOption()) continue;
    
    
    
                Object itemValue = option.getSelectItem().getValue();
                String itemValueAsString = getOptionAsString(context, menu, itemValue, converter);
    
                Object optionValue;
                if (submittedValue != null) {
                    optionValue = itemValueAsString;
                } else {
                    optionValue = itemValue;
                }
    
                if (itemValue != null) {
                    if (isSelected(context, menu, selectedOption, optionValue, converter)) {
                        return option;
                    }
                } 
            }
            return null;
        }
    
    </selectitemandcomponent>
    点赞 评论 复制链接分享

相关推荐