Link to home
Start Free TrialLog in
Avatar of r211
r211

asked on

Button in a form

Hi,

I have a button in a form X. That button needs to appear if this form X is in update or changed mode and shouldn't appear when it is insert mode. This form is calleed from form Y always. WHen it is coming from form Y to X only it has to validate whether it is in insert/ new or update/change modes.

For this I did wrote a pre-form trigger.
BEGIN
if :SYSTEM.FORM_STATUS in ('QUERY','CHANGED') then
      set_item_property('X1', VISIBLE, PROPERTY_TRUE);
           SET_ITEM_PROPERTY('X1',ENABLED,PROPERTY_TRUE);
else if :SYSTEM.FORM_STATUS in ('NEW','INSERT') then
      set_item_property('X1', VISIBLE, PROPERTY_FALSE);
           SET_ITEM_PROPERTY('X1',ENABLED,PROPERTY_FALSE);

end if;
The problem is:this button appears as tab through the fields only . Can any one tell me the mistake I did?Why is it not able to recognise the form status?
Avatar of Helena Marková
Helena Marková
Flag of Slovakia image

The form status can be only:
CHANGED
NEW
QUERY

After making EXECUTE_QUERY in the When-New-Form-Instance trigger the form status becomes QUERY.

This is from the on-line help:
CHANGED     Indicates that the form contains at least one block with a Changed record. The value of SYSTEM.FORM_STATUS becomes CHANGED only after at least one record in the form has been changed and the associated navigation unit has also changed.

NEW             Indicates that the form contains only New records.

QUERY         Indicates that a query is open. The form contains at least one block with QUERY records and no blocks with CHANGED records.
What happens in your form when it is called to ensure it is called in either QUERY/CHANGED or NEW status?

I would guess that when the form is called, you have some startup trigger code that queries existing rows or doesn't.  This code may be on the WHEN-NEW-FORM-INSTANCE trigger.

I suspect your problem is due to checking the form status too early.  The PRE-FORM trigger hasn't yet loaded the form so it may not know the status and even if it does, it will probably be NEW as no data has yet been queried.

Try moving your code to the WHEN-NEW-FORM-INSTANCE trigger and after the code that optionally queries data in the form.
It looks like you are not trying to use Oracle Forms the way it works best (most efficiently and with the least programming effort on your part) but rather you seem to be trying to get Forms to work the way you imagine it can work.  Yes, if you understand very well how Oracle Forms works by default, you can supplement that with some custom code in triggers and/or program units to get some non-default functionality.  But, I  would advise that you first learn and understand very well how Forms works by default, and only after that should you attempt to add non-default functionality.

Your attempt to distinguish between "update or changed mode" and "insert mode" look like an attempt to force Oracle Forms to do something that it doesn't do by default.   True, if you haven't done a query in ablock, the form will be in "insert" mode, but if you have done a query, the form will be in both "insert" and "update" (and/or "delete") mode depending on whether you scroll to an empty record or stay on a queried record.

What action do want the button to support that you want to have displayed when the form is in "update" mode?
Avatar of r211
r211

ASKER

Thanks for your valuable suggestions...I am new and learning it...hope u guys understand...u need not get ticked-off with the question..if I know how it works i wouldn't have post anything on this forum....

I already wrote it in When-New-form-Instance trigger only.
Can you give more information about how you want this form to work and why it isn't working.

You say in your question that you put the code into a PRE-FORM trigger, but now you are saying you have put it into a WHEN-NEW-FORM-INSTANCE trigger.  Do you get the same result when the code is in either trigger.
You won't be able to use either a when-new-form-instance or a pre-form trigger to determine to determine whether a block contains records that an be updated or not since when those fire, the form is not populated yet.  One exception would be if your when-new-form-instance trigger automatically navigates to at least one base-table block and executes a query.

You could use a post-query trigger to determine this.  But, to be consistent, you may also need this logic in (or called by) a post-insert trigger as well, since after doing an insert, the block will support updates by default.
Avatar of r211

ASKER

Yeah it didn't work when written in either trigger...I also did try post-query in the data block where that button is.

When coming from form X to form Y the status is
Form-level=Changed
Block-Level=Changed
Record_status=Insert

But its not recognising the status of the form. so it is not able to hide that button when a new record is being added.
If you define the button to be normally disabled (or not visible) you could use a post-query trigger to enable it.  That way it won't be visible for new records. You will have to use: set-item-instance-property to set the property just for the current record, not: set-item_property which would set it the same for all records in the block.

But if you could tell us what you want this button to do, there may be a better or easier way to accomplish this task in Oracle Forms.
Avatar of r211

ASKER

I have form X for employee search. When I give the emp number, it retrieves the data and consequently it leads to other set of forms one by one. When it takes me to form Y, if  it  retrieves already existing record, this button has to appear. Also this button when-button-pressed needs to validate that if that employee company email id is already in  use by others. If so need to display that it is already in use or needs to update the employee email (casual like yahoo,..) with that email id. But if I am adding a new employee to the database that button shouldn't appear.

