Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

set_item_instance_property - Disable button for specific record 2

Status
Not open for further replies.

MissJules

Programmer
Apr 2, 2003
8
0
0
NL
Hi everyone

Using forms 6i, I have a block on a form where I am showing multiple records, each record has 2 buttons associated with it (as part of the block).

I need to either hide (preferably) or disable one of the two buttons at a record level - depending of the data in the record.

I have eventually resorted to using a display item formatted to look like a button, but I would prefer it to be a button because I need it to be an icon type button!!

To sum up I need the following :

set_item_property (‘my_item’, visible, property_false);
OR
set_item_property (‘my_item’, enabled, property_false);

but on a record level!!!

Any ideas?

Thanks
Jules
 
There are only a few properties you can set using set_item_instance_property, and 'ENABLE' and 'VISIBLE' are not amongst them, but you knew that! ;)

If you really need one button per record then you will have problems. I recommend setting the number of items displayed property of the button to 1, then use set_item_property as you require in a when-new-record-instance trigger. Dont position the button directly adjacent to any record, but provide a 'control' area for the button on the form.
 
As lewisp said, put only one button then
try to call this function in your post_query. This is the one I daily use for this job:

Code:
PROCEDURE HIDE_AN_ITEM (item_name VARCHAR2, hide_it BOOLEAN) IS
  it_id   Item;
  res number;
BEGIN
	it_id := Find_Item (item_name);
	IF NOT Id_Null (it_id) THEN
		IF hide_it THEN
			Set_Item_Property (it_id, VISIBLE, PROPERTY_FALSE);
		ELSE
			Set_Item_Property (it_id, VISIBLE, PROPERTY_TRUE);
			Set_Item_Property (it_id, ENABLED, PROPERTY_TRUE);
			Set_Item_Property (it_id, NAVIGABLE, PROPERTY_TRUE);
      IF Get_Item_Property(it_id, ITEM_TYPE) != 'BUTTON' THEN
				Set_Item_Property (it_id, UPDATE_ALLOWED, PROPERTY_TRUE);
			END IF;
		END IF;
	END IF;
EXCEPTION
	WHEN LOGIN_DENIED THEN
		RAISE LOGIN_DENIED;
	WHEN OTHERS THEN

                Put a message here
		RAISE LOGIN_DENIED;
END;
It works fine to hide all kinds of items, and can show all test and list items plus the buttons.

Let me know how it is for you...
 
Hi guys
Thanks for your input, but showing one record is not an option! Easy, but not an option!

I need to have at least 8 of the records showing and all of them must have the 2 buttons – one of which must be disabled or hidden. The users want to be able to see actions required “at a glance” – and this is what they specified.

So far my solution is –

2 non-database items on my block, with their visual attributes set to Bevel raised and foreground colour black which makes them look like an enabled button.

Then on my post-query trigger, I set the value of the 2 items to “button descriptions” and if I disable the one button I do the following

Set_item_instance_property (‘txtbutton1’, current_record, visual_attribute, ‘VA_DISABLED’);
Set_item_instance_property (‘txtbutton1’, current_record, bevel_border, lowered); /* not sure this looks so cool may remove this*/

Where va_disabled is a visual attribute with foreground colour set to gray32 (pseudo disabled button).

Then on the when-mouse-click trigger I use
Set_item_instance_property (‘txtbutton1’, current_record, bevel_border, lowered);
Set_item_instance_property (‘txtbutton1’, current_record, bevel_border, raised);
To simulate the button pressing.


But I cant HIDE the button, because you cant set a bevel_border to NONE, and if you start off the with the item as bevel_border = NONE you cant change it to RAISED. Also setting bevel_border = PLAIN leaves an ugly black border!!

So I have pretty much simulated what the users are looking for.
I am now trying to make them look like Icon buttons…. but for that I think I will have to make my text item an image item- and populate the image in my post query….

Any suggestions?
 
Any one who is interested!

I found a brilliant piece of very-easy-to-use code on Metalink to do EXACTLY what I was looking for.

If anyone ever needs to do something like this look at "Doc_id 117494.1 - How to Implement Iconic Buttons Having Different Images in a Multirecord-Block ?" on Metalink.

Its well documented and super easy to use!
 
All credit to go to Metalink...

Doc ID:
Note:117494.1
Subject: How to Implement Iconic Buttons Having Different Images in a Multirecord-Block ?
Type: FAQ
Status: PUBLISHED
Content Type: TEXT/PLAIN
Creation Date: 15-AUG-2000
Last Revision Date: 29-OCT-2002

ORACLE DEVELOPER - FORMS
------------------------

