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.

