75473

Best way to “switch” bean on selection in JSF

Question:

I have a bean "Player" When I select a value in the selectOneMenu I would like to "switch" to the bean that's matching in the database.

I have the beans sent back to the select one menu in

public List<Player> getAllPlayers() { }

Updated the dropdown to this.

<pre class="lang-xhtml prettyprint-override"><h:selectOneMenu value="#{servicePlayer.myPlayer.combinedName}" converter="playerConverter" id="playerList"> <f:selectItems value="#{servicePlayer.allPlayers}" var="player" itemLabel="#{player.combinedName}" itemValue="#{player.id}" /> </h:selectOneMenu>

But I still can't get it to send the ID to the converter. It will send in the firstName from the player.

@FacesConverter(value = "playerConverter") public class PlayerConverter implements Converter { @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { if (value == null) { return null; } long idValue; try { idValue = Long.parseLong(value); } catch (NumberFormatException ex) { return null; } ServicePlayer servicePlayer = context.getApplication() .evaluateExpressionGet(context, "#{servicePlayer}", ServicePlayer.class); Player player = servicePlayer.getPlayerByID(idValue); return player; } @Override public String getAsString(FacesContext arg0, UIComponent arg1, Object value) { String string = null; if (value instanceof Player) { string = ((Player) value).getFirstName(); } return string; } } public class ServicePlayer { private static final String PERSISTENCE_UNIT_NAME = "BowlingFacelets"; public static EntityManagerFactory factory; Player myPlayer; public Player getMyPlayer() { return myPlayer; } public void setMyPlayer(Player myPlayer) { this.myPlayer = myPlayer; } public List<Player> getAllPlayers() { if (factory == null) { factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); } EntityManager em = factory.createEntityManager(); //Order by the matchdate. //Query q = em.createQuery("select t from DBTest t"); Query q = em.createQuery("select t from Player t"); List<Player> players = q.getResultList(); for (Player aPlayer : players) { System.out.println(aPlayer); } System.out.println("Size: " + players.size()); em.close(); return players; } public Player getPlayerByID(long id) { if (factory == null) { factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); } EntityManager em = factory.createEntityManager(); //Query q = em.createQuery("select t from Player t where t.name = '" + playerName + "'"); //List<Player> players = q.getResultList(); Player currentPlayer = em.find(Player.class, id); return currentPlayer; } }

Answer1:

A JSF Converter does the job of converting an Object to the string value for the itemValue attribute and then recover that Object from the string value. For your case, the <strong>Object</strong> is the Player entity while the <strong>value</strong> is the String representation of its id (could be anything else, as long as you know it's <em>unique</em>).

Basically, using this converter:

@FacesConverter(value = "playerConverter") public class PlayerConverter implements Converter { @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { if (value == null) { return null; } long idValue; try { idValue = Long.parseLong(value); } catch (NumberFormatException ex) { return null; } ServicePlayer servicePlayer = context.getApplication() .evaluateExpressionGet(context, "#{servicePlayer}", ServicePlayer.class); Player player = servicePlayer.getPlayerByID(idValue); return player; } @Override public String getAsString(FacesContext arg0, UIComponent arg1, Object value) { String string = null; if (value instanceof Player) { string = ((Player) value).getId(); } return string; } }

Note <strong>I changed the name you're returning by the id</strong>. That way, being the player id 1, JSF knows the String value for that is "1". That's the value for the selection, which is obtained by the getAsString method.

When you <em>POST</em> the form, JSF has to recover the Player entity from the "1" value, so you use Converter's getAsObject to load it from the DB.

That way it would be enough to reference the object itself from the view to let jsf do the conversion:

<pre class="lang-xhtml prettyprint-override"><h:selectOneMenu value="#{servicePlayer.myPlayer.combinedName}" converter="playerConverter" id="playerList"> <f:selectItems value="#{servicePlayer.allPlayers}" var="player" itemLabel="#{player.combinedName}" itemValue="#{player}" /> </h:selectOneMenu>

Answer2:

I think you've misunderstood what the value attribute of the selectOneMenu refers to. It's use is like in all other input components the place to store the user input (or where to take an existing value from).

Check <a href="http://www.jsftoolbox.com/documentation/help/12-TagReference/core/f_selectItems.html" rel="nofollow">http://www.jsftoolbox.com/documentation/help/12-TagReference/core/f_selectItems.html</a>. You will need to set key and value pairs based on a 'var' attribute on the f:select items, else JSF has no real way of knowing what you want to do with the Player object.

So given that key/value pairs (key goes into whatever you sets as the value attribute and value is shown to the user) is in place, and if you for example use the player.id as the value, you can fetch a user based on that id.

Recommend

  • how to use the SharedPreferrence value in another activity in android app
  • Change value of in PartialView
  • Don't change the name on the listView
  • Hibernate lazy initialization - failed to lazily initialize a collection
  • How to call a constructor of a class with Activity as argument inside a Fragment?
  • Large Photo Version from contacts in android
  • Convert from DataFrame to JavaPairRDD
  • How to pass the selected dropdown value to a URL in MVC?
  • ZF2 Event before not_found_template
  • Task.IsCancelled doesn't work
  • Zend Framework 2, Module Redirect
  • Apache Lucene - Improving the results of Spell Checker
  • adjust iframe height based on the content
  • parsing numbers from a text file
  • Nodejs bluebird promise fails while processing image
  • How to handle empty space in url when downloading image from web?
  • Smack 4.1.0 android Roster not displaying
  • extjs4 catching the scroll event on panel
  • What's the syntax to inherit documentation from another indexer?
  • C++ Single function pointer for all template instances
  • What is the correct way to synchronize a shared, static object in Java?
  • How to copy styled text in JTextPane
  • Why does it draw lines in the wrong place?
  • How to get data from **Realm database** using **date object**?
  • close() was never explicitly called on database
  • How VBA declared Volatility works
  • Converting a WriteableBitmap image ToArray in UWP
  • print() is showing quotation marks in results
  • Content-Length header not returned from Pylons response
  • Play WS (2.2.1): post/put large request
  • Reading JSON from a file using C++ REST SDK (Casablanca)
  • How to access EntityManager inside Entity class in EJB3
  • Why value captured by reference in lambda is broken? [duplicate]
  • javascript inside java/jsp code
  • vba code to select only visible cells in specific column except heading
  • Is there any way to bind data to data.frame by some index?
  • Django query for large number of relationships
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • How can I use `wmic` in a Windows PE script?
  • How to push additional view controllers onto NavigationController but keep the TabBar?