oracle-apexinteractive-grid

Oracle APEX Interactive Grid Cell Template


Scenario:

I have an interactive grid with 4 columns: prod_ref (select list), prod_name, promo_ref (hidden), and weight.

When prod_ref changes, a dynamic action updates prod_name and promo_ref values.

promo_ref is hidden via the Actions menu.

Requirement: If promo_ref has a value, I want to display an icon next to prod_name.

Current Implementation:

Using a custom cellTemplate on the prod_name column to conditionally show:

The product name

Weight (if available)

A bullhorn icon button (if promo_ref exists)

function(options) {
  options.defaultGridColumnOptions = {
    cellTemplate: `&PRODUCT_NAME. {if WEIGHT/}|| @&WEIGHT.Kg {endif/}
                  {if PROMOTION_REF/}
                    <button type="button"
                            class="t-Button t-Button--noLabel t-Button--icon t-Button--tiny t-Button--success t-Button--link">
                      <span aria-hidden="true" class="t-Icon fa fa-bullhorn"></span>
                    </button>
                  {endif/}`
  }
  return options;
}

Using a model subscription to refresh the grid when weight or promo_ref changes:

model.subscribe({
  onChange: function(changeType, change) {
    if (changeType == 'set') {
      if (change.field === "WEIGHT" || change.field === "PROMOTION_REF") {
        gridView$.grid("refreshColumns").grid("refresh");
      }
    }
  }
});

The Problem:

Desired Solution:

This would prevent grid instability while maintaining the required functionality.


Solution

  • You may try like this as to refresh the product name cell in the active row:

    model.subscribe({
      onChange: function(changeType, change) {
        if (changeType == 'set') {
          if (change.field === "WEIGHT" || change.field === "PROMOTION_REF") {
            let columns = gridView$.grid('getColumns');
            let cellTemplate = columns.filter((e)=>e.property=='PRODUCT_NAME')[0].cellTemplate;
            let options = {model: model, record: change.record};
            let htmlString = apex.util.applyTemplate(cellTemplate, options);
            let cell$ = gridView$.grid('getActiveCellFromColumnItem', apex.item('<product_name column static id>').node);
            cell$.html(htmlString);
          }
        }
      }
    });