Skip to Main Content
Change the login background image Code Instrumentation

Close a page from JavaScript

In Oracle APEX, you can close a page from JavaScript depending on how it was opened.:

---UN TESTED CODE ---

Close a Dialog Page

If the page was opened as a modal/dialog, you can use the built-in APEX JavaScript API:

apex.navigation.dialog.close(true, "yourReturnValue");

true β†’ means success. Use false if you want to indicate cancel/error.
"yourReturnValue" β†’ optional return value you can pass back.

πŸ‘‰ Example (close dialog without return):

apex.navigation.dialog.close(true);

Close Browser Window / Tab

If the APEX page was opened in a new window/tab (not as a dialog), you can use:

window.close();

⚠️ Note: This only works if the page was opened by JavaScript (e.g., window.open). 
Browsers often block closing tabs that the user opened manually.

Redirect Instead of Closing
If you just want to exit the page and go somewhere else:

apex.navigation.redirect("f?p=100:1:&APP_SESSION:");

Replace 100 with your Application ID
Replace 1 with the page number you want to go to.

βœ… Best Practice:

  • Use apex.navigation.dialog.close for modal pages.
  • Use apex.navigation.redirect for normal navigation.
  • Only use window.close() if you’re sure the page is opened by script.

Close Page with Button Click

1. Close a Dialog Page

  • If your page is a Modal/Dialog: 
  • Add a button (e.g., Close).
  • Create a Dynamic Action:
  • Event: Click
  • Selection Type: Button
  • Button: Close
  • Add a True Action β†’ Execute JavaScript 
apex.navigation.dialog.close(true);

Close a Normal Page (Tab/Window)
If your page is opened in a new browser window/tab:

  • Add a button (e.g., Exit).
  • Create a Dynamic Action:
  • Event: Click
  • Selection Type: Button
  • Button: Exit
  • Add a True Action β†’ Execute JavaScript 
window.close();

⚠️ Works only if the page was opened via window.open(). Browsers block window.close() if the user opened the page manually.

Redirect Instead of Close
If you want the button to send the user back to another APEX page (e.g., Home Page 1):

apex.navigation.redirect("f?p=&APP_ID.:1:&APP_SESSION.");

Close a Dialog Page (Modal)
Steps:
Create a button on your dialog page (e.g., CLOSE_DIALOG).

  • Add a Dynamic Action:
  • Event β†’ Click
  • Selection Type β†’ Button
  • Button β†’ CLOSE_DIALOG
  • Add a True Action β†’ Execute JavaScript Code
// Close the dialog and return success
apex.navigation.dialog.close(true, "Closed from button");

πŸ‘‰ If you don’t need to return a value:

apex.navigation.dialog.close(true);

This will close the dialog immediately when the button is clicked.

Close a Normal Page (Tab / Window)
Steps:

  • Create a button on your normal page (e.g., CLOSE_PAGE).
  • Add a Dynamic Action:
  • Event β†’ Click
  • Selection Type β†’ Button
  • Button β†’ CLOSE_PAGE
  • Add a True Action β†’ Execute JavaScript Code.
// Try to close the window if it was opened by script
if (window.opener) {
   window.close();
} else {
   // Fallback: redirect to Home Page (page 1)
   apex.navigation.redirect("f?p=&APP_ID.:1:&APP_SESSION.");
}

πŸ‘‰ This version is safer:
If the page was opened with window.open(), it closes.
If the user opened it manually (browser blocks window.close()), it redirects to page 1 instead.
βœ… With these two snippets, you can handle both scenarios (dialogs and normal pages).

Sending a Value Back from a Dialog

On your Dialog Page:

  • Add a button (e.g., BTN_CLOSE_WITH_RETURN).
  • Create a Dynamic Action:
  • Event β†’ Click
  • Selection Type β†’ Button
  • Button β†’ BTN_CLOSE_WITH_RETURN
  • Add a True Action β†’ Execute JavaScript Code.
// Example: return a Customer ID value from an item
var returnVal = $v("P20_CUSTOMER_ID"); 
apex.navigation.dialog.close(true, returnVal);

