Navigation and Events

Back

Loading concept...

🧭 Web User Interfaces: Navigation and Events in Jakarta EE

The Story of the Magic Mall

Imagine you’re in a gigantic magic mall. This mall has many rooms (pages), and you need to move between them. Sometimes you walk through doors by yourself, sometimes a friendly guide takes you, and sometimes magic happens when you touch things!

In Jakarta EE Faces, this is exactly how web pages work. Let’s explore!


🚪 Faces Navigation: The Doors of Your App

Think of Faces Navigation as all the doors in your magic mall. When you click a button, you go through a door to another room (page).

How It Works

Every web app needs a way to move from one page to another. Faces gives you three magical doors:

  1. Implicit Navigation → The automatic door
  2. Programmatic Navigation → The guide-controlled door
  3. Faces-config.xml Navigation → The map-planned door
graph TD A["User Clicks Button"] --> B{Which Navigation?} B --> C["Implicit Navigation"] B --> D["Programmatic Navigation"] B --> E["faces-config.xml"] C --> F["Auto-finds Page"] D --> G["Code Decides Page"] E --> H["Config File Decides"]

🔮 Implicit Navigation: The Smart Automatic Door

Analogy: Imagine a door that knows where you want to go just by hearing the room name!

What Is It?

Implicit Navigation is the easiest way to navigate. You just tell the button the page name, and Faces finds it automatically.

Simple Example

<h:commandButton
  value="Go to Welcome"
  action="welcome" />

What happens:

  • User clicks the button
  • Faces looks for welcome.xhtml
  • User goes to that page!

The Magic Rule

You Write Faces Looks For
"home" home.xhtml
"about" about.xhtml
"contact" contact.xhtml

No configuration needed! The name in action becomes the page name + .xhtml.

Real-World Example

<!-- login.xhtml -->
<h:form>
  <h:commandButton
    value="Login"
    action="dashboard" />
  <h:commandButton
    value="Register"
    action="register" />
</h:form>

After clicking “Login” → Goes to dashboard.xhtml After clicking “Register” → Goes to register.xhtml


🎮 Programmatic Navigation: The Smart Guide

Analogy: Instead of automatic doors, you have a smart guide (your Java code) who decides which room to take you to!

What Is It?

Sometimes you need to think before navigating. Maybe:

  • Check if login was successful
  • Decide based on user’s age
  • Go different places based on what happened

How It Works

Your button calls a Java method that returns the page name.

Example: Login Check

The Button (login.xhtml):

<h:commandButton
  value="Login"
  action="#{loginBean.checkLogin}" />

The Java Bean:

@Named
@RequestScoped
public class LoginBean {
  private String username;
  private String password;

  public String checkLogin() {
    if (isValidUser()) {
      return "dashboard"; // Go here!
    } else {
      return "error";     // Go here instead!
    }
  }
}

The Decision Flow

graph TD A["User Clicks Login"] --> B["checkLogin runs"] B --> C{Valid User?} C -->|Yes| D["Return &&#35;39;dashboard&&#35;39;"] C -->|No| E["Return &&#35;39;error&&#35;39;"] D --> F["Go to dashboard.xhtml"] E --> G["Go to error.xhtml"]

Using NavigationHandler Directly

For extra control, use the NavigationHandler:

@Inject
FacesContext facesContext;

public void goSomewhere() {
  facesContext
    .getApplication()
    .getNavigationHandler()
    .handleNavigation(
      facesContext,
      null,
      "targetPage"
    );
}

⚡ Faces Event Handling: When Magic Happens

Analogy: In our magic mall, when you touch things, magic happens! These are events.

There are three types of magic touches:

Event Type When It Happens
Action Events Button clicks
Value Change Events Dropdown changes, typing
Phase Events Behind-the-scenes

🎯 Action Events: The Button Click Magic

Analogy: When you press a magic button, a spell is cast!

What Is It?

Action Events happen when users click buttons or links. Two ways to handle them:

Way 1: action (Navigate After)

<h:commandButton
  value="Save"
  action="#{userBean.save}" />
public String save() {
  // Save data
  return "success"; // Navigate to success.xhtml
}

Way 2: actionListener (React Immediately)

<h:commandButton
  value="Like"
  actionListener="#{postBean.like}" />
public void like(ActionEvent event) {
  likeCount++;
  // No navigation, stay on same page
}

When to Use Which?

Use action Use actionListener
Need to navigate Stay on same page
After form submit Quick reactions
Returns page name Returns nothing

Complete Example

<h:form>
  <h:commandButton
    value="Add to Cart"
    actionListener="#{cartBean.addItem}"
    action="#{cartBean.checkout}" />
</h:form>

What happens:

  1. addItem() runs first (adds item)
  2. checkout() runs next (navigates)

🔄 Value Change Events: The Watcher Magic

Analogy: Imagine a magic mirror that notices when you change your outfit and reacts!

What Is It?

Value Change Events trigger when form values change. Great for:

  • Updating related dropdowns
  • Showing/hiding sections
  • Validating as you type