I wrote that trigger for validating if email id is already in use or not. I am stuck with the button display only.
One possible solution is putting this code to the Post-Query and When-New-Record-Instance triggers:
IF :your_block.emp_number is not null THEN
-- existing employee
 set_item_property('X1', VISIBLE, PROPERTY_TRUE);
 SET_ITEM_PROPERTY('X1',ENABLED,PROPERTY_TRUE);
 SET_ITEM_PROPERTY('X1',NAVIGABLE,PROPERTY_TRUE);
ELSE
-- new employee
 set_item_property('X1', VISIBLE, PROPERTY_FALSE);
END IF;
I think this should use; SET_ITEM_INSTANCE_PROPERTY, not SET_ITEM_PROPERTY, since this check only applies to the current record.  Also, this logic should then be in a program unit so it can be called from both the Post-Query and Post-insert triggers.  It should not be needed in the When-New-Record-Instance trigger if the item is normally not visible.

One other caution about using a When-New-Record-Instance trigger: this fires a lot more often than you might expect, including: when the user first enters the block (no surprise); whenever the block gets cleared (including pre-query); whenever the user navigates to a new (empty) record, etc.  So, this can be a performance problem.

I'm still not convinced that using a button that you try to hide or display programmatically is the best way to handle this in an Oracle Form, but if you remember to cover every possible way that a user can either get to a new record or to an existing record, it may be possible.
The properties you can set with SET_ITEM_INSTANCE_PROPERTY are much more restricted than with SET_ITEM_PROPERTY and I don't think you can change the VISIBLE  property.

If the form is only showing one record at a time then this shouldn't be a problem as the SET_ITEM_PROPERTY can be used and the button will appear/disappear as different records are displayed.
I disagree.  SET_ITEM_PROPERTY applies to all records in the block, whether they are currently displayed, or not.  True, SET_ITEM_INSTANCE_PROPERTY is more restricted, plus you also have to indicate which row is the current row (I think Forms has a supplied variable that can do this).

That is partly why I don't like this approach of trying to display or hide a button programmatically on individual records.  That looks like a complex way (in Oracle Forms at least) of trying to solve a problem that may be solved easier in Oracle Forms by other means.
I agree that SET_ITEM_PROPERTY applies to all items in a block, rather than the current item (identified by a record number), all I was saying is that if only one record is displayed at a time then using SET_ITEM_PROPERTY within a WHEN-NEW-ITEM-INSTANCE trigger will work as the user will only see the button related to the current record (or they won't see it, if you get my meaning).  As the form navigates through the records, the SET_ITEM_PROPERTY would display or hide the button for the currently displayed record as appropriate.  In a single record block, only one button would be visible at any time.

If the block displays multiple records then this wouldn't work as the button would appear/disappear for ALL records displayed in the block, not just the current record.

It isn't possible to switch off the visibility of an item using SET_ITEM_INSTANCE_PROPERTY as the VISIBLE property can't be specified so this method couldn't be used.
OK, if the visible property cannot by changed with SET_ITEM_INSTANCE_PROPERTY, that would be another reason to not try to use this technique (of trying to show or hide a button based on some conditions) but to use other features of Oracle Forms to try to solve the business problem.  (It may be possible to change the enabled property of a button with the SET_ITEM_INSTANCE_PROPERTY - I didn't check that, but I still don't like this technique.)

Oracle Forms works much better when you use the features it does by default, and try to stay away from things that it doesn't do all that well.  Remember, Oracle Forms is a powerful data entry, validation and query tool that was developed before the days of Windows and GUI desktops.  Yes, it can support many GUI features now, but some of them may not be as easy to use in Oracle Forms as they may be in some other tools that weren't even invented until after GUI desktops were common.
If there are multiple records in the block but only ONE instance of the button visible (which in most of the cases is used in forms) then there is no problem using set_item_property() because user can position cursor to only one record at a time (well - I assume no multi-record-select functionality) and then even set_item_property() is applied to all records, the effect of it will be visually expressed only to this one instance of the button.

What I am confused with is that it looks to me on the called form you need to know what is the state of the calling form(?) or you need the state of the record on the called form? Regardless - when-new-record-instance is a good place for the logic to take care of the button visibility. To work well, you need couple of things
- in when-new-form-istance: add code to navigate to the appropriate block and issue execute_query() if needed. This will fire w-n-r-i
- make the w-n-r-i not to fire in enter-query if you use such functionality
- make sure the button is not you first navigable item in the block or instead of go_block() in w-n-f-i, use go_item() to navigate to specific item.
- keep in mind, property VISIBLE=FALSE automatically sets ENABLED=FALSE, so you don't have to issue this command.
- when set to VISIBLE=TRUE you have to set not only ENABLED=TRUE but also NAVIGABLE=TRUE to ensure your button can be reached through the keyboard tabbing.
- make sure the code to use set_item_property() checks if the button is the current item - however, this is more applicable if you have multiple instances of the button when VISIBLE property is not applicable, but you can play with ENABLED (as far as I remember)


Hope this can help.
Are you willing to tell us how you solved the problem?
ASKER CERTIFIED SOLUTION
Avatar of r211
r211

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of r211

ASKER

Thank you all for the suggestions....I really learnt a lot
Avatar of r211

ASKER

solved..