السلام عليكم ورحمه الله وبركاته
اخواني واخواتي الاعزاء
انا جايب ليكم انهارده درس ازاي نعمل tree معقده من اكتر من جدول
انا عن نفسي الموضوع ده اتطلب مني في الشغل اني اعمل تري على اربع جدوال فكرت وعمتلها وخدت مني وقت اربع تيام
وقلت ارفع ليكم الفكره عشان الكل يستفاد منها ان شاء الله
بسم الله الرحمن نبدا
هنستخدم في الشرح جدول وانت قيس بقى لو انت عايز تزود عدد الجدول بس الفكره واضحه ان شاء الله
جدول الموظفين EMPLOYEES و جدول الادارات DEPARTMENTS
الفكره بكل بساطه عايز الادرات تظهر افتح الادراه تظهر كل الموظفين الى فيها
اتنين كليك على الموظف تنزل بياناته كلها رقم الارده وسام الادراه وبياناته الباقيه
انا كانت مطلوبه مني على اربع جدوال
مباني
اقسام
حجرات
سراير
المبنى يفتح ينزل منه اقسامه يفتح القسم تنزل الحجرات الى فيه الحجرات تفتح ينزل السراير الى في الحجره اتنين كلك على السرير يقولكمين المريض الى على السرير
لو قولنا ان ده جدول الادرات
[TABLE="width: 6"]
[TR]
[TD="width: 238"]DEPARTMENT_NAME[/TD]
[TD="width: 160"]NODE_ID[/TD]
[TD="width: 193"]PARENT_NODE_ID[/TD]
[/TR]
[TR]
[TD="width: 238"]Accounting[/TD]
[TD="width: 160"]1[/TD]
[TD="width: 193"]0[/TD]
[/TR]
[TR]
[TD="width: 238"]Administration[/TD]
[TD="width: 160"]2[/TD]
[TD="width: 193"]0[/TD]
[/TR]
[TR]
[TD="width: 238"]Benefits[/TD]
[TD="width: 160"]3[/TD]
[TD="width: 193"]0[/TD]
[/TR]
[TR]
[TD="width: 238"]Construction[/TD]
[TD="width: 160"]4[/TD]
[TD="width: 193"]0[/TD]
[/TR]
[TR]
[TD="width: 238"]Etc…..[/TD]
[TD="width: 160"][/TD]
[TD="width: 193"][/TD]
[/TR]
[/TABLE]
وده جدول الموظفين[TABLE]
[TR]
[TD]DEPARTMENT_NAME[/TD]
[TD]LAST_NAME[/TD]
[TD="width: 125"]NODE_ID[/TD]
[TD="width: 154"]PARENT_NODE_ID[/TD]
[/TR]
[TR]
[TD="width: 177"]Accounting[/TD]
[TD="width: 134"][/TD]
[TD="width: 125"]1[/TD]
[TD="width: 154"]0[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"]Higgins[/TD]
[TD="width: 125"]2[/TD]
[TD="width: 154"]1[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"]Gietz[/TD]
[TD="width: 125"]3[/TD]
[TD="width: 154"]1[/TD]
[/TR]
[TR]
[TD="width: 177"]Administration[/TD]
[TD="width: 134"][/TD]
[TD="width: 125"]4[/TD]
[TD="width: 154"]0[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"]Whalen[/TD]
[TD="width: 125"]5[/TD]
[TD="width: 154"]4[/TD]
[/TR]
[TR]
[TD="width: 177"]Executive[/TD]
[TD="width: 134"][/TD]
[TD="width: 125"]6[/TD]
[TD="width: 154"]0[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"]King[/TD]
[TD="width: 125"]7[/TD]
[TD="width: 154"]6[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"]Kochhar[/TD]
[TD="width: 125"]8[/TD]
[TD="width: 154"]6[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"]De Haan[/TD]
[TD="width: 125"]9[/TD]
[TD="width: 154"]6[/TD]
[/TR]
[TR]
[TD="width: 177"]Finance[/TD]
[TD="width: 134"][/TD]
[TD="width: 125"]10[/TD]
[TD="width: 154"]0[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"][/TD]
[TD="width: 125"][/TD]
[TD="width: 154"][/TD]
[/TR]
[/TABLE]
الفكره كلها منحصره في الحاجات دي
Let’s Get Started
* افتح الفورم بليدر وانشى مديول جيدخلى اسمه HIERACHY_TREE
*احفظ مشروع واعمل كومبيل
* هنعمل Create a new Program Unit,
اسمها TREE_CONTROL واختار Package Spec يبقى احنا كده عملنا باكيدج
هنتكب الكود ده فيها
تعالو نشرح الكود
طبعا في الاول عرفت شويه متغيرات ومكتوب كومنت عليها
نيجي من اول الفاكنشن
دي فاكنشن بتاخد برماتير وبترج ريكورد جورب
ده برويسجور بيقوم بملىء الريكورد جورب زي ما احنا عارفين ان التري جملت السكلت بتاعتها لازم بتجيب 5 حاجات
ده بيروسجور يفتح التري مره واحده
بروسجيور يقفل التري كلها
برويسجور يقفل نود نود
بروسيجور لم اختار قيمه من النود
برويريجسور لم يعمل اكتف للنود
بروسجور لم يعمل سيرش على التري
نعمل باكديج بدي بقى او نعرف الاكواد بتاعتنا
الخطوه التاليه
Create a new Program Unit, name it TREE_CONTROL and select Package Body as the program unit type.
ونكتب الكود الجميل ده
طبعا الكود كبير وانا حاولت على اقد ما اقدر اعمل كومنتات في الكود هشان تفهموا الدنيا الى مش فاهم جئيه في الكود يكتبها في كومنت وانا اشرحها
كده طبعا احنا عملنا الباكيدج كامله الجزء التعريفي في الدرس الى فات والجزء البدي بتاع الباكديج
نعمل همنعل كانفس جديد
ونقف عليك كليك يمين نغير الخصائص بتاعته ونخليها كده
(1) Name: TREE
(2) Canvas Type: Content (should be the default value)
(3) Window: WINDOW1 (should automatically be created with the new Forms Module)
(4) Width: 540
(5) Height: 324
نضغط على f2 او كليك يمن على الكانفس select the Layout Editor
نختار الاكيونه بتاع الترير من التول بار
ارسمها على الكانفس واتتين كلك عليها عشان نغير في خصائصها
(1) Name: MY_TREE
(2) Canvas: Tree (should already be set)
(3) X Position: 15
(4) Y Position: 23
(5) Width: 205
(6) Height: 278
نمقف على البلوك الى اتعمل ونغير خضائضه
(1) Name: MY_TREE_DATA
(2) Database Data Block: No
الان وصلنا لمرحله اننا نعمل ريكرود جورب ونعلمى التري
) Now it is time to build a Record Group and use this to populate the Tree.
a) Create a Form level When-New-Form-Instance trigger and add the following code
DECLARE
CURSOR c_dept IS
SELECT *
FROM hr.departments;
CURSOR c_emp ( n_dept NUMBER ) IS
SELECT *
FROM hr.employees
WHERE department_id = n_dept;
n_level NUMBER := 1;
n_row NUMBER := 1;
rg_id RecordGroup;
node Ftree.Node;
BEGIN
Tree_Control.v_item_name := 'MY_TREE_DATA.MY_TREE';
rg_id := Tree_Control.Create_RG;
<<parent>>
FOR r_dept IN c_dept LOOP
-- Add Parent Department_ID
Tree_Control.ADD_RG_ROW(rg_id, ftree.collapsed_node, n_row, n_level, r_dept.department_name, null, r_dept.department_id);
n_row := n_row + 1;
n_level := n_level + 1;
--Add Child Employee Records
<<child>>
FOR r_emp IN c_emp(r_dept.department_id) LOOP
Tree_Control.ADD_RG_ROW(rg_id, ftree.collapsed_node, n_row, n_level, r_emp.last_name, NULL, r_emp.employee_id);
n_row := n_row + 1;
END LOOP child;
n_level := n_level - 1;
END LOOP parent;
ftree.Add_Tree_Data(Tree_Control.v_item_name, ftree.ROOT_NODE, ftree.PARENT_OFFSET, ftree.LAST_CHILD, ftree.RECORD_GROUP, rg_id);
END;
At this point you should be able to run your form to confirm the Tree is populated. Your form should look similar to the following:
Now, let’s add the code to expand and collapse all tree nodes.
a) Create a new data block and set the following properties:
i) Name: CONTROL
ii) Database Data Block: No
Add two new items to the CONTROL block. These items are going to be the Expand All and Collapse All buttons.
c) Select the first item and set the following properties in the property palette:
i) Name: BTN_EXPAND_ALL
ii) Item Type: Push Button
iii) Label: >>
iv) Canvas: TREE
v) X Position: 2
vi) Y Position: 4
vii) Width: 18
viii) Height: 18
ix) Tooltip: Expand All Nodes
d) Select the second item added and set the following properties in the property palette:
i) Name: BTN_COLLAPSE_ALL
ii) Item Type: Push Button
iii) Label: <<
iv) Canvas: TREE
v) X Position: 214
vi) Y Position: 4
vii) Width: 18
viii) Height: 18
ix) Tooltip: Collapse All Nodes
e) Select the BTN_EXPAND_ALL item and add a When-Button-Pressed trigger with the following code:
Select the BTN_COLLAPSE_ALL item and add a When-Button-Pressed trigger with the following code:
Let run the form and test your code. Your form should look similar to the following:
Now we will add the Expand One and Collapse One buttons.
i) Add two more items between BTN_EXPAND_ALL and BTN_COLLASPE_ALL buttons in the CONTROL block.
j) Select the new item that follows the BTN_EXPAND_ALL button and set the following properties in the property palette:
i) Name: BTN_EXPAND_ONE
ii) Item Type: Push Button
iii) Label: >
iv) Canvas: TREE
v) X Position: 21
vi) Y Position: 4
vii) Width: 18
viii) Height: 18
ix) Tooltip: Expand selected node
x) Add a When-Button Pressed trigger with the following code:
Select the next newly added item and set the following properties in the property palette:
i) Name: BTN_COLLAPSE_ONE
ii) Item Type: Push Button
iii) Label: <
iv) Canvas: TREE
v) X Position: 195
vi) Y Position: 4
vii) Width: 18
viii) Height: 18
ix) Tooltip: Collapse selected node
x) Add a When-Button Pressed trigger with the following code:
From the Object Navigator, select the MY_TREE_DATA block and expand the MY_TREE item and add the following triggers and code:
i) When-Tree-Node-Selected
When-Tree-Node-Activated
Run the form and let’s test what we’ve added. Select a node of the tree and click the Expand One and Collapse One buttons. Your form should look similar to the following:
اخواني واخواتي الاعزاء
انا جايب ليكم انهارده درس ازاي نعمل tree معقده من اكتر من جدول
انا عن نفسي الموضوع ده اتطلب مني في الشغل اني اعمل تري على اربع جدوال فكرت وعمتلها وخدت مني وقت اربع تيام
وقلت ارفع ليكم الفكره عشان الكل يستفاد منها ان شاء الله
بسم الله الرحمن نبدا
هنستخدم في الشرح جدول وانت قيس بقى لو انت عايز تزود عدد الجدول بس الفكره واضحه ان شاء الله
جدول الموظفين EMPLOYEES و جدول الادارات DEPARTMENTS
الفكره بكل بساطه عايز الادرات تظهر افتح الادراه تظهر كل الموظفين الى فيها
اتنين كليك على الموظف تنزل بياناته كلها رقم الارده وسام الادراه وبياناته الباقيه
انا كانت مطلوبه مني على اربع جدوال
مباني
اقسام
حجرات
سراير
المبنى يفتح ينزل منه اقسامه يفتح القسم تنزل الحجرات الى فيه الحجرات تفتح ينزل السراير الى في الحجره اتنين كلك على السرير يقولكمين المريض الى على السرير
لو قولنا ان ده جدول الادرات
[TABLE="width: 6"]
[TR]
[TD="width: 238"]DEPARTMENT_NAME[/TD]
[TD="width: 160"]NODE_ID[/TD]
[TD="width: 193"]PARENT_NODE_ID[/TD]
[/TR]
[TR]
[TD="width: 238"]Accounting[/TD]
[TD="width: 160"]1[/TD]
[TD="width: 193"]0[/TD]
[/TR]
[TR]
[TD="width: 238"]Administration[/TD]
[TD="width: 160"]2[/TD]
[TD="width: 193"]0[/TD]
[/TR]
[TR]
[TD="width: 238"]Benefits[/TD]
[TD="width: 160"]3[/TD]
[TD="width: 193"]0[/TD]
[/TR]
[TR]
[TD="width: 238"]Construction[/TD]
[TD="width: 160"]4[/TD]
[TD="width: 193"]0[/TD]
[/TR]
[TR]
[TD="width: 238"]Etc…..[/TD]
[TD="width: 160"][/TD]
[TD="width: 193"][/TD]
[/TR]
[/TABLE]
وده جدول الموظفين[TABLE]
[TR]
[TD]DEPARTMENT_NAME[/TD]
[TD]LAST_NAME[/TD]
[TD="width: 125"]NODE_ID[/TD]
[TD="width: 154"]PARENT_NODE_ID[/TD]
[/TR]
[TR]
[TD="width: 177"]Accounting[/TD]
[TD="width: 134"][/TD]
[TD="width: 125"]1[/TD]
[TD="width: 154"]0[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"]Higgins[/TD]
[TD="width: 125"]2[/TD]
[TD="width: 154"]1[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"]Gietz[/TD]
[TD="width: 125"]3[/TD]
[TD="width: 154"]1[/TD]
[/TR]
[TR]
[TD="width: 177"]Administration[/TD]
[TD="width: 134"][/TD]
[TD="width: 125"]4[/TD]
[TD="width: 154"]0[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"]Whalen[/TD]
[TD="width: 125"]5[/TD]
[TD="width: 154"]4[/TD]
[/TR]
[TR]
[TD="width: 177"]Executive[/TD]
[TD="width: 134"][/TD]
[TD="width: 125"]6[/TD]
[TD="width: 154"]0[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"]King[/TD]
[TD="width: 125"]7[/TD]
[TD="width: 154"]6[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"]Kochhar[/TD]
[TD="width: 125"]8[/TD]
[TD="width: 154"]6[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"]De Haan[/TD]
[TD="width: 125"]9[/TD]
[TD="width: 154"]6[/TD]
[/TR]
[TR]
[TD="width: 177"]Finance[/TD]
[TD="width: 134"][/TD]
[TD="width: 125"]10[/TD]
[TD="width: 154"]0[/TD]
[/TR]
[TR]
[TD="width: 177"][/TD]
[TD="width: 134"][/TD]
[TD="width: 125"][/TD]
[TD="width: 154"][/TD]
[/TR]
[/TABLE]
الفكره كلها منحصره في الحاجات دي
- (ملىء الشجره)Populate the tree
- Programmatically expand and collapse a single tree node(فتح وقفل الشرجه عن طريق زراير)
- Programmatically expand and collapse all tree nodes.(وفتح وقفل الشجر كلها )
- How to search for a value in the tree and how to search for subsequent instances of a specified search value.(ازاي ابحث في الشجره)
- How to select a value from a tree node and use this to filter records in a different data block.(واختار قيمه تنزل بيناتها)
Let’s Get Started
* افتح الفورم بليدر وانشى مديول جيدخلى اسمه HIERACHY_TREE
*احفظ مشروع واعمل كومبيل
* هنعمل Create a new Program Unit,
اسمها TREE_CONTROL واختار Package Spec يبقى احنا كده عملنا باكيدج
هنتكب الكود ده فيها
PACKAGE tree_control IS -- Package Variables -- -- These Variables are used by supporting Triggers and -- package methods. -- -------------------------------------------------- -- The Block and Item Name of the Tree Control widget v_item_name VARCHAR2(61); -- The current and previously selected node's parent node ID n_curr_parent_node Ftree.NODE; n_prev_parent_node Ftree.NODE; -- The current and previously select node's ID n_curr_node Ftree.NODE := 0; n_prev_node Ftree.NODE; -- The current and previously selected node's label v_curr_label VARCHAR2(60); v_prev_label VARCHAR2(60); -- The currnet and previously selected node's value v_curr_value VARCHAR2(256); v_prev_value VARCHAR2(256); FUNCTION Create_RG (p_rg_name VARCHAR2 DEFAULT 'TREE_GROUP') RETURN RecordGroup; PROCEDURE ADD_RG_ROW (rg_id RECORDGROUP, n_state NUMBER, n_row NUMBER, n_level NUMBER, v_label VARCHAR2, v_icon VARCHAR2, v_data VARCHAR2); PROCEDURE EXPAND_ALL (p_tree VARCHAR2); PROCEDURE EXPAND_ONE (p_tree VARCHAR2); PROCEDURE COLLAPSE_ALL (p_tree VARCHAR2); PROCEDURE COLLAPSE_ONE (p_tree VARCHAR2); PROCEDURE Node_Selected; PROCEDURE Node_Activated; PROCEDURE Find_Node(p_value VARCHAR2, p_start_node NUMBER DEFAULT 0); p_start_node NUMBER DEFAULT 0); END;
تعالو نشرح الكود
طبعا في الاول عرفت شويه متغيرات ومكتوب كومنت عليها
نيجي من اول الفاكنشن
FUNCTION Create_RG (p_rg_name VARCHAR2 DEFAULT 'TREE_GROUP') RETURN RecordGroup;
دي فاكنشن بتاخد برماتير وبترج ريكورد جورب
PROCEDURE ADD_RG_ROW (rg_id RECORDGROUP, n_state NUMBER, n_row NUMBER, n_level NUMBER, v_label VARCHAR2, v_icon VARCHAR2, v_data VARCHAR2);
ده برويسجور بيقوم بملىء الريكورد جورب زي ما احنا عارفين ان التري جملت السكلت بتاعتها لازم بتجيب 5 حاجات
select 1 ,level ,<label_name>,<icon_name>,<value> from table_name
PROCEDURE EXPAND_ALL (p_tree VARCHAR2);
ده بيروسجور يفتح التري مره واحده
PROCEDURE EXPAND_ONE (p_tree VARCHAR2);ده بريجسور بيفتح نود نود
PROCEDURE COLLAPSE_ALL (p_tree VARCHAR2);
بروسجيور يقفل التري كلها
PROCEDURE COLLAPSE_ONE (p_tree VARCHAR2);
برويسجور يقفل نود نود
PROCEDURE Node_Selected;
بروسيجور لم اختار قيمه من النود
PROCEDURE Node_Activated;
برويريجسور لم يعمل اكتف للنود
PROCEDURE Find_Node(p_value VARCHAR2, p_start_node NUMBER DEFAULT 0);
بروسجور لم يعمل سيرش على التري
نعمل باكديج بدي بقى او نعرف الاكواد بتاعتنا
الخطوه التاليه
Create a new Program Unit, name it TREE_CONTROL and select Package Body as the program unit type.
ونكتب الكود الجميل ده
PACKAGE BODY tree_control IS -- Create_RG -- Creates an Instance of a Record Group -- --------------------------------------- FUNCTION Create_RG (p_rg_name VARCHAR2 DEFAULT 'TREE_GROUP') RETURN RecordGroup IS rg_id RecordGroup; gc_id GroupColumn; BEGIN rg_id := Find_Group(p_rg_name); -- Make sure the RG doesn't already exist. IF ( NOT Id_NULL(rg_id) ) THEN Delete_Group(rg_id); END IF; IF ( Id_NULL(rg_id) ) THEN rg_id := Create_Group(p_rg_name); -- Initial state. gc_id := Add_Group_Column(rg_id, 'state', NUMBER_COLUMN); -- Add Node Tree Dept gc_id := Add_Group_Column(rg_id, 'dept', NUMBER_COLUMN); -- Label gc_id := Add_Group_Column(rg_id, 'label', CHAR_COLUMN,50); -- Icon gc_id := Add_Group_Column(rg_id, 'icon', CHAR_COLUMN,10); -- Data gc_id := Add_Group_Column(rg_id, 'data', CHAR_COLUMN,50); END IF; RETURN rg_id; END Create_RG; -- ADD_RECORD -- Adds a record to the Record Group -- --------------------------------------- PROCEDURE ADD_RG_ROW ( rg_id RECORDGROUP, n_state NUMBER, n_row NUMBER, n_level NUMBER, v_label VARCHAR2, v_icon VARCHAR2, v_data VARCHAR2) AS BEGIN Add_Group_Row(rg_id, END_OF_GROUP); Set_Group_Number_Cell('Tree_Group.state', n_row, n_state); Set_Group_Number_Cell('Tree_Group.dept', n_row, n_level); Set_Group_Char_Cell('Tree_Group.label', n_row, v_label); Set_Group_Char_Cell('Tree_Group.icon', n_row, v_icon); Set_Group_Char_Cell('Tree_Group.data', n_row, v_data); END ADD_RG_ROW; -- EXPAND_ALL -- Starting from the ROOT node, this procedure will -- Expand all nodes of a tree. -- PARAMETERS: -- p_tree - Name of the Tree Control object. -- --------------------------------------- PROCEDURE expand_all ( p_tree VARCHAR2 ) IS n_node ftree.NODE; i_tree ITEM; v_state VARCHAR2(30); BEGIN -- Find the Tree Item i_tree := Find_Item(p_tree); -- Find the ROOT Node of the tree n_node := Ftree.Find_Tree_Node(i_tree, ''); --LOOP through all of the nodes and expand each one --if it is collapsed <<expand_tree>> WHILE NOT Ftree.ID_NULL(n_node) LOOP v_state := Ftree.Get_Tree_Node_Property(i_tree, n_node, Ftree.NODE_STATE); IF ( v_state = Ftree.COLLAPSED_NODE ) THEN Ftree.Set_Tree_Node_Property(i_tree, n_node, Ftree.NODE_STATE, Ftree.EXPANDED_NODE); END IF; n_node := Ftree.Find_Tree_Node(i_tree, '', Ftree.Find_Next, Ftree.NODE_LABEL, '',n_node); END LOOP expand_tree; END expand_all; -- EXPAND_ONE -- Starting from the ROOT node, this procedure will -- Expand all nodes of a tree. -- PARAMETERS: -- p_tree - Name of the Tree Control object. -- --------------------------------------- PROCEDURE EXPAND_ONE (p_tree VARCHAR2) IS v_state VARCHAR2(30); i_tree ITEM; BEGIN -- Find the Tree Item i_tree := Find_Item(p_tree); v_state := Ftree.Get_Tree_Node_Property(i_tree, n_curr_node, Ftree.NODE_STATE); IF ( v_state = Ftree.COLLAPSED_NODE ) THEN Ftree.Set_Tree_Node_Property(i_tree, n_curr_node, Ftree.NODE_STATE, Ftree.EXPANDED_NODE); END IF; END EXPAND_ONE; -- COLLAPSE_ALL -- Starting from the ROOT node, this procedure will -- Collapse all nodes of a tree. -- PARAMETERS: -- p_tree - Name of the Tree Control object. -- --------------------------------------- PROCEDURE collapse_all ( p_tree VARCHAR2 ) IS n_node Ftree.NODE; i_tree ITEM; v_state VARCHAR2(30); BEGIN -- Find the Tree Item i_tree := Find_Item(p_tree); -- Find the root node n_node := Ftree.Find_Tree_Node(i_Tree, ''); -- Loop through all of the nodes and collapse if expanded. <<collapse_tree>> WHILE ( NOT Ftree.ID_NULL(n_node) ) LOOP v_state := Ftree.Get_Tree_Node_Property(i_tree, n_node, Ftree.NODE_STATE); IF ( v_state = Ftree.EXPANDED_NODE ) THEN Ftree.Set_Tree_Node_Property(i_tree, n_node, Ftree.NODE_STATE, Ftree.COLLAPSED_NODE); END IF; n_node := Ftree.Find_Tree_Node(i_tree, '', Ftree.FIND_NEXT, Ftree.NODE_LABEL, '', n_node); END LOOP collapse_tree; END collapse_all; -- COLLAPSE_ONE -- Starting from the ROOT node, this procedure will -- Expand all nodes of a tree. -- PARAMETERS: -- p_tree - Name of the Tree Control object. -- --------------------------------------- PROCEDURE COLLAPSE_ONE (p_tree VARCHAR2) IS v_state VARCHAR2(30); i_tree ITEM; BEGIN -- Find the Tree Item i_tree := Find_Item(p_tree); v_state := Ftree.Get_Tree_Node_Property(i_tree, n_curr_node, Ftree.NODE_STATE); IF ( v_state = Ftree.EXPANDED_NODE ) THEN Ftree.Set_Tree_Node_Property(i_tree, n_curr_node, Ftree.NODE_STATE, Ftree.COLLAPSED_NODE); END IF; END COLLAPSE_ONE; -- NODE_SELECTED -- Used in When-Tree-Node-Selected trigger to capture -- the Current Node, Current Parent Node, Current Node Label, -- Prev Node, Prev Parent Node, and Prev Node Label. -- -------------------------------------------- PROCEDURE Node_Selected IS BEGIN IF ( :SYSTEM.Trigger_Node_SELECTED = 'TRUE' ) THEN n_curr_node := :SYSTEM.Trigger_Node; n_curr_parent_node := Ftree.Get_Tree_Node_Parent( v_item_name, :SYSTEM.Trigger_Node); v_curr_label := Ftree.Get_Tree_Node_Property( v_item_name,:SYSTEM.Trigger_Node, Ftree.NODE_LABEL); ELSE n_prev_node := :SYSTEM.Trigger_Node; n_prev_parent_node := Ftree.Get_Tree_Node_Parent( v_item_name,:SYSTEM.Trigger_Node); v_prev_label := Tree_Control.v_curr_label; END IF; END Node_Selected; -- NODE_ACTIVATED -- Used in the When-Tree-Node-Activated trigger -- to capture the NODE_VALUE of the selected node. -- ------------------------------------------- PROCEDURE Node_Activated IS BEGIN IF ( v_curr_value IS NOT NULL ) THEN v_prev_value := v_curr_value; END IF; v_curr_value := Ftree.Get_Tree_Node_Property( v_item_name,n_curr_node, Ftree.NODE_VALUE); END Node_Activated; -- FIND_NODE -- Called by a User defined button to search the -- tree for a value. If a value is in the tree more than once, -- calling the FIND_NODE a subsequent time will find the next -- occurance of the value specified in P_VALUE. -- Parameters: -- p_value - the value you are searching for -- p_start_node - defaults to 0 (zero). If specified, -- the search will begin at this node -- location, else it starts at the ROOT node. -- ------------------------------------------- PROCEDURE find_node (p_value VARCHAR2, p_start_node NUMBER DEFAULT 0) IS htree ITEM; found_node FTREE.node; BEGIN htree := Find_Item(Tree_Control.v_item_name); IF ( p_start_node = 0 ) THEN found_node := Ftree.Find_Tree_Node(htree ,p_value ,Ftree.FIND_NEXT ,Ftree.NODE_LABEL ,Ftree.ROOT_NODE ,Ftree.ROOT_NODE); ELSE found_node := Ftree.Find_Tree_Node(htree ,p_value ,Ftree.FIND_NEXT ,Ftree.NODE_LABEL ,Ftree.ROOT_NODE ,p_start_node); END IF; IF ( NOT Ftree.ID_NULL(found_node) ) THEN Clear_Message; Message('Value: "'||p_value||'" found'); n_curr_node := found_node; Ftree.Set_Tree_Selection(htree, found_node, Ftree.SELECT_ON); ELSE Clear_Message; Message('Value: "'||p_value|| '" not found. Please try again.'); END IF; EXCEPTION WHEN OTHERS THEN Clear_Message; Message('Value: "'||p_value|| '" not found. Please try again.'); Message(' '); END Find_Node; END;
طبعا الكود كبير وانا حاولت على اقد ما اقدر اعمل كومنتات في الكود هشان تفهموا الدنيا الى مش فاهم جئيه في الكود يكتبها في كومنت وانا اشرحها
كده طبعا احنا عملنا الباكيدج كامله الجزء التعريفي في الدرس الى فات والجزء البدي بتاع الباكديج
نعمل همنعل كانفس جديد
ونقف عليك كليك يمين نغير الخصائص بتاعته ونخليها كده
(1) Name: TREE
(2) Canvas Type: Content (should be the default value)
(3) Window: WINDOW1 (should automatically be created with the new Forms Module)
(4) Width: 540
(5) Height: 324
نضغط على f2 او كليك يمن على الكانفس select the Layout Editor
نختار الاكيونه بتاع الترير من التول بار
ارسمها على الكانفس واتتين كلك عليها عشان نغير في خصائصها
(1) Name: MY_TREE
(2) Canvas: Tree (should already be set)
(3) X Position: 15
(4) Y Position: 23
(5) Width: 205
(6) Height: 278
نمقف على البلوك الى اتعمل ونغير خضائضه
(1) Name: MY_TREE_DATA
(2) Database Data Block: No
الان وصلنا لمرحله اننا نعمل ريكرود جورب ونعلمى التري
) Now it is time to build a Record Group and use this to populate the Tree.
a) Create a Form level When-New-Form-Instance trigger and add the following code
DECLARE
CURSOR c_dept IS
SELECT *
FROM hr.departments;
CURSOR c_emp ( n_dept NUMBER ) IS
SELECT *
FROM hr.employees
WHERE department_id = n_dept;
n_level NUMBER := 1;
n_row NUMBER := 1;
rg_id RecordGroup;
node Ftree.Node;
BEGIN
Tree_Control.v_item_name := 'MY_TREE_DATA.MY_TREE';
rg_id := Tree_Control.Create_RG;
<<parent>>
FOR r_dept IN c_dept LOOP
-- Add Parent Department_ID
Tree_Control.ADD_RG_ROW(rg_id, ftree.collapsed_node, n_row, n_level, r_dept.department_name, null, r_dept.department_id);
n_row := n_row + 1;
n_level := n_level + 1;
--Add Child Employee Records
<<child>>
FOR r_emp IN c_emp(r_dept.department_id) LOOP
Tree_Control.ADD_RG_ROW(rg_id, ftree.collapsed_node, n_row, n_level, r_emp.last_name, NULL, r_emp.employee_id);
n_row := n_row + 1;
END LOOP child;
n_level := n_level - 1;
END LOOP parent;
ftree.Add_Tree_Data(Tree_Control.v_item_name, ftree.ROOT_NODE, ftree.PARENT_OFFSET, ftree.LAST_CHILD, ftree.RECORD_GROUP, rg_id);
END;
At this point you should be able to run your form to confirm the Tree is populated. Your form should look similar to the following:
Now, let’s add the code to expand and collapse all tree nodes.
a) Create a new data block and set the following properties:
i) Name: CONTROL
ii) Database Data Block: No
c) Select the first item and set the following properties in the property palette:
i) Name: BTN_EXPAND_ALL
ii) Item Type: Push Button
iii) Label: >>
iv) Canvas: TREE
v) X Position: 2
vi) Y Position: 4
vii) Width: 18
viii) Height: 18
ix) Tooltip: Expand All Nodes
d) Select the second item added and set the following properties in the property palette:
i) Name: BTN_COLLAPSE_ALL
ii) Item Type: Push Button
iii) Label: <<
iv) Canvas: TREE
v) X Position: 214
vi) Y Position: 4
vii) Width: 18
viii) Height: 18
ix) Tooltip: Collapse All Nodes
e) Select the BTN_EXPAND_ALL item and add a When-Button-Pressed trigger with the following code:
Tree_Control.Expand_all(Tree_Control.v_item_name);
Select the BTN_COLLAPSE_ALL item and add a When-Button-Pressed trigger with the following code:
Tree_Control.Collapse_all(Tree_Control.v_item_name);
Let run the form and test your code. Your form should look similar to the following:
Now we will add the Expand One and Collapse One buttons.
i) Add two more items between BTN_EXPAND_ALL and BTN_COLLASPE_ALL buttons in the CONTROL block.
j) Select the new item that follows the BTN_EXPAND_ALL button and set the following properties in the property palette:
i) Name: BTN_EXPAND_ONE
ii) Item Type: Push Button
iii) Label: >
iv) Canvas: TREE
v) X Position: 21
vi) Y Position: 4
vii) Width: 18
viii) Height: 18
ix) Tooltip: Expand selected node
x) Add a When-Button Pressed trigger with the following code:
Tree_Control.EXPAND_ONE(Tree_Control.v_item_name);
Select the next newly added item and set the following properties in the property palette:
i) Name: BTN_COLLAPSE_ONE
ii) Item Type: Push Button
iii) Label: <
iv) Canvas: TREE
v) X Position: 195
vi) Y Position: 4
vii) Width: 18
viii) Height: 18
ix) Tooltip: Collapse selected node
x) Add a When-Button Pressed trigger with the following code:
Tree_Control.COLLAPSE_ONE(Tree_Control.v_item_name);
From the Object Navigator, select the MY_TREE_DATA block and expand the MY_TREE item and add the following triggers and code:
i) When-Tree-Node-Selected
Tree_Control.Node_Selected;
When-Tree-Node-Activated
Tree_Control.Node_Activated;
Run the form and let’s test what we’ve added. Select a node of the tree and click the Expand One and Collapse One buttons. Your form should look similar to the following:
Now, let’s add the ability to search the tree. Note; Values in the tree are case sensitive with respects to how the data is stored in the table.
o) Click on the CONTROL.BTN_EXPAND_ONE item and add two new items.
p) Click on the first new item and set the following properties:
i) Name: FIND_NAME
ii) Item Type: Text Item (default value)
iii) Maximum Length: 60
iv) Canvas: TREE
v) X Position: 43
vi) Y Position: 6
vii) Width: 85
viii) Height: 14
ix) Tooltip: Enter a name to search for
q) Select the next new item and set the following properties:
i) Name: BTN_FIND
ii) Item Type: Push Button
iii) Label: Find
iv) Access Key: d
v) Canvas: TREE
vi) X Position: 129
vii) Y Position: 4
viii) Width: 30
ix) Height: 18
x) Tooltip: Click to search for the given name
r) Add a When-Button-Pressed trigger with the following code:
Note: the comment in the code. The find function always starts at the currently select tree node. This enables the ability to search and find more than first instance of a given value.
s) Again, let’s run the form to test our changes.
t) In the search field, enter “Smith” and click the find button.
u) Your form should look similar to the following:
7) Now let’s add the final code to select a tree node value and perform an action based on the value. In this example, we will query the Departments and Employees tables.
a) Create two new data blocks using the Data Block Wizard for the HR.DEPARTMENTS and HR.EMPLOYEES tables.
i) For the Departments table, only display the DEPARTMENT_ID and DEPARTMENT_NAME columns.
ii) Allow the data block wizard to call the Layout Wizard and use a “Form” layout versus a “Tabular” layout.
iii) For the EMPLOYEES table, select all columns to be displayed.
iv) Allow the data block wizard to call the Layout Wizard and use a “Form” layout versus a “Tabular” layout.
v) Select the MY_TREE_DATA block, MY_TREE item and add the following triggers and code:
(1) When-Tree-Node-Activated
When-Tree-Node-Selected
Now, let’s run the form and validate everything works correctly. Your form should look similar to the following:
vii) Double-clicking the Purchasing node will populate the Department region. Double-clicking the user Raphaely will populate the Employee region.
This ends this Forms Tree widget demonstration. This demonstration utilizes the many of the functions available to a Tree widget and should sufficiently familiarize you with the use of a tree widget. There are many other Forms Built-in available for the Tree widget. You should now be familiar enough with the use of a Forms Tree widget that you can figure out how to use the remaining Tree built-ins. If you find a bug in this code or have any suggestions, please let me know.
I hope you find this demonstration helpful.
o) Click on the CONTROL.BTN_EXPAND_ONE item and add two new items.
p) Click on the first new item and set the following properties:
i) Name: FIND_NAME
ii) Item Type: Text Item (default value)
iii) Maximum Length: 60
iv) Canvas: TREE
v) X Position: 43
vi) Y Position: 6
vii) Width: 85
viii) Height: 14
ix) Tooltip: Enter a name to search for
q) Select the next new item and set the following properties:
i) Name: BTN_FIND
ii) Item Type: Push Button
iii) Label: Find
iv) Access Key: d
v) Canvas: TREE
vi) X Position: 129
vii) Y Position: 4
viii) Width: 30
ix) Height: 18
x) Tooltip: Click to search for the given name
r) Add a When-Button-Pressed trigger with the following code:
-- Find from Current selected node. Tree_Control.find_node(:CONTROL.Find_Name, Tree_Control.n_curr_node);
Note: the comment in the code. The find function always starts at the currently select tree node. This enables the ability to search and find more than first instance of a given value.
s) Again, let’s run the form to test our changes.
t) In the search field, enter “Smith” and click the find button.
u) Your form should look similar to the following:
7) Now let’s add the final code to select a tree node value and perform an action based on the value. In this example, we will query the Departments and Employees tables.
a) Create two new data blocks using the Data Block Wizard for the HR.DEPARTMENTS and HR.EMPLOYEES tables.
i) For the Departments table, only display the DEPARTMENT_ID and DEPARTMENT_NAME columns.
ii) Allow the data block wizard to call the Layout Wizard and use a “Form” layout versus a “Tabular” layout.
iii) For the EMPLOYEES table, select all columns to be displayed.
iv) Allow the data block wizard to call the Layout Wizard and use a “Form” layout versus a “Tabular” layout.
v) Select the MY_TREE_DATA block, MY_TREE item and add the following triggers and code:
(1) When-Tree-Node-Activated
BEGIN Tree_Control.Node_Activated; IF ( Tree_Control.n_curr_parent_node = 0 ) THEN -- Dept Selected Set_Block_Property('DEPARTMENTS',ONETIME_WHERE, 'DEPARTMENT_ID = '||TO_NUMBER(Tree_Control.v_curr_value)); Go_Block('DEPARTMENTS'); ELSE -- Employee selected. Set_Block_Property('EMPLOYEES',ONETIME_WHERE, 'EMPLOYEE_ID = '|| TO_NUMBER(Tree_Control.v_curr_value)); Go_Block('EMPLOYEES'); END IF; Execute_Query; Go_Item('MY_TREE_DATA.MY_TREE'); END;
When-Tree-Node-Selected
Tree_Control.Node_Selected;
Now, let’s run the form and validate everything works correctly. Your form should look similar to the following:
vii) Double-clicking the Purchasing node will populate the Department region. Double-clicking the user Raphaely will populate the Employee region.
This ends this Forms Tree widget demonstration. This demonstration utilizes the many of the functions available to a Tree widget and should sufficiently familiarize you with the use of a tree widget. There are many other Forms Built-in available for the Tree widget. You should now be familiar enough with the use of a Forms Tree widget that you can figure out how to use the remaining Tree built-ins. If you find a bug in this code or have any suggestions, please let me know.
I hope you find this demonstration helpful.


تعليقات
إرسال تعليق