Skip to main content

Freeze panes in Interactive Grid : Driven by a page item

Oracle APEX Tutorial

Freeze Panes in Interactive Grid
: Driven by a Page Item

Lock N columns in place with a select list : no plugins, no hacks. Pure JavaScript, a Dynamic Action, and clean CSS that survives sort, search, and pagination.

Create page item
Add page JavaScript
Dynamic Action
Optional CSS
1

Create the P1_FREEZE_COLS select list

In Page Designer, add a Select List page item. Configure it as shown below. Also set the Interactive Grid region's Static ID to emp_grid via Properties → Advanced → Static ID.

NameP1_FREEZE_COLS
List of ValuesStatic Values : Display/Return 0 through 5
Default Value0
TemplateOptional / Floating Label
Region Static IDemp_grid
2

Page JavaScript : Execute when Page Loads

Paste this into Page → JavaScript → Execute when Page Loads. It handles the initial render, post-sort, pagination, and every apexafterrefresh event automatically.

JavaScript
(function () {
  "use strict";

  var REGION_ID  = "emp_grid";       
  var ITEM_NAME  = "P1_FREEZE_COLS";  

  function clearFreeze() {
    var $tbl = apex.region(REGION_ID).widget().find(".a-GV-table");
    $tbl.find("thead tr th, tbody tr td").css({
      position    : "", left        : "", zIndex      : "",
      background  : "", boxShadow   : "", borderRight : ""
    }).removeClass("ig-frozen-col ig-freeze-edge");
  }

  function applyFreeze(numCols) {
    clearFreeze();
    numCols = parseInt(numCols, 10);
    if (!numCols || numCols < 1) return;

    var $tbl = apex.region(REGION_ID).widget().find(".a-GV-table");
    if (!$tbl.length) return;

    var colWidths = [];
    $tbl.find("thead tr:first-child th").each(function (i) {
      colWidths[i] = $(this).outerWidth() || 120;
    });

    $tbl.find("thead tr, tbody tr").each(function () {
      var $row    = $(this);
      var inHead  = !!$row.closest("thead").length;
      var cumLeft = 0;

      $row.children("th, td").each(function (colIdx) {
        if (colIdx >= numCols) return false;
        var $cell  = $(this);
        var isEdge = (colIdx === numCols - 1);

        $cell.css({
          position   : "sticky",
          left       : cumLeft + "px",
          zIndex     : inHead ? 31 : 20,
          background : inHead ? "#1a5f9e" : "#e8f0fa",
          boxShadow  : isEdge ? "2px 0 0 0 #0572ce" : ""
        });
        cumLeft += colWidths[colIdx];
      });
    });

    apex.region(REGION_ID).widget()
        .find(".a-GV-w-scrollX")
        .css("overflow-x", "auto");
  }

  function applyFromItem() {
    var val = $v(ITEM_NAME) || "0";
    applyFreeze(val);
  }

  apex.jQuery(document)
    .on("gridviewcreate apexafterrefresh", "#" + REGION_ID,
        function () { setTimeout(applyFromItem, 200); });

  setTimeout(applyFromItem, 800);

  window.igApplyFreeze = applyFromItem;
}());
3

Dynamic Action on P1_FREEZE_COLS

Right-click P1_FREEZE_COLS in Page Designer → Create Dynamic Action. Configure the event and add a True Action with the one-liner below. It calls the function already defined in Step 2 : no duplication needed.

EventChange
ItemP1_FREEZE_COLS
True ActionExecute JavaScript Code
JavaScript
igApplyFreeze();
4

Optional : Inline CSS for zebra striping

Add this to Page → CSS → Inline. Keeps the sticky header above the scroll layer and preserves the alternate-row shading on frozen cells.

CSS

#emp_grid .a-GV-w-scrollX {
  overflow-x: auto !important;
}


#emp_grid .a-GV-thead {
  position: sticky;
  top: 0;
  z-index: 30;
}

#emp_grid .a-GV-table tbody tr:nth-child(even) td[style*="sticky"] {
  background: #d4e4f7 !important;
}

How it works

When the user changes P1_FREEZE_COLS, $v("P1_FREEZE_COLS") reads the selected value in real time.
Each column's actual pixel width is measured from the live DOM on every call : zero hardcoding needed.
position: sticky is applied with the correct cumulative left offset to every <th> and <td> inside the frozen range.
A teal box-shadow line marks the freeze boundary on the rightmost frozen column : just like Excel's freeze pane indicator.
Freeze re-applies automatically after every sort, search, and pagination event via the apexafterrefresh hook : no manual trigger needed.

Quick Checklist

Add P1_FREEZE_COLS select list with static values 0–5 and default value 0
Set the Interactive Grid region Static ID to emp_grid via Properties → Advanced → Static ID
Paste the Step 2 JavaScript into Page → JavaScript → Execute when Page Loads
Create Dynamic Action on Change event → Execute JavaScript → igApplyFreeze();

Comments

Popular posts from this blog

Face Detection in Oracle Apex

Face Detection Blog - Embedded JS Jefith Shalin Oracle APEX Developer · May 2025 Live Demo GitHub Oracle APEX · AI Integration A Developer's Real Story Building a Face Detection Attendance System in Oracle APEX A real story of trial, error, and finally making face-api.js actually work inside an APEX app. No fluff — just what happened and what finally worked. Try Live Demo View on GitHub 0.22.2 face-api.js Version 2 APEX Pages Built 4 AJAX Processes face-api.js Oracle APEX JavaScript AI / ML Face Recognition CDN Attendance System PL/SQL The Beginning So here is how it all started I was tasked with building an attendance system for our off...

Screen Recorder in Oracle APEX (Single Page)

Oracle APEX Tutorial Screen Recorder in Oracle APEX : Single Page Build a fully functional browser-based screen recorder inside Oracle APEX using just one Static Content region and native JavaScript. No plugins, no external libraries, no server uploads required. ✍️ Why I Built This I was working on a client project where the support team needed to record screen issues and share them directly from the APEX application, without switching to any external tool. Installing third-party software was not an option on their machines, and every screen recorder extension required IT approval. That is when I thought: the browser already has everything we need. Why not build it right inside APEX? That idea turned into this. &#127916; Start / Stop Recording &#128065; Instant Preview ⬇️ One-click Download &#128266; Audio + Video ...

Sticky Notes Widget Inside Oracle APEX

Oracle APEX Project Building a Sticky Notes Widget in Oracle APEX How I built a fully draggable, color-coded, per-user sticky notes board using jQuery UI, APEX Ajax callbacks, and a bit of patience. Live Demo GitHub Repo Oracle APEX jQuery UI PL/SQL Ajax Callbacks JavaScript CSS Introduction Why I Built This I have been building internal tools on Oracle APEX for a while now, and one thing I always felt was missing was a place where users could quickly jot down thoughts without leaving the page. Think of it like a personal scratchpad that lives right inside the app. I had seen sticky note UIs in some Google products and I thought, how hard can this be in APEX? It turned out to be more interesting than I expected. There were a few wrong tu...