Current Record Visual Attribute problem

If you have a multi-record block, and you use the handy Current Record Visual Attribute (CRVA) to set, say, a different background colour on all the items in the currently selected record, you may have run into this problem.

If you want to conditionally switch the visual attribute for certain items, at the item instance (i.e. record) level, this causes the CRVA to be overwritten, and the current record won’t be consistently highlighted. To get around this problem, a bit more code is required.

For example, let’s say you have a multi-record block called EMP, and it has two items that are sometimes gray, sometimes white – SALARY and ROLE. You have defined the following visual attributes:
EDITABLE_ITEM – white background
READONLY_ITEM – gray background
CURRENT_RECORD – blue background

Package Specification

PACKAGE EMP_BLOCK IS
PROCEDURE highlight_current_record;
PROCEDURE when_clear_block;
PROCEDURE when_remove_record;
END EMP_BLOCK;

Package Body

PACKAGE EMP_BLOCK IS

record_highlighted INTEGER;

PROCEDURE highlight_current_record IS
  rec INTEGER := GET_BLOCK_PROPERTY('EMP', CURRENT_RECORD);
  PROCEDURE set_visattr
    (itemn IN VARCHAR2
    ,rec IN NUMBER
    ,visattr IN VARCHAR2) IS
  BEGIN
    IF visattr IS NULL THEN
      -- (we could, if needed, make this more intelligent about
      -- detecting whether the record is NEW/INSERT/CHANGED,
      -- and examine the INSERT_ALLOWED/UPDATE_ALLOWED
      -- properties accordingly)
      IF GET_ITEM_INSTANCE_PROPERTY
        (itemn
        ,record_highlighted
        ,UPDATE_ALLOWED) = 'TRUE' THEN
        set_visattr(itemn, record_highlighted, 'EDITABLE_ITEM');
      ELSE
        set_visattr(itemn, record_highlighted, 'READONLY_ITEM');
      END IF;
    ELSE
      SET_ITEM_INSTANCE_PROPERTY
        (itemn
        ,rec
        ,VISUAL_ATTRIBUTE
        ,visattr);
    END IF;
  END set_visattr;
BEGIN
  -- Note: if record_highlighted is null, then no record
  -- is currently highlighted
  IF rec != record_highlighted THEN
    --un-highlight the record that was highlighted
    set_visattr('EMP.SALARY', record_highlighted);
    set_visattr('EMP.ROLE', record_highlighted);
  END IF;
  --highlight the newly selected record
  set_visattr('EMP.SALARY', rec, 'CURRENT_RECORD');
  set_visattr('EMP.ROLE', rec, 'CURRENT_RECORD');
  record_highlighted := rec;
END highlight_current_record;

PROCEDURE when_clear_block IS
BEGIN
  record_highlighted := NULL;
END when_clear_block;

PROCEDURE when_remove_record IS
BEGIN
  IF record_highlighted = :SYSTEM.TRIGGER_RECORD THEN
    record_highlighted := NULL;
  END IF;
END when_remove_record;

END EMP_BLOCK;

Block-level triggers on EMP:

when-new-record-instance

EMP_BLOCK.highlight_current_record;

when-clear-block

EMP_BLOCK.when_clear_block;

when-remove-record

EMP_BLOCK.when_remove_record;

Also, whenever your code modifies the UPDATE_ALLOWED property on SALARY or ROLE, it must then call EMP_BLOCK.highlight_current_record again.

Forms Library: PKG_FORM
Priority #1: Keep it simple

Leave a Reply

Your email address will not be published / Required fields are marked *