2011년 12월 7일 수요일

Forms에서 멀티 라인 입력하기


The idea for this sample form came to me from the Oracle Technology Network (OTN) user forums.  The question was asked: Is there a way to count the number of characters a user has typed into a multi-line Text-Item and display the number of characters remaining?  I knew this could be done with a timer, but had never seen it done nor had I done it myself.  So, I decided it was time to figure out how to do it. 

I hope you find the following sample Form useful.  The code included is not specific to any version of Oracle Forms, however, I have only tested the code with Oracle Forms 10g R2 (10.1.2.0.2).  The supplied sample form is written using this version, but you should be able to use the supplied code in Forms 6i or higher.

The following sample will walk you through creating a non-base table form that employs a timer to count the number of characters that have been entered in a multi-line Text-Item and display how many characters are left.  It is assumed that you have a basic working knowledge of Oracle Forms

If you find bugs with the supplied form or code, please let me know.

1.      Open Forms Builder and log into any database.
2.      Open Create a new forms module.
3.      Create a new Canvas and set the following properties in the Property Palette:
a.       Name:  MLINE_COUNTER or leave at default name
b.      Width:   380
c.       Height:  250
4.      Create a new “Non-Base table” data block (do not use the Data Block Wizard to create the block) and change the following block properties in the Property Palette:
a.       Name:   MLINE_COUNTER or leave at default name
b.      Database Data Block:   No
c.       Query Data Source Type:  None
5.      Add three Text-Items to the MLINE_COUNTER block and change the following item properties:
a.       ITEM1
i.       Name:  MLINE_TEXT
ii.      Multi-line:  Yes
iii.     Maximum Length:  500
iv.    Database Item:   No
v.     Visible:  Yes
vi.    Canvas:  MLINE_COUNTER
vii.   X Position:  35
viii.  Y Position:  19
ix.     Width:  310
x.      Height:  127
xi.     Show Vertical Scroll Bar:  Yes
b.      ITEM2
i.       Name:  DSP_TEXT_COUNT
ii.      Item Type:  Display Item
iii.     Maximum Length:  100
iv.     Database Item:  No
v.      Visible:  Yes
vi.     Canvas:  MLINE_COUNTER
vii.    X Position:  96
viii.   Y Position:  150
ix.     Width:  188
x.      Height:  14
xi.     Bevel:  None
c.       ITEM3  (This item is not required, but was used during development to prove the concept.  You can skip this step if you want.)
i.        Name:  BTN_COUNT_TEXT
ii.       Item Type:  Push Button
iii.      Label:  Count
iv.     Canvas:  MLINE_COUNTER
v.      X Position:  156
vi.     Y Position:  174
vii.    Width:  68
viii.   Height:  16
6.      Now we will add three Program Units to encapsulate the code for the counting process.  Again, it is assumed that you familiar enough with Oracle Forms to add a program unit to the Program Units node in the Object Navigator.
a.       GET_ITEM_COUNT_F (Function)
i.      Program Unit Text:

FUNCTION get_item_count_f (p_block_item VARCHAR2) RETURN VARCHAR2 IS
      nCount      NUMBER := 0;     
      nItmSize    NUMBER := 0;
      nRemaining  NUMBER := 0;
      vRetVal     VARCHAR2(100);
     
BEGIN
      nItmSize := Get_Item_Property(p_block_item, MAX_LENGTH);
      nCount := length(NAME_IN(p_block_item));
      nRemaining := nItmSize - nvl(nCount,0);
      vRetVal := 'Remaining: '||nRemaining||' of '||nItmSize;
      RETURN vRetVal;
END;

b.      MYTIMER (Package Specification)
i.      Program Unit Text:

PACKAGE MyTimer IS
      tID               TIMER;     
      v_block_item      VARCHAR2(61);

  PROCEDURE SET_TIMER (p_item  VARCHAR2);
  PROCEDURE DEL_TIMER (p_item VARCHAR2);
END;

c.       MYTIMER (Package Body)
i.      Program Unit Text:

PACKAGE BODY MyTimer IS
  -- The value passed to this procedure should be the value of
  -- :SYSTEM.CURSOR_ITEM (if Forms version 6i, use
  -- :SYSTEM.CURRENT_ITEM)
  PROCEDURE SET_TIMER (p_item  VARCHAR2) AS
  BEGIN
      IF ( p_item = v_block_item ) THEN 
            -- tID is a Package level Variable
            tID := Create_Timer('MLINE_TEXT',1000,REPEAT);

      -- These ELSIF statements are here only to demonstrate
      -- how you can extend this procedure to support multiple items
      -- in a Form that you use this method on.  They can be excluded
      -- if you do not want to include them.
      ELSIF ( p_item = 'BLOCK2.Item2' ) THEN
            tID := Create_Timer('ITEM2',1000,REPEAT);
      ELSIF ( p_item = 'BLOCK2.Item3' ) THEN
            tID := Create_Timer('ITEM3',1000,REPEAT);            
      END IF;
  END SET_TIMER;

  PROCEDURE DEL_TIMER (p_item VARCHAR2) AS
  BEGIN
      IF ( p_item = v_block_item ) THEN 
            -- tID is a Package level Variable
            Delete_Timer('MLINE_TEXT');
      ELSIF ( p_item = 'BLOCK2.Item2' ) THEN
            Delete_Timer('ITEM2');
      ELSIF ( p_item = 'BLOCK2.Item3' ) THEN
            Delete_Timer('ITEM3');             
      END IF;
  END DEL_TIMER;
END;


7.      Create a Form level When-Timer-Expired trigger and add the following Trigger Text:

DECLARE
   vTimer   VARCHAR2(30) := Get_Application_Property(TIMER_NAME);
BEGIN
   IF ( vTimer = 'COUNTER' ) THEN
      :MLINE_COUNTER.DSP_TEXT_COUNT :=
             get_item_count_f(:SYSTEM.CURSOR_ITEM);        
   END IF
END;


At this point, your form should look similar to the following:


 
You are now ready to compile and run your form.  It is assumed that you are familiar enough with Oracle Forms to configure your installation to allow running Form locally.  For Forms 6i, this is quite simple as the form will run in Client/Server mode Forms Runtime.  If you are using Oracle Forms 9i or higher then you will need to configure your Forms installation to enable running a form from your developer installation of Oracle Forms.  How to configure forms to run locally is covered in a separate document.  You could also deploy this form to a Development environment to test.

Run the form and as you type, your form should look similar to the following:


Attachments (2)