12 Replies Latest reply on Apr 30, 2009 2:48 PM by daxxy

    convert input value to a different search value

    daxxy
      The overview:

      My goal is to take the name of a state as input, ie "Alaska" and find an "office view" associated with the state.My office view has a "state" field populated with 2-letter abbreviation.  The basic question is how do I take a full state name as input and query using only the 2-letter abbreviation. I have access to a supporting table that translates state names to 2-letter abbreviations.

           step 1: input = Alaska
           step 2: convert Alaska to AK
           step 3: Run query like this: "select officeview from OfficeView where officeview.state=AK"

           I can't figure out how to get from Alaska to AK.
           
      Some details:

      I have a table: states with 2 columns, abbreviation and fullname. It contains names of states and abbreviations.

      e.g.

      Alaska AK
      Alabama AL
      Michigan MI

      In my view, basicsearch.xhtml, I have a combobox containing a list of state names:
      The combobox is populated via a query for state names from StateList ("select fullName from States").

      Here is the code for the combobox

      <rich:comboBox selectFirstOnUpdate="false"
                   defaultLabel="Start typing a state name..."
                   directInputSuggestions="true"
                   enableManualInput="true" 
                   value="#{officeViewList.officeView.state}"  << not sure what to put for value
                   suggestionValues="#{stateList.resultList}"/>
                   
      The StateList is the action bean for a States entity which is backed by a little supporting table that translates full state names to abbreviations, ie.

      AK Alaska
      AL Alabama
      MI Michigan
      etc.

      The officeView entity has a "state" property which contains the 2-letter abbreviation.

      When I input the value of resultList, it is a fullName.  But I want the query returned by OfficeViewList to use the 2-letter abbreviation instead of the full name?

      In other words, how do I submit a different value than what I displayed in "suggestionValues".

      I hope this makes sense...

      TDR
        • 1. Re: convert input value to a different search value
          ztiringer

          I would suggest that you use


          <h:selectOneMenu id="stateMenu" value="#{officeViewList.officeView.state}">
                          <s:selectItems var="_states" value="#{stateList.resultList}" label="#{_states.fullName}"
                                         noSelectionLabel="-- Select one --"/>
                          <s:convertEntity/>
                      </h:selectOneMenu>



          So in label you specify the value to be displayed, and in value of the menu you specify the binding for the value to be returned.

          • 2. Re: convert input value to a different search value
            ztiringer

            And I guess you have to change your query so that not only fullName is selected, but the whole entity, to something like:



            select states from States states


            • 3. Re: convert input value to a different search value
              pgmjsd

              Also, why convert as a separate step at all?


              If you have the translation table, and it's mapped then you can just join.

              • 4. Re: convert input value to a different search value
                daxxy

                The first solution seems feasible.  I will certainly try it.  It's the type of solution I had in mind.


                The last solution, regarding just join -- I am struggling to understand all the parts of seam and how they fit together.  Where would the join occur and when?  On my select of officeView -- it's already joined with another object devices (each office has a list of devices) and I was afraid another join with the translation table would have too large an impact on performance.


                Thanks,
                TDR

                • 5. Re: convert input value to a different search value
                  daxxy
                  After doing a little reading, I'm pretty sure it's convertEntity I want. 

                  Here is the current code:

                  <h:selectOneMenu value="#{officeViewList.officeView.state}" >
                    <s:selectItems value="#{statesList.resultList}" var="_states"
                                   label="#{_states.fullName}"
                                   noSelectionLabel="-- Select one --"/>
                      <s:convertEntity />
                  </h:selectOneMenu>

                  This gives the drop-down menu I want.  I think convertEntity is going to take my input "Pennsylvania", convert it to "PA", and assign it to #{officeViewList.officeView.state}, but I still don't get how that happens. Obviously convertEntity doesn't magically know I want to convert "fullName" to "abbreviation" so how do I tell it that?

                  I'm on the right track, but if anyone can explain this further it would be appreciated.

                  TDR
                  • 6. Re: convert input value to a different search value
                    pgmjsd

                    If done properly this should not have any performance impact compared to the first idea because what you lose in the extra join you gain because there will be only one query.   (BTW, I am a big fan of keeping things simple and not doing any optimization without measuring performance impacts first).


                    Since I don't know your object model, mappings, and the original query I can't say what it would be exactly.   Here is an example:



                    • Office is an entity with an Address

                    • Address refers to a State (ManyToOne)

                    • State has a shortCode attribute (unique, maybe also primary key) and a full name.



                    select o from Office o where o.address.state.shortCode = :param or o.address.state.fullName = :param



                    Hibernate will make the implied join(s) for you, and you can change the fetch attributes to bring in the other objects to match what you are going to use on the page without changing the query.


                    • 7. Re: convert input value to a different search value
                      pgmjsd

                      Tanya Ruttenberg wrote on Apr 29, 2009 16:28:


                      This gives the drop-down menu I want.  I think convertEntity is going to take my input Pennsylvania, convert it to PA, and assign it to

                      1. {officeViewList.officeView.state}, but I still don't get how that happens. Obviously convertEntity doesn't magically know I want to convert fullName to abbreviation so how do I tell it that?



                      I'm on the right track, but if anyone can explain this further it would be appreciated.

                      TDR


                      Take a look at the HTML that s:selectItems generates.  The HTML option elements will have the value attribute set to the ID property of the entity.   The actual text the user sees is whatever EL expression you have there.   The form actually submits the entity ID, not the text, and that is what is passed to s:convertEntity.   All s:convertEntity needs to do is find the entity using it's ID much like you would if you were doing entityManager.find().


                      • 8. Re: convert input value to a different search value
                        daxxy
                        I'm almost there!

                        Here is the generated HTML:

                        <select name="j_id29:j_id49" size="1">     <option value="org.jboss.seam.ui.NoSelectionConverter.noSelectionValue">-- Select one --</option>
                             <option value="0">Alabama</option>
                             <option value="1">Alaska</option>
                             <option value="2">American Samoa</option>
                             <option value="3">Arizona</option>

                             <option value="4">Arkansas</option>
                             <option value="5">California</option>
                             <option value="6">Canada</option>
                        </select>

                        The shortForm is in fact the primary key of the table. It looks like this in my entity bean:

                        @Entity
                        @Table(name = "states", catalog = "ondtdr")
                        public class States implements java.io.Serializable {

                             private String abbreviation;
                             private String fullName;
                             
                             @Id
                             @GeneratedValue(strategy = IDENTITY)
                             @Column(name = "abbreviation", unique = true,
                                      nullable = true)
                             public String getAbbreviation() {
                                  return this.abbreviation;
                             }


                             public void setAbbreviation(String abbreviation) {
                                  this.abbreviation = abbreviation;
                             }

                             @Column(name = "full_name", length = 50)
                             @Length(max = 50)
                             public String getFullName() {
                                  return this.fullName;
                             }

                             public void setFullName(String fullName) {
                                  this.fullName = fullName;
                             }

                        }

                        You are saying that convertEntity should take the number "1" or "2" or whatever and convert it to the corresponding value of "abbreviation" ?  It's not doing it.

                        It seems the integer is trying to get bound to my input value #{officeViewList.officeView.state} because I am getting an IllegalArgumentException error.

                        I am missing something regarding the use of convertEntity.

                        (I'm going to try the other solution with the simple "join" once I get this one working)

                        TDR
                        • 9. Re: convert input value to a different search value
                          ztiringer

                          It's better if you create a private State with public accessors in officeViewList and bind the value to that and refer that in the restrictions (assuming that your entity is called officeView):


                          "officeView.state = #{officeViewList.state}"




                          In EJBQL do:


                          select officeView from OfficeView officeView join officeView.state state


                          • 10. Re: convert input value to a different search value
                            daxxy

                            I ended up using this. It was WAY simple.


                            http://in.relation.to/Bloggers/SselectItemsCustomisingTheValue


                            When my brain is not so tired I will try the simpler solution, ie the join method.

                            • 11. Re: convert input value to a different search value
                              pgmjsd

                              Tanya Ruttenberg wrote on Apr 29, 2009 22:10:


                              I ended up using this. It was WAY simple.

                              http://in.relation.to/Bloggers/SselectItemsCustomisingTheValue

                              When my brain is not so tired I will try the simpler solution, ie the join method.


                              Definitely simpler.  Previously, I thought you wanted to use a 'combo box' where the user can enter text as well as select from a list.  In that case you would need to do some kind of query.

                              • 12. Re: convert input value to a different search value
                                daxxy

                                I admit to being somewhat enamored of the idea of using richfaces.  But after staring at this for hours on end and still not really getting it, I decided to go the simple route.


                                I may come back to it at a future date.


                                Thank you to everyone who responded!


                                TDR