Some improvements I've just added surrounding the menu-item widgets:

  • Widget classes can now be defined as inner-classes of resources.
  • New Tooltip template class has been added that allows you to programmatically specify a tooltip.  It can be mixed with arbitrary HTML5 beans.

I've added a new menu-item example to the Pet Store resource complete with tooltips:

 

The menu item is defined as an inner class on the PetStoreResource class and gets added via a new addPet() method...

/**
 * Sample REST resource that renders summary and detail views of the same bean.
 */
@RestResource(
   ...
)
public class PetStoreResource extends ResourceJena {

	@RestMethod(name="POST", path="/")
	public Redirect addPet(@Body Pet pet) throws Exception {
		this.petDB.put(pet.id, pet);
		return new Redirect("servlet:/");
	}
	
	/**
	 * Renders the "ADD" menu item.
	 */
	public class AddPet extends MenuItemWidget {

		@Override
		public String getLabel(RestRequest req) throws Exception {
			return "add";
		}

		@Override
		public Object getContent(RestRequest req) throws Exception {
			return div(
				form().id("form").action("servlet:/").method("POST").children(
					table(
						tr(
							th("ID:"),
							td(input().name("id").type("number").value(getNextAvailableId())),
							td(new Tooltip("(?)", "A unique identifer for the pet.", br(), "Must not conflict with existing IDs"))
						),
						tr(
							th("Name:"),
							td(input().name("name").type("text")),
							td(new Tooltip("(?)", "The name of the pet.", br(), "e.g. 'Fluffy'")) 
						),
						tr(
							th("Kind:"),
							td(
								select().name("kind").children(
									option("CAT"), option("DOG"), option("BIRD"), option("FISH"), option("MOUSE"), option("RABBIT"), option("SNAKE")
								)
							),
							td(new Tooltip("(?)", "The kind of animal.")) 
						),
						tr(
							th("Breed:"),
							td(input().name("breed").type("text")),
							td(new Tooltip("(?)", "The breed of animal.", br(), "Can be any arbitrary text")) 
						),
						tr(
							th("Gets along with:"),
							td(input().name("getsAlongWith").type("text")),
							td(new Tooltip("(?)", "A comma-delimited list of other animal types that this animal gets along with.")) 
						),
						tr(
							th("Price:"),
							td(input().name("price").type("number").placeholder("1.0").step("0.01").min(1).max(100)),
							td(new Tooltip("(?)", "The price to charge for this pet.")) 
						),
						tr(
							th("Birthdate:"),
							td(input().name("birthDate").type("date")),
							td(new Tooltip("(?)", "The pets birthday.")) 
						),
						tr(
							td().colspan(2).style("text-align:right").children(
								button("reset", "Reset"),
								button("button","Cancel").onclick("window.location.href='/'"),
								button("submit", "Submit")
							)
						)
					).style("white-space:nowrap")
				)
			);
		}
	}
	
	// Poormans method for finding an available ID.
	private int getNextAvailableId() {
		int i = 100;
		for (Integer k : petDB.keySet())
			i = Math.max(i, k);
		return i+1;
	}
}

 

The Tooltip class is a simple POJO with a swap method that wraps the contents in a Div tag....

public class Tooltip {
	private final String display;
	private final List<Object> content;

   /**
    * Constructor.
    *
    * @param display
    * 	The normal display text.
    * 	This is what gets rendered normally.
    * @param content
    * 	The hover contents.
    * 	Typically a list of strings, but can also include any HTML5 beans as well.
    */
   public Tooltip(String display, Object...content) {
   	this.display = display;
   	this.content = new ArrayList<Object>(Arrays.asList(content));
   }

   /**
    * The swap method.
    *
    * <p>
    * Converts this bean into a div tag with contents.
    *
    * @param session The bean session.
    * @return The swapped contents of this bean.
    */
   public Div swap(BeanSession session) {
      return div(
      	small(display),
      	span()._class("tooltiptext").children(content)
      )._class("tooltip");
   }
}
  • No labels