javaserverfaces
  1. javaserverfaces
  2. JAVASERVERFACES-2163

Converter registered on one component in a panelGrid runs on 3 components in the panelGrid

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 2.1.1
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None

      Description

      The attached facelets file, bookcashier.html, registers a custom converter (CreditCardConverter.java, also attached) on a UIInputText component with the id "ccno". The f:converter tag is inside the f:inputText tag, and it also specifies the id in its for attribute.

      <h:inputText id="ccno"
      size="19"
      converter="#

      {cashier.creditCardConverter}"
      converterMessage="#{bundle.CreditMessage}"
      required="true"
      requiredMessage="#{bundle.ReqCreditCard}" >
      <f:converter for="ccno"
      binding="#{cashier.creditCardConverter}

      "/>
      <f:validateRegex
      pattern="\d

      {16}

      |\d

      {4} \d{4}

      \d

      {4} \d{4}

      |\d

      {4}-\d{4}

      -\d

      {4}-\d{4}

      " />
      </h:inputText>

      However, the converter is run not only on the ccno component, but also on the inputText component with the id "name" as well as on the selectOneMenu component with the id "shippingOption". The logger output from the converter confirms this:

      INFO: Entering CreditCardConverter.getAsObject
      INFO: Converted value is mynamejones
      INFO: Entering CreditCardConverter.getAsObject
      INFO: Converted value is 1234123412341234
      INFO: Entering CreditCardConverter.getAsObject
      INFO: Converted value is 2

      The getAsObject method of the converter strips spaces from strings separated by spaces, or hyphens from strings separated by hyphens, and leaves other strings as is. This means that it strips spaces from names entered in the name field, which is an undesirable side effect (unless the name contains both a space and a hyphen, in which case the method leaves it alone).

      This seems to be a bug in the Facelets implementation?

      The full application is available in the Java EE Tutorial project at http://java.net/projects/javaeetutorial/sources/svn/show. It is in trunk/examples/web/dukes-bookstore. You can check out the examples.

      1. bookcashier.xhtml
        5 kB
        Kim Haase
      2. bookcashier.xhtml
        5 kB
        Kim Haase
      3. CashierBean.java
        3 kB
        Kim Haase
      4. CreditCardConverter.java
        4 kB
        Kim Haase
      5. CreditCardConverter.java
        4 kB
        Kim Haase

        Activity

        Hide
        Ian Evans added a comment -

        Steps to reproduce using the attached project.

        1. Open in NetBeans (configured with GlassFish) and select Run.
        2. Select the United States on the map to set the locale.
        3. Click Add to Cart.
        4. Click Buy Your Books.
        5. Enter "Firstname Lastname" in the Name field, "1111 1111 1111 1111" in the Credit Card Number field, and click Submit Information.
        6. Note that the name is now "FirstnameLastname".

        The server.log file also shows that the converter was called:
        INFO: Entering CreditCardConverter.getAsObject
        INFO: Converted value is FirstnameLastname
        INFO: Entering CreditCardConverter.getAsObject
        INFO: Converted value is 2
        INFO: Clearing cart.

        Show
        Ian Evans added a comment - Steps to reproduce using the attached project. 1. Open in NetBeans (configured with GlassFish) and select Run. 2. Select the United States on the map to set the locale. 3. Click Add to Cart. 4. Click Buy Your Books. 5. Enter "Firstname Lastname" in the Name field, "1111 1111 1111 1111" in the Credit Card Number field, and click Submit Information. 6. Note that the name is now "FirstnameLastname". The server.log file also shows that the converter was called: INFO: Entering CreditCardConverter.getAsObject INFO: Converted value is FirstnameLastname INFO: Entering CreditCardConverter.getAsObject INFO: Converted value is 2 INFO: Clearing cart.
        Hide
        Kim Haase added a comment -

        Back in EE 5, when our example actually worked, the JSP file had the following:

        <h:inputText id="ccno"
        size="19"
        converterMessage="#

        {customMessages.CreditMessage}

        "
        required="true"
        requiredMessage="#

        {customMessages.ReqMessage}

        " >
        <f:converter binding="#

        {cashier.creditCard}

        "/>
        <bookstore:formatValidator
        formatPatterns="9999999999999999|9999 9999 9999 9999|9999-9999-9999-9999"/>
        </h:inputText>

        The converter was bound to the cashier backing bean, which instantiated it. It seems that the binding attribute applies only to managed beans. I tried supplying the converterId attribute that the TagException complained about –

        <f:converter converterId="ccno"
        binding="#

        {dukesbookstore.converters.creditCardConverter}"/>

        (I also specified "ccno" as the value for the @FacesConverter annotation on the converter class: @FacesConverter("ccno").)

        But when I do this, I get a different runtime error:

        javax.el.PropertyNotFoundException: /bookcashier.xhtml @64,94 binding="#{dukesbookstore.converters.creditCardConverter}

        ": Target Unreachable, identifier 'dukesbookstore' resolved to null

        I see that when we specify classes other than managed beans in our Facelets pages, we always seem to do so with the type attribute – for example,

        <f:actionListener type="dukesbookstore.listeners.LinkLocaleChangeListener" />

        But the f:converter tag does not have a type attribute, only a binding attribute.

        Show
        Kim Haase added a comment - Back in EE 5, when our example actually worked, the JSP file had the following: <h:inputText id="ccno" size="19" converterMessage="# {customMessages.CreditMessage} " required="true" requiredMessage="# {customMessages.ReqMessage} " > <f:converter binding="# {cashier.creditCard} "/> <bookstore:formatValidator formatPatterns="9999999999999999|9999 9999 9999 9999|9999-9999-9999-9999"/> </h:inputText> The converter was bound to the cashier backing bean, which instantiated it. It seems that the binding attribute applies only to managed beans. I tried supplying the converterId attribute that the TagException complained about – <f:converter converterId="ccno" binding="# {dukesbookstore.converters.creditCardConverter}"/> (I also specified "ccno" as the value for the @FacesConverter annotation on the converter class: @FacesConverter("ccno").) But when I do this, I get a different runtime error: javax.el.PropertyNotFoundException: /bookcashier.xhtml @64,94 binding="#{dukesbookstore.converters.creditCardConverter} ": Target Unreachable, identifier 'dukesbookstore' resolved to null I see that when we specify classes other than managed beans in our Facelets pages, we always seem to do so with the type attribute – for example, <f:actionListener type="dukesbookstore.listeners.LinkLocaleChangeListener" /> But the f:converter tag does not have a type attribute, only a binding attribute.
        Hide
        Kim Haase added a comment -

        So then I thought, maybe you need either the converterId or the binding attribute, but not both? So I did

        <f:converter converterId="ccno"/>

        This seems to work! It ties the converter to the component to which it is attached, and does not operate on any of the others on the page.

        INFO: Entering CreditCardConverter.getAsString
        INFO: Entering CreditCardConverter.getAsObject
        INFO: Converted value is 1234123412341234
        INFO: Clearing cart.

        I will close the issue as User Confusion or whatever. And we'll document this ...

        Show
        Kim Haase added a comment - So then I thought, maybe you need either the converterId or the binding attribute, but not both? So I did <f:converter converterId="ccno"/> This seems to work! It ties the converter to the component to which it is attached, and does not operate on any of the others on the page. INFO: Entering CreditCardConverter.getAsString INFO: Entering CreditCardConverter.getAsObject INFO: Converted value is 1234123412341234 INFO: Clearing cart. I will close the issue as User Confusion or whatever. And we'll document this ...
        Hide
        Kim Haase added a comment -

        Actually, I can't close it. You can close it, Roger.

        Show
        Kim Haase added a comment - Actually, I can't close it. You can close it, Roger.
        Hide
        rogerk added a comment -

        Per latest comments from reporter.

        Show
        rogerk added a comment - Per latest comments from reporter.

          People

          • Assignee:
            rogerk
            Reporter:
            Kim Haase
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: