Webman-framework

Lightweight, Component-based, and Database-oriented Web Application Framework

About | Overview | Documentation

 

Documentation > Modules and APIs > webman_db_item_insert_multirows

webman_db_item_insert_multirows

 

Description:

Multi phases component-type module that provides dynamic control on database table items for multi-rows insert operation.

 

Dependencies:

Webman-framework's Core Modules:

  • Data_HTML_Map (Composition)
  • HTML_DB_Map (Composition)

Webman-framework's Component-type Modules:
  • CGI_Component::webman_CGI_component (Inheritance)
  • webman_link_path_generator (Composition)

 

1. View Template

There are two view template files can be assigned to a single webman_db_item_insert_multirows module. First is an insert form page for items' field entries and the second is a confirmation page for displaying back fields and their values entered before proceed with the insert operation. If there is no second view template assigned to the module the confirmation phase will be skipped.

1.1 Insert Form Page

There are two HTML-forms used with declarations covering lines 6-14, and lines 16-53. The first form is used to change the default number of rows of input-elements used for item field entries. The second form is used to submit the rows of item field values entered for final insert operations. Before and outside of these two HTML-forms, the DYNAMIC_CONTENT template-element (line 4) named link_path will be processed by webman_link_path_generator module inside process_DYNAMIC hook function. It's used as place-holder to render current application's link path when webman_db_item_insert module is called.

Inside the first form there is CGIHTML template-element (lines 8-10) contains an input-elements named link_id and irn_param_name. Both have their values set via CGI parameters which names are identical with the names of input-elements themselves. Read CGI_HTML_Map core module documentation for details how these CGI parameters are mapped to their place-holders inside the CGIHTML template-element. The link_id hidden input-element is the standard CGI parameter name used to refer nodes' IDs that construct the overall application's link structure. The logic is to use again node's link-id which is used to call webman_db_item_insert_multirows module previously each time the form is submitted to change the default row number of item field entries. The irn_param_name text input-element will be passed as CGI parameter that store the number of rows of item field entries. There is no specific convention for its name but the module will by default used the name that in the form of irn_table_name.

Next, the rest of template's parts are enclosed inside the second form. The DYNAMIC_CONTENT template-element (line 17) named form_hidden_field is used as place-holder for HTML-form's hidden input-element. The generated hidden input-element is used as an entity to pass the CGI parameter named link_id that has the same role as link_id hidden input-element inside the first form.

The DATAHTML template-element (lines 27-43) named form_db_field is passed to process_DATAHTML hook function and manipulated by Data_HTML_Map core module. The rows of input-elements enclosed inside the DATAHTML template-element are intended to be passed as CGI parameters using a series of parameter's names as follows:

$db_field_name_1_0, ..., $db_field_name_n_0,
$db_field_name_1_1, ..., $db_field_name_n_1,
...
$db_field_name_1_n, ..., $db_field_name_n_n

Thus, the input element names and template's word patterns used are in the form of $db_field_name_1_$row_idx till $db_field_name_n_$row_idx and $db_field_name_1_$row_idx_ till $db_field_name_n_$row_idx_. Note that $db_field_name_1_$row_idx and $db_field_name_1_$row_idx_ are two different things. The former is an input-element name to be passed as CGI parameter representing item field name and value involved in the insert operation. The later is template-element's word pattern, treated by Data_HTML_Map module as a place-holder to render the coresspond CGI parameter value. Template's word patterns $fe_field_name_1_$row_idx_ till $fe_field_name_n_$row_idx_ are used as place-holders for highlighting errors on field values entered.

Two form's submit buttons (lines 48-49) with identical name button_submit but having two different values (Proceed and Cancel) are the default settings to provide users the options to proceed or cancel the submission of insert form. In other word the module by default will check the input type element named button_submit and look at its value either Proceed or Cancel before decide to continue or cancel the insert form submission.

  1 <html>                                                                                                                      
  2 <body>                                                                                                                      
  3 <!-- start_view_ //-->                                                                                                      
  4 <!-- dynamic_content_ name=link_path //--> &gt; Insert Items                                                                
  5 <p />                                                                                                                       
  6 <form method="POST" action="./index.cgi">                                                                                   
  7   <!-- start_cgihtml_ //-->                                                                                                 
  8   <input type="hidden" name="link_id" value="$cgi_link_id_">                                                                
  9   <b>Row Number:</b>                                                                                                        
 10   <input type="text" name="irn_param_name" size="3" value="$cgi_irn_param_name_">                                           
 11   <!-- end_cgihtml_ //-->                                                                                                   
 12                                                                                                                             
 13   <input name="button_submit" type="submit" id="button_submit" value="Change" />                                            
 14 </form>                                                                                                                     
 15                                                                                                                             
 16 <form method="POST" action="./index.cgi">                                                                                   
 17 <!-- dynamic_content_ name=form_hidden_field //-->                                                                          
 18 <table border="1">                                                                                                          
 19   <tr>                                                                                                                      
 20     <td align="right" valign="top"><b>Num. </b></td>                                                                        
 21     <td valign="top">field_caption_1</td>                                                                                   
 22     ...                                                                                                                     
 23     <td valign="top">field_caption_n</td>                                                                                   
 24   </tr>                                                                                                                     
 25                                                                                                                             
 26   <!-- start_datahtml_ name=form_db_field //-->                                                                             
 27   <tr>                                                                                                                      
 28     <td align="right" valign="top">                                                                                         
 29       <b>$row_num_. </b>                                                                                                    
 30     </td>                                                                                                                   
 31     <td valign="top">                                                                                                       
 32       <input name="$db_field_name_1_$row_idx" type="text" id="$db_field_name_1_$row_idx" value="$db_field_name_1_$row_idx_">
 33       </br>                                                                                                                 
 34       <font color="#FF0000">$fe_field_name_1_$row_idx_</font>                                                               
 35     </td>                                                                                                                   
 36     ...                                                                                                                     
 37     ...                                                                                                                     
 38     <td valign="top">                                                                                                       
 39       <input name="$db_field_name_n_$row_idx" type="text" id="$db_field_name_n_$row_idx" value="$db_field_name_n_$row_idx_">
 40       </br>                                                                                                                 
 41       <font color="#FF0000">$fe_field_name_n_$row_idx_</font>                                                               
 42     </td>                                                                                                                   
 43   </tr>                                                                                                                     
 44   <!-- end_datahtml_ //-->                                                                                                  
 45                                                                                                                             
 46   <tr>                                                                                                                      
 47     <td align="right" colspan="6">                                                                                          
 48       <input name="button_submit" type="submit" id="button_submit" value="Proceed" />                                       
 49       <input name="button_submit" type="submit" id="button_submit" value="Cancel" />                                        
 50     </td>                                                                                                                   
 51   </tr>                                                                                                                     
 52 </table>                                                                                                                    
 53 </form>                                                                                                                     
 54 <!-- end_view_ //-->                                                                                                        
 55 </body>                                                                                                                     
 56 </html>                                                                                                                     

1.2 Confirmation Form Page

There is only single html-form used inside the view template for confirmation form page. The two DYNAMIC_CONTENT template-elements (lines 4 and 7) are play the same roles as explained in insert form page above. The DATAHTML template-element (lines 18-23) is also the same as in insert form page but doesn't contain form's input-elements and word patterns for highlighting field entries errors. At the time confirmation form page processed by the module, all CGI parameters passed from the previous insert form page are already cached into the database. DATAHTML template-element is solely used to display back item's field values held by these cached CGI parameters for confirmation purpose.

Three form's submit buttons (lines 28-30) with identical name button_submit but having three different values (Confirm, Edit, and Cancel) are the default settings to provide users the options to confirm or cancel the insert operation, or back to insert form page to edit the field entries. In other word the module by default will check the input-element named button_submit and look at its value either Confirm, Edit, or Cancel before decide to continue or cancel the insert operation, or going back to insert form page to edit the previous data entries..

  1 <html>                                                                              
  2 <body>                                                                              
  3 <!-- start_view_ //-->                                                              
  4 <!-- dynamic_content_ name=link_path //--> &gt; Insert Items                        
  5 <p />                                                                               
  6 <form method="POST" action="./index.cgi">                                           
  7 <!-- dynamic_content_ name=form_hidden_field //-->                                  
  8                                                                                     
  9 <table border="1">                                                                  
 10   <tr>                                                                              
 11     <td align="right" valign="top"><b>Num. </b></td>                                
 12     <td valign="top">field_caption_1</td>                                           
 13     ...                                                                             
 14     <td valign="top">field_caption_n</td>                                           
 15   </tr>                                                                             
 16                                                                                     
 17   <!-- start_datahtml_ name=form_db_field //-->                                     
 18   <tr>                                                                              
 19    <td align="right" valign="top"><b>$row_num_. </b></td>                           
 20    <td>$db_field_name_1_$row_idx_</td>                                              
 21    ...                                                                              
 22    <td>$db_field_name_n_$row_idx_</td>                                              
 23   </tr>                                                                             
 24   <!-- end_datahtml_ //-->                                                          
 25                                                                                     
 26   <tr>                                                                              
 27     <td align="right" colspan="6">                                                  
 28       <input name="button_submit" type="submit" id="button_submit" value="Confirm"/>
 29       <input name="button_submit" type="submit" id="button_submit" value="Edit"/>   
 30       <input name="button_submit" type="submit" id="button_submit" value="Cancel"/> 
 31     </td>                                                                           
 32   </tr>                                                                             
 33 </table>                                                                            
 34 </form>                                                                             
 35 <!-- end_view_ //-->                                                                
 36 </body>                                                                             
 37 </html>                                                                             


 
2. Instantiation and Basic Parameter Setting

Generally, all the parameters to bet set are the same as explained in webman_db_item_insert module. The only differences are the extra settings to control row item number of the field entries involved in the insert operations (lines 9 and 12).

  1 my $component = new webman_db_item_insert_multirows;                                                         
  2                                                                                                              
  3 $component->set_CGI($cgi);                                                                                   
  4 $component->set_DBI_Conn($db_conn);                                                                          
  5                                                                                                              
  6 $component->set_Table_Name($table_name);                                                                     
  7                                                                                                              
  8 ### Default is 1                                                                                             
  9 #$component->set_Row_Num($row_num);                                                                          
 10                                                                                                              
 11 ### Will set $row_num = $row_num_limit if $row_num > $row_num_limit                                          
 12 #$component->set_Row_Num_Limit($row_num_limit);                                                              
 13                                                                                                              
 14 ### Default is "irn" . $table_name string concatenation.                                                     
 15 #$component->set_Row_Num_Param($row_num_param);                                                              
 16                                                                                                              
 17 $component->set_Check_On_CGI_Data("\$db_field_name_1_ ... \$db_field_name_n_");                              
 18 $component->set_Check_On_Fields_Duplication("field_name_1_ field_name_2_&field_name_3_ ... field_name_n_");  
 19 $component->set_Check_On_Fields_Existence("field_name_1_=>table_name_1_, ..., field_name_n_=>table_name_n_");
 20                                                                                                              
 21 #$component->set_Exceptional_DB_Fields("field_name_1 ... field_name_n");                                     
 22                                                                                                              
 23 ### Option to debug SQL satement generated by the module.                                                    
 24 #$component->set_SQL_Debug(1);                                                                               
 25                                                                                                              
 26 #$component->set_Submit_Button_Name($submit_button_name);  ### default is "button_submit"                    
 27 #$component->set_Proceed_On_Submit($proceed_button_value); ### default is "Proceed"                          
 28 #$component->set_Confirm_On_Submit($confirm_button_value); ### default is "Confirm"                          
 29 #$component->set_Edit_On_Submit($edit_button_value);       ### default is "Edit"                             
 30 #$component->set_Cancel_On_Submit($cancel_button_value);   ### default is "Cancel"                           
 31                                                                                                              
 32 #$component->set_Last_Phase_CGI_Data_Reset("param_name_1 param_name_2 ... param_name_n");                    
 33                                                                                                              
 34 #$component->set_Last_Phase_Only_If_Submit_Is("submit_button_value_");                                       
 35                                                                                                              
 36 ### Insert form page template.                                                                               
 37 $component->set_Template_Default($template_file);                                                            
 38                                                                                                              
 39 ### Don't assign confirm view template if want to skip the confirmation phase.                               
 40 $component->set_Template_Default_Confirm($template_file_confirm);                                            
 41                                                                                                              


 
3. Component-type Generic Function Calls

The implementation below is exactly the same as explained in webman_db_item_insert module.

 39 if ($component->authenticate) {                                 
 40     ### $status == 1 if insert operation is proceed and succeed.
 41     my $status = $component->run_Task;                          
 42                                                                 
 43     if ($status) {                                              
 44         ### Do other extra tasks if insert operation is succeed.
 45         ### ...                                                 
 46     }                                                           
 47                                                                 
 48     $component->process_Content;                                
 49 }                                                               
 50                                                                 
 51 my $content = undef;                                            
 52                                                                 
 53 if ($component->last_Phase) {                                   
 54     $component->end_Task;                                       
 55                                                                 
 56     ### Set to other related content .                          
 57     #$content = "...";                                          
 58                                                                 
 59     ### Jump to other URL.                                      
 60     #$cgi->redirect_Page($url);                                 
 61                                                                 
 62 } else {                                                        
 63     $content = $component->get_Content;                         
 64 }                                                               

The next proposed implementations is the more simple version but requires internal customizations inside child module implementations such as shown in the next section (section 4).
 39 if ($component->authenticate) {       
 40     $component->run_Task;             
 41     $component->process_Content;      
 42 }                                     
 43                                       
 44 if ($component->last_Phase) {         
 45     $component->end_Task;             
 46 }                                     
 47                                       
 48 my $content = $component->get_Content;


 
4. Child Module for Customization

