Vaadin 7 Cookbook
上QQ阅读APP看书,第一时间看更新

Viewing details of items in ListSelect

In this recipe, we will show the use of a ListSelect component. It's a list box that shows the selectable items in a vertical list. If the number of items exceeds the height of the component, a scrollbar is shown. We will use it for viewing details of contacts in a list as shown in the following screenshot. We'll create it as a custom component.

Our Contact viewer is based on the HorizontalSplitPanel that contains two components and lays them horizontally. On the left side, we will have list of full names and on the right side we will have details about the selected user. We will learn how to add items to the ListSelect component using the Container and how to work with the listener.

Viewing details of items in ListSelect

How to do it...

Carry out the following steps for viewing the details of items in the list:

  1. We create a Vaadin project with the main UI class called Demo.
    public class Demo extends UI {
  2. First, we need a bean called Contact. We create a simple bean with first name, last name, and e-mail. We also create a method that returns the full name. This name will be shown in the UI list. We add appropriate constructor and getter methods as follows:
    public class Contact {
    
      private String firstName;
      private String lastName;
      private String email;
    
    public Contact(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
      }
      
      public String getFullName() {
        return firstName + " " + lastName;
      }
      <insert getters and setter>  
      …  
    }
  3. Now we create our custom component called ContactViewer.
    public class ContactViewer extends CustomComponent {…}
  4. The constructor will have one parameter, BeanItemContainer<Contact> contacts. Through this parameter, we pass the container of contacts. In the constructor, we create the main horizontal split panel that has to be the final object because we will use it from the inner class ValueChangeListener. We use this panel as a compositions root in our custom component.
    public ContactViewer(BeanItemContainer<Contact> contacts) {
    
      final HorizontalSplitPanel panel = 
                           new HorizontalSplitPanel();
      setCompositionRoot(panel);
      …
  5. Then we create our main component contactSelect that is an instance of the SelectList class. We stretch this component over the entire area by the setSizeFull() method and we set it to the immediate mode, which means that changes in this component are fired immediately. Item captions will be read from the property specified with the setItemCaptionPropertyId(Object propertyId) method. In our case, we use the fullName property that returns the first name and last name of Contact.
      final ListSelect contactSelect = new ListSelect();
      contactSelect.setSizeFull();
      contactSelect.setImmediate(true);
      contactSelect.setContainerDataSource(contacts);
      contactSelect.setItemCaptionPropertyId("fullName");
      …
  6. In the contactSelect object, we add a listener for changes in the selected item. After each change, we update the second component in the panel with the details of the selected contact. At the end of the constructor, we set the contactSelect object as a first component in the main split panel.
      contactSelect.addValueChangeListener(
        new ValueChangeListener() {
          @Override
          public void valueChange(ValueChangeEvent event) {
            Contact contact = 
            (Contact) event.getProperty().getValue(); panel.setSecondComponent(createInfoLabel(contact));
            contactSelect.focus();
          }
        });
      panel.setFirstComponent(contactSelect);
    }
  7. Next, we add a method that creates our info label for viewing details of the selected contact. It's a simple Label with safe HTML code. The SafeHtml class has been already described in the Creating an adjustable layout using split panels recipe in Chapter 2, Layouts.
    private Label createInfoLabel(Contact contact) {
      String info = "";
      if (contact != null) {
        info = "<ul>";
        info += String.format("<li><b>First name: </b> %s </li>", 
        contact.getFirstName());
        info += String.format("<li><b>Last name: </b> %s </li>",
        contact.getLastName());
        info += String.format("<li><b>Email: </b> %s </li>",
        contact.getEmail());
        info += "</ul>";
      }
      SafeHtml safeHtml = SafeHtmlUtils.fromSafeConstant(info);
      return new Label(safeHtml.asString(), ContentMode.HTML);
      }
  8. Now we can use our ContactViewer component in the main UI class Demo. Here we insert a method that creates a contact container with some dummy data.
    public class Demo extends UI {
    
      @Override
      protected void init(VaadinRequest request) {
        ContactViewer contactViewer = 
                new ContactViewer(createContactContainer());
        setContent(contactViewer);
      }
    
      private BeanItemContainer<Contact> createContactContainer(){
        BeanItemContainer<Contact> contacts = 
              w BeanItemContainer<>(Contact.class);
        contacts.addItem(
          new Contact("Tom", "Smith", "tom.smith@gmail.com"));
        contacts.addItem(
          new Contact("Bob", "Taylor", "bob.taylor@yahoo.com"));
        contacts.addItem(
          new Contact("Jane", "White", "jane.white@gmail.com"));
        contacts.addItem(
          new Contact("Suzan", "Lee", "suzan.lee@aol.com"));
        return contacts;
      }
    
    }

The application is ready now. We can run the server and show it in the web browser.

How it works...

The ListSelect component used in this recipe is a list box that shows selected and selectable items in a vertical list. A user can select an item by using the mouse or by using the up and down arrow keys. After selecting an item, ValueChangeEvent is caught in the ValueChangeListener. In this event, an info label with detailed information about the contact is created and added to the right side of the split panel.

There's more...

Vaadin gives many alternatives for selecting one or more items from a list: using drop-down and regular lists, radio button and checkbox groups, tables, trees, and so on. The core library includes the following selection components, all based on the AbstractSelect class. Here are some of them with shortened generated HTML code:

  • ComboBox: It is a text field with a drop-down list. Users can filter the displayed items and add new ones. It's very similar to the Select component that is deprecated in Vaadin 7. In HTML, it's represented by the element <input>. Lists of items are added as a small pop up created by divs and table elements.
    <input type="text">
    <div class="popupContent">
      <table>
        <tr>
          <td class="gwt-MenuItem"><span>first item</span></td>
        </tr>
      </table>
    </div>
  • NativeSelect: It is a good alternative to ComboBox if we want to use a simple select component without extra generated HTML code. This component is without features such as filtering and adding new items. In HTML, it's a <select> element with a default size of 1 item.
    <select size="1">
      <option value="1">first item</option>
      <option value="2">second item</option>
    </select>
  • ListSelect: It is a vertical list box with items. Users can use single or multiple selection modes. In HTML, it is represented by the element <select> with a default size of 10 items.
    <select size="10">
      <option value="1">first item</option>
      <option value="2">second item</option>
    </select>
  • OptionGroup: It is one class for two components known as radio button and checkbox. If we set it as a multi-select setMultiSelect(true), it will be a checkbox component.
    <span>
      <input type="checkbox" id="gwt-uid-1">
      <label for="gwt-uid-1">first item</label>
    </span>

    If we set it as a single-select setMultiSelect(false), it will be a radio button. It's the default value.

    <span>
      <input type="radio" id="gwt-uid-1">
      <label for="gwt-uid-1">first item</label>
    </span>

See also