Webman-framework

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

About | Overview | Documentation

 

Documentation > Modules and APIs > webman_db_item_update_multirows

webman_db_item_update_multirows

 

Description:

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

 

Dependencies:

Webman-framework's Core Modules:

  • CGI_HTML_Map (Composition)
  • Data_HTML_Map (Composition)
  • DBI_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 might be assigned to a single webman_db_item_update_multirows module. First is an update form page for item's field entries and the second is a confirmation page for displaying back fields and their values entered before proceed with the update operation. If there is no second view template assigned to the module the confirmation phase will be skipped.

1.1 Update Form Page

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_update_multirows module is called. The next DYNAMIC_CONTENT template-element (line 7) named form_hidden_field is used as place-holder for HTML-form's hidden input-element. This hidden input-element is used as an entity to pass the parameter named link_id (via POST-method) which 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_update_multirows module previously.

The DATAHTML template-element (lines 17-33) 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 update 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.

CGI parameters mapped by the word patterns $db_field_name_1_, ..., $db_field_name_n_ are already made available at the first time the update form page was loaded for the purpose of displaying current field values from the database prior the update operation. It's done by injecting all item's field names and values involved as CGI parameters named in the form of aforementioned word patterns before start processing the DATAHTML template-element. Items's field names and values are retrieved from Table_List_Data instance, created by DBI_HTML_Map core module using SQL string command automatically or manually constructed via module's basic parameter settings that will be explained in the next main section (section 2, code lines 6-7 or line 12).

Other 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 38-39) 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 update 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 update form submission.

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

1.2 Confirmation Form Page

The two DYNAMIC_CONTENT template-elements (lines 4 and 7) are play the same roles as explained in update form page above. The DATAHTML template-element (lines 18-23) is also the same as in update 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 update 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 update operation, or back to update 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 update operation, or going back to update form page to edit the previous data entries..

  1 <html>                                                                              
  2 <body>                                                                              
  3 <!-- start_view_ //-->                                                              
  4 <!-- dynamic_content_ name=link_path //--> &gt; Update 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

All basic parameters to be set are exactly the same as explained in webman_db_item_update module documentation. The difference is the way of CGI parameters representing update's key-field set via function calls (lines 6-7 or line 12) are passed to the module. Since the module is used to support multi-rows update operation, update's key-fields need to be passed as CGI parameters named in the form of key_field_name_0, key_field_name_1, ..., till key_field_name_n.

  1 my $component = new webman_db_item_update_multirows;                                                                                          
  2                                                                                                                                               
  3 $component->set_CGI($cgi);                                                                                                                    
  4 $component->set_DBI_Conn($db_conn);                                                                                                           
  5                                                                                                                                               
  6 $component->set_Table_Name($table_name);                                                                                                      
  7 $component->set_Update_Keys_Str("key_field_name='\$cgi_key_field_name_'");                                                                    
  8                                                                                                                                               
  9 ### The next function call is not necessary if the previous two function calls                                                                
 10 ### is completed and complex key-field or tables joint for viewing current                                                                    
 11 ### item to be updated is not required.                                                                                                       
 12 ### $component->set_SQL_View("select * from $table_name where key_field_1='\$cgi_key_field_1_' and ... and key_field_n='\$cgi_key_field_n_'");
 13                                                                                                                                               
 14 ### Option to debug SQL satement generated by the module.                                                                                     
 15 #$component->set_SQL_Debug(1);                                                                                                                
 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_Limit_On_Fields("field_name_1 ... field_name_n");                                                                            
 22                                                                                                                                               
 23 #$component->set_Submit_Button_Name($submit_button_name);  ### default is "button_submit"                                                     
 24 #$component->set_Proceed_On_Submit($proceed_button_value); ### default is "Proceed"                                                           
 25 #$component->set_Confirm_On_Submit($confirm_button_value); ### default is "Confirm"                                                           
 26 #$component->set_Edit_On_Submit($edit_button_value);       ### default is "Edit"                                                              
 27 #$component->set_Cancel_On_Submit($cancel_button_value);   ### default is "Cancel"                                                            
 28                                                                                                                                               
 29 #$component->set_Last_Phase_CGI_Data_Reset("param_name_1 param_name_2 ... param_name_n");                                                     
 30                                                                                                                                               
 31 ### Option to automatically change the current active page by going                                                                           
 32 ### to other URL when last phase has been reached.                                                                                            
 33 #$component->set_Last_Phase_URL_Redirect($url);                                                                                               
 34                                                                                                                                               
 35 ### Update form page template.                                                                                                                
 36 $component->set_Template_Default($template_file);                                                                                             
 37                                                                                                                                               
 38 ### Don't assign confirm view template if want to skip the confirmation phase.                                                                
 39 $component->set_Template_Default_Confirm($template_file_confirm);                                                                             
 40                                                                                                                                               


 
3. Component-type Generic Function Calls

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

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

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).
 41 if ($component->authenticate) {       
 42     $component->run_Task;             
 43     $component->process_Content;      
 44 }                                     
 45                                       
 46 if ($component->last_Phase) {         
 47     $component->end_Task;             
 48 }                                     
 49                                       
 50 my $content = $component->get_Content;


 
4. Child Module for Customization

Child module implementation for customizations are almost the same with webman_db_item_update 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_update_multirows;                                                                                                            
  4                                                                                                                                                 
  5 @ISA=("webman_db_item_update_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 after update 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 update                                                                                         
 96 ### operation is implemented inside the run_Task function.                                                                                      
 97 sub customize_CGI_Data {                                                                                                                        
 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->{update_key_field_list}}; $row_idx++) {                                                         
128         #$str =~ ....;                                                                                                                          
129     #}                                                                                                                                          
130                                                                                                                                                 
131     return $str;                                                                                                                                
132 }                                                                                                                                               
133                                                                                                                                                 
134 1;