P20_CUSTOMER_ID β†’ replace with your page item name.
returnVal will be sent back to the parent page.

Receiving the Value in the Parent Page
On your Parent Page (the one that opened the dialog):

  • Create a Dynamic Action:
  • Event β†’ Dialog Closed
  • Selection Type β†’ Region (or Page if you want globally).
  • In the When Dialog Closed dynamic action, add a True Action β†’ Execute JavaScript Code.
// The return value from the dialog
var returnVal = this.data;
console.log("Dialog returned value: " + returnVal);
// Example: set it into a page item
$s("P10_CUSTOMER_ID", returnVal);

this.data contains the value sent from the dialog.
$s("P10_CUSTOMER_ID", returnVal); sets the value into an item on the parent page.

Example Use Case
Dialog Page (20) lets you search and pick a customer.
When you click Select, it closes the dialog and returns the customer ID.

apex.navigation.dialog.close(true, $v("P20_CUSTOMER_ID"));

Parent Page (10) listens for dialog close, then receives the ID and sets it into P10_CUSTOMER_ID.

$s("P10_CUSTOMER_ID", this.data);

βœ… This way, your dialog can pass back any value (IDs, names, JSON, etc.) to the parent page.

βœ… Method A (Recommended): JSON payload

Dialog page (sender)
Use your button’s Dynamic Action β†’ Execute JavaScript 

// Build a payload with as many fields as you need
var payload = {
 id:   $v("P20_CUSTOMER_ID"),
 name: $v("P20_CUSTOMER_NAME"),
 vip:  $v("P20_IS_VIP") === "Y",      // example boolean
 notes:$v("P20_NOTES")
};
// Close dialog with JSON string
apex.navigation.dialog.close(true, JSON.stringify(payload));

Parent page (receiver)
Create a Dynamic Action on Dialog Closed β†’ Execute JavaScript 

// this.data may be a string (JSON) or undefined if canceled
if (!this.data) {
 // User canceled or no return data
 return;
}
var data;
try {
 data = (typeof this.data === "string") ? JSON.parse(this.data) : this.data;
} catch(e) {
 // Fallback if it wasn't valid JSON
 data = {};
}
// Set multiple page items
apex.item("P10_CUSTOMER_ID").setValue(data.id || "", {fireChangeEvent:true});
apex.item("P10_CUSTOMER_NAME").setValue(data.name || "", {fireChangeEvent:true});
apex.item("P10_IS_VIP").setValue(data.vip ? "Y" : "N", {fireChangeEvent:true});
apex.item("P10_NOTES").setValue(data.notes || "");
// (Optional) refresh regions that depend on these items
// apex.region("orders_region").refresh();

βœ… Method B: Delimited string (simple

Dialog page (sender)

// Return a pipe-delimited string: ID|NAME|VIP|NOTES
var payload = [
 $v("P20_CUSTOMER_ID"),
 $v("P20_CUSTOMER_NAME"),
 $v("P20_IS_VIP"),
 $v("P20_NOTES")
].join("|");
apex.navigation.dialog.close(true, payload);

Parent page (receiver)

if (!this.data) return;
var parts = String(this.data).split("|");
// Defensive reads in case parts are missing
apex.item("P10_CUSTOMER_ID").setValue(parts[0] || "", {fireChangeEvent:true});
apex.item("P10_CUSTOMER_NAME").setValue(parts[1] || "", {fireChangeEvent:true});
apex.item("P10_IS_VIP").setValue(parts[2] || "N", {fireChangeEvent:true});
apex.item("P10_NOTES").setValue(parts[3] || "", {fireChangeEvent:true});

Note: Delimiters can break if your text contains |. JSON avoids that.

Bonus tips
If you want to detect cancel vs. OK, send false on cancel:

apex.navigation.dialog.close(false); // in dialog
  • Then in the parent, this.data will be undefined and you can just return;.
  • Use {fireChangeEvent:true} so dependent Dynamic Actions and Cascading LOVs react immediately.
  • After setting items, refresh any regions that depend on them