This article describes a way to work around the limitation that it is not
possible to change the icon shown on an iconic button in a multi-record-block.
SET_ITEM_PROPERTY changes the label of the button in all the records of the
block, whereas the ICON_NAME is not one of the properties which can be set
using SET_ITEM_INSTANCE_PROPERTY.

The method described in this article consists of a set of buttons, placed in a
separate-block. For each record in the multi-record-block there is one button
in the separate block. In the when-new-record-instance-trigger the icons shown
on the buttons are synchronized with the record the buttons are placed by.

To make it all work create the buttons with names 'PB_x' with x=record-number.
Suppose you have an EMP-block with 5 records shown, you have to create a control
block with buttons PB_1, PB_2, PB_3, PB_4 and PB_5.

All the triggers needed in the application invoke a procedure from a package
which can also be found in this article.

___________________________________________________________________________
FORM-LEVEL-TRIGGERS
___________________________________________________________________________
There are one or two triggers to be defined at form-level, depending on the
display of a scrollbar for the multi-record-block.

When there is no scrollbar use:

WHEN-NEW-FORM-INSTANCE-trigger:
mr_buttons.when_new_form_instance (start_timer => FALSE);

When there is a scrollbar use:

WHEN-NEW-FORM-INSTANCE-trigger:
mr_buttons.when_new_form_instance (start_timer => TRUE);

WHEN-TIMER-EXPIRED-trigger:
mr_buttons.when_timer_expired;

(When the user drags a scrollbar no trigger fires; to synchronize the images
on the buttons in this situation a timer is used which checks every x seconds
whether the top-record displayed in the multi-record-block is still the same).

___________________________________________________________________________
BLOCK-LEVEL-TRIGGERS
___________________________________________________________________________
In the control-block containing the buttons the next trigger must be defined:
WHEN-BUTTON-PRESSED-trigger:
mr_buttons.when_button_pressed;

In the multi-record-block the following triggers must be defined:
WHEN-NEW-RECORD-INSTANCE-trigger:
mr_buttons.when_new_record_instance;

PRE-QUERY-trigger:
mr_buttons.pre_query;

KEY-ENTQRY-trigger:
mr_buttons.key_entqry;

KEY-CREREC-trigger:
mr_buttons.key_crerec;

KEY-DELREC-trigger:
mr_buttons.key_delrec;

KEY-DOWN-trigger:
mr_buttons.key_down;

___________________________________________________________________________
ITEM-LEVEL-TRIGGERS
___________________________________________________________________________
There is only one item-level-trigger in this situation on the item determining
the image to be displayed on the button:

WHEN-VALIDATE-ITEM-trigger:
mr_buttons.when_validate_item;

___________________________________________________________________________
MR_BUTTONS-package
___________________________________________________________________________
This package contains all the necessary routines; the routines to be localized
can be found by searching on --####### NEEDS TO BE LOCALIZED !!!
The localizations contain eg. the name of the multirecord-block, the delay when
using timers, the names of the icons as well as the whole algorithm determining
which icons are to be shown, and the when-button-pressed-trigger on the button-
block.

PACKAGE MR_BUTTONS IS

-- form-level procedures
PROCEDURE WHEN_NEW_FORM_INSTANCE (start_timer in boolean);
PROCEDURE WHEN_TIMER_EXPIRED;

-- block-level procedures for multi-record-block
PROCEDURE WHEN_NEW_RECORD_INSTANCE;
PROCEDURE PRE_QUERY;
PROCEDURE KEY_ENTQRY;
PROCEDURE KEY_CREREC;
PROCEDURE KEY_DELREC;
PROCEDURE KEY_DOWN;

-- item-level procedure for multi-record-item
PROCEDURE WHEN_VALIDATE_ITEM;

-- block-level procedures for control-block
PROCEDURE WHEN_BUTTON_PRESSED;
END;


PACKAGE BODY MR_BUTTONS IS
MR_BLOCK_NAME VARCHAR2(50) := 'EMP'; --####### NEEDS TO BE LOCALIZED !!!
NR_OF_RECORDS NUMBER := GET_BLOCK_PROPERTY (MR_BLOCK_NAME, RECORDS_DISPLAYED);

PROCEDURE EMPTY_BUTTONS IS
BEGIN
FOR i IN 1..nr_of_records LOOP -- nr of records in block
SET_ITEM_PROPERTY('CONTROL.PB_'||TO_CHAR(i), ICON_NAME, ' ');
END LOOP;

END;