Child module implementation for customizations are almost the same with webman_db_item_insert module. However, CGI parameters manipulation requires the consideration of handling them as a multi-rows HTML-form's input-elements (lines 105-113). Pay attention on the "\$db_linked_table_PK" . $row_idx string concatenation.

  1 package child_module_name;                                                                                                    
  2                                                                                                                                                 
  3 use webman_db_item_insert_multirows;                                                                                                            
  4                                                                                                                                                 
  5 @ISA=("webman_db_item_insert_multirows");                                                                                                       
  6                                                                                                                                                 
  7 sub new {                                                                                                                                       
  8     my $class = shift;                                                                                                                          
  9                                                                                                                                                 
 10     my $this = $class->SUPER::new();                                                                                                            
 11                                                                                                                                                 
 12     #$this->set_Debug_Mode(1, 1);                                                                                                               
 13                                                                                                                                                 
 14     bless $this, $class;                                                                                                                        
 15                                                                                                                                                 
 16     return $this;                                                                                                                               
 17 }                                                                                                                                               
 18                                                                                                                                                 
 19 sub get_Name {                                                                                                                                  
 20     my $this = shift @_;                                                                                                                        
 21                                                                                                                                                 
 22     return __PACKAGE__;                                                                                                                         
 23 }                                                                                                                                               
 24                                                                                                                                                 
 25 sub get_Name_Full {                                                                                                                             
 26     my $this = shift @_;                                                                                                                        
 27                                                                                                                                                 
 28     return $this->SUPER::get_Name_Full . "::" . __PACKAGE__;                                                                                    
 29 }                                                                                                                                               
 30                                                                                                                                                 
 31 sub run_Task {                                                                                                                                  
 32     my $this = shift @_;                                                                                                                        
 33                                                                                                                                                 
 34     my $cgi = $this->get_CGI;                                                                                                                   
 35     my $dbu = $this->get_DBU;                                                                                                                   
 36     my $db_conn = $this->get_DB_Conn;                                                                                                           
 37                                                                                                                                                 
 38     my $login_name = $this->get_User_Login;                                                                                                     
 39     my @groups = $this->get_User_Groups;                                                                                                        
 40                                                                                                                                                 
 41     my $match_group = $this->match_Group($group_name_, @groups);                                                                                
 42                                                                                                                                                 
 43     if ($this->init_Phase) {                                                                                                                    
 44         ### init. phase extra tasks                                                                                                             
 45         #$cgi->add_Debug_Text("init_Phase", __FILE__, __LINE__, "TRACING");                                                                     
 46                                                                                                                                                 
 47     } elsif ($this->confirm_Phase) {                                                                                                            
 48         ### confirm phase extra tasks                                                                                                           
 49         #$cgi->add_Debug_Text("confirm_Phase", __FILE__, __LINE__, "TRACING");                                                                  
 50                                                                                                                                                 
 51     } elsif ($this->edit_Phase) {                                                                                                               
 52         ### edit phase extra tasks                                                                                                              
 53         #$cgi->add_Debug_Text("edit_Phase", __FILE__, __LINE__, "TRACING");                                                                     
 54                                                                                                                                                 
 55     } elsif($this->last_Phase) {                                                                                                                
 56         ### last phase extra tasks                                                                                                              
 57         #$cgi->add_Debug_Text("last_Phase", __FILE__, __LINE__, "TRACING");                                                                     
 58     }                                                                                                                                           
 59                                                                                                                                                 
 60     my $status = $this->SUPER::run_Task();                                                                                                      
 61                                                                                                                                                 
 62     if ($status) {                                                                                                                              
 63         ### Extra tasks if insert operation is succeed.                                                                                         
 64     }                                                                                                                                           
 65 }                                                                                                                                               
 66                                                                                                                                                 
 67 sub end_Task {                                                                                                                                  
 68     my $this = shift @_;                                                                                                                        
 69                                                                                                                                                 
 70     my $cgi = $this->get_CGI;                                                                                                                   
 71     my $dbu = $this->get_DBU;                                                                                                                   
 72     my $db_conn = $this->get_DB_Conn;                                                                                                           
 73                                                                                                                                                 
 74     my $login_name = $this->get_User_Login;                                                                                                     
 75     my @groups = $this->get_User_Groups;                                                                                                        
 76                                                                                                                                                 
 77     ### Skeleton code to check if current user's groups are match with                                                                          
 78     ### specific intended group name.                                                                                                           
 79     #my $group_name = "???";                                                                                                                    
 80     #my $match_group = $this->match_Group($group_name, @groups);                                                                                
 81                                                                                                                                                 
 82     ### It's mandatory to call this for multi phases modules                                                                                    
 83     ### to reset some of the no longer required CGI data.                                                                                       
 84     $this->SUPER::end_Task();                                                                                                                   
 85                                                                                                                                                 
 86     ### Put other extra end-task jobs after this line.                                                                                          
 87                                                                                                                                                 
 88     ### Set to other related content.                                                                                                           
 89     #$this->set_Content("...");                                                                                                                 
 90                                                                                                                                                 
 91     ### Jump to other URL.                                                                                                                      
 92     #$cgi->redirect_Page($url);                                                                                                                 
 93 }                                                                                                                                               
 94                                                                                                                                                 
 95 ### This function will be called just before the insert                                                                                         
 96 ### operation is implemented inside the run_Task function.                                                                                      
 97 sub customize_CGI_Data { ### 11/10/2011                                                                                                         
 98     my $this = shift @_;                                                                                                                        
 99     my $te = shift @_;                                                                                                                          
100                                                                                                                                                 
101     my $cgi = $this->get_CGI;                                                                                                                   
102     my $dbu = $this->get_DBU;                                                                                                                   
103     my $db_conn = $this->get_DB_Conn;                                                                                                           
104                                                                                                                                                 
105     for (my $row_idx = 0; $row_idx < $this->{row_num}; $row_idx++) {                                                                            
106         ### Example on how to add/insert other linked table primary keys                                                                        
107         ### (linked_table_PK) that act as a foreign keys inside current table                                                                   
108         ### by refering to one of current table field that act as a unique keys                                                                 
109         ### inside the linked table (linked_table_UK)                                                                                           
110         #$dbu->set_Table("linked_table_name");                                                                                                  
111         #my $linked_table_PK = $dbu->get_Item("linked_table_PK", "linked_table_UK", $cgi->param("\$db_linked_table_UK" . $row_idx));            
112         #$cgi->push_Param("\$db_linked_table_PK" . $row_idx, $linked_table_PK);                                                                 
113     }                                                                                                                                           
114 }                                                                                                                                               
115                                                                                                                                                 
116 ### Provide more flexibility inside the child module so developers can                                                                          
117 ### further refine the final constructed form-field-row string using Perl's                                                                     
118 ### regular expression and string substitutions.                                                                                                
119 sub refine_Form_DB_Field_Row_Str {                                                                                                              
120     my $this = shift @_;                                                                                                                        
121     my $str = shift @_;                                                                                                                         
122                                                                                                                                                 
123     my $cgi = $this->get_CGI;                                                                                                                   
124     my $db_conn = $this->get_DB_Conn;                                                                                                           
125     my $db_interface = $this->get_DB_Interface;                                                                                                 
126                                                                                                                                                 
127     #for (my $row_idx = 0;  $row_idx < $this->{row_num}; $row_idx++) {                                                                          
128         #$str =~ ....;                                                                                                                          
129     #}                                                                                                                                          
130                                                                                                                                                 
131     return $str;                                                                                                                                
132 }                                                                                                                                               
133                                                                                                                                                 
134 1;