Basic Example

<h:selectOneMenu
  value="#{bean.country}"
  onchange="submit()"
  valueChangeListener="#{bean.countryChanged}">
  <f:selectItem
    itemValue="us"
    itemLabel="USA" />
  <f:selectItem
    itemValue="uk"
    itemLabel="UK" />
</h:selectOneMenu>
public void countryChanged(
    ValueChangeEvent event) {
  String oldVal =
    (String) event.getOldValue();
  String newVal =
    (String) event.getNewValue();

  // Load cities for new country
  loadCities(newVal);
}

The Flow

graph TD A["User Changes Value"] --> B["Form Submits"] B --> C["valueChangeListener Runs"] C --> D["Get Old Value"] C --> E["Get New Value"] D --> F["React to Change"] E --> F

Using f:valueChangeListener Tag

<h:inputText value="#{bean.email}">
  <f:valueChangeListener
    type="com.app.EmailValidator" />
</h:inputText>

AJAX Way (Modern Approach)

<h:selectOneMenu value="#{bean.country}">
  <f:ajax
    event="change"
    listener="#{bean.countryChanged}"
    render="cityDropdown" />
  <f:selectItems value="#{bean.countries}" />
</h:selectOneMenu>

<h:selectOneMenu
  id="cityDropdown"
  value="#{bean.city}">
  <f:selectItems value="#{bean.cities}" />
</h:selectOneMenu>

🌊 Phase Events: The Behind-the-Scenes Magic

Analogy: Before you enter a room in the magic mall, invisible helpers clean it, turn on lights, and prepare everything!

What Is It?

Jakarta Faces has a lifecycle - a series of steps that happen every time a page is requested. Phase Events let you hook into these steps.

The 6 Phases

graph TD A["1. RESTORE VIEW"] --> B["2. APPLY REQUEST"] B --> C["3. VALIDATE"] C --> D["4. UPDATE MODEL"] D --> E["5. INVOKE APP"] E --> F["6. RENDER RESPONSE"]
Phase What Happens
Restore View Build/restore the page
Apply Request Get form data
Process Validations Check if data is valid
Update Model Put data in beans
Invoke Application Run your methods
Render Response Show the result

Creating a Phase Listener

public class MyPhaseListener
    implements PhaseListener {

  @Override
  public void beforePhase(
      PhaseEvent event) {
    System.out.println(
      "Before: " + event.getPhaseId());
  }

  @Override
  public void afterPhase(
      PhaseEvent event) {
    System.out.println(
      "After: " + event.getPhaseId());
  }

  @Override
  public PhaseId getPhaseId() {
    return PhaseId.ANY_PHASE;
  }
}

Registering It

In faces-config.xml:

<lifecycle>
  <phase-listener>
    com.app.MyPhaseListener
  </phase-listener>
</lifecycle>

Common Use Cases

Use Case Listen To
Security check RESTORE_VIEW
Logging ANY_PHASE
Performance RENDER_RESPONSE

🎁 Putting It All Together

Here’s a complete example showing all concepts:

The Page (shop.xhtml)

<h:form>
  <!-- Value Change Event -->
  <h:selectOneMenu
    value="#{shopBean.category}">
    <f:ajax
      event="change"
      listener="#{shopBean.catChanged}"
      render="products" />
    <f:selectItems
      value="#{shopBean.categories}" />
  </h:selectOneMenu>

  <!-- Action Event (stays on page) -->
  <h:commandButton
    value="Add to Cart"
    actionListener="#{shopBean.addToCart}">
    <f:ajax render="cartCount" />
  </h:commandButton>

  <!-- Implicit Navigation -->
  <h:commandButton
    value="View Cart"
    action="cart" />

  <!-- Programmatic Navigation -->
  <h:commandButton
    value="Checkout"
    action="#{shopBean.checkout}" />
</h:form>

The Bean

@Named
@SessionScoped
public class ShopBean implements Serializable {

  // Value Change Listener
  public void catChanged(
      AjaxBehaviorEvent event) {
    loadProducts(category);
  }

  // Action Listener
  public void addToCart(ActionEvent e) {
    cart.add(selectedProduct);
  }

  // Programmatic Navigation
  public String checkout() {
    if (cart.isEmpty()) {
      return null; // Stay on page
    }
    return "checkout"; // Navigate
  }
}

🚀 Quick Summary

Concept What It Does Code Hint
Implicit Nav Auto-navigate by name action="pageName"
Programmatic Nav Code decides where return "pageName";
Action Event Button click handler actionListener=
Value Change Input change handler valueChangeListener=
Phase Event Lifecycle hooks PhaseListener

💡 Remember!

  1. Implicit = Easy, just use the page name
  2. Programmatic = Smart, your code decides
  3. Action Events = Clicks
  4. Value Change = Typing/selecting
  5. Phase Events = Behind the scenes

You’re now ready to navigate your Jakarta EE magic mall like a pro! 🎉

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.