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.