PROCEDURE RESYNC_BUTTON (recno in number) IS
BEGIN
--####### NEEDS TO BE LOCALIZED !!!
if :emp.sal is null THEN
set_item_property('control.PB_'||to_char(recno), icon_name, ' ');
elsif :emp.sal <= 2000 then
set_item_property('control.PB_'||to_char(recno), icon_name, 'afldown');
else
set_item_property('control.PB_'||to_char(recno), icon_name, 'aflup');
end if;
END;

PROCEDURE RESYNC IS
v varchar2(30);
topnr number;
curr number;
BEGIN
if :SYSTEM.MODE != 'ENTER-QUERY' then
v := get_block_property(mr_block_name, current_record);
curr := to_number(v);
v := get_block_property(mr_block_name, top_record);
topnr := to_number(v);
for i in 1 .. nr_of_records loop -- nr of records in block
set_item_property('control.PB_'||to_char(I), icon_name, ' ');
go_record(topnr+(i-1));
resync_button (i);
end loop;
go_record(curr); -- go back to the original record
:GLOBAL.TOPRECORD := V;
end if;
END;

PROCEDURE WHEN_NEW_FORM_INSTANCE (start_timer in boolean) IS
timerid timer;
BEGIN
:GLOBAL.TopRecord := 'wnfi'; -- to force resynchronisation
GO_BLOCK (MR_BLOCK_NAME);
EXECUTE_QUERY;
if start_timer then -- this will cause heavy load when running on the web !!
--####### timervalue NEEDS TO BE LOCALIZED !!!
timerid := create_timer ('RESYNC', 2000, repeat);
end if;

END;

PROCEDURE WHEN_TIMER_EXPIRED IS
v varchar2(20);
BEGIN
v := get_block_property (mr_block_name, TOP_RECORD);
if v is not null and v <> :GLOBAL.TOPRECORD then
-- resync when user has apparently dragged the scrollbar
resync;
end if;
END;

PROCEDURE WHEN_NEW_RECORD_INSTANCE IS
v VARCHAR2(2000);
BEGIN
v := GET_BLOCK_PROPERTY(MR_BLOCK_NAME, TOP_RECORD);
IF v IS NOT NULL AND V <> :GLOBAL.TopRecord THEN
resync; -- call program unit to show values
END IF;
END;

PROCEDURE KEY_CREREC IS
v VARCHAR2(2000);
topnr number;
curr number;
new_icon varchar2(200);
BEGIN
create_record;
v := :system.cursor_record;
-- temporarily set the recordstatus so that navigation out of
-- the new record is allowed; thus all scrolling forms has
-- performed to show the new record can be resync-ed to the buttons
set_record_property (v, MR_BLOCK_NAME, STATUS, QUERY_STATUS);
resync;
go_record (v);
-- and of course reset the status to its original
set_record_property (v, MR_BLOCK_NAME, STATUS, NEW_STATUS);
END;

PROCEDURE KEY_DELREC IS
BEGIN
delete_record;
resync;
END;

PROCEDURE PRE_QUERY IS
BEGIN
:GLOBAL.TopRecord := 'pq'; -- change the top record to force image-change
empty_buttons;
END;

PROCEDURE KEY_ENTQRY IS
BEGIN
:GLOBAL.TopRecord := 'ke'; -- change the top record to force image-change
empty_buttons;
ENTER_QUERY;
END;

PROCEDURE KEY_DOWN IS
BEGIN
-- when tabbing through records, create a new record after the last one
if :SYSTEM.LAST_RECORD = 'TRUE' then
do_key ('create_record');
else
next_record;
end if;
END;

PROCEDURE WHEN_VALIDATE_ITEM IS
v varchar2(30);
topnr number;
curr number;
BEGIN
v := :system.cursor_record;
curr := to_number(v);
v := get_block_property(mr_block_name, top_record);
topnr := to_number(v);
resync_button (curr+1-topnr);
END;

PROCEDURE WHEN_BUTTON_PRESSED IS
BEGIN
--####### NEEDS TO BE LOCALIZED !!!
Message('Button : '||:SYSTEM.TRIGGER_ITEM||' is pressed');
-- This will contain nr as well ....
END;

END;

References
----------
Note:42018.1 CREATING DYNAMICALLY POSITIONED LIST ITEMS IN FORMS
Describes a similar trick to position an item dynamically.
 
Had a similar situation with a record group. Customer wanted a check-box on each record, set up so that once checked, could not be un-checked. Tried to use SET_ITEM_INSTANCE_PROPERTY, didn't work. Ended up using a radio group, w/ one of the buttons visible and the other hidden. Customer decided a dot-in-a-circle was equivalent to a checked-box. Hadn't thought of creating a pseudo check-box.

 
Set Update Only if NULL property.

Regards, Dima
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top