diff --git a/Generate-a-form-from-a-DB-table.md b/Generate-a-form-from-a-DB-table.md new file mode 100755 index 00000000..93967c38 --- /dev/null +++ b/Generate-a-form-from-a-DB-table.md @@ -0,0 +1,374 @@ +This depends on [[XAJAX]] CI library. If you don't want to use that then it should be simple to eliminate this dependency. + +How to use this code: + +1)Copy the functions below into your controller, +2)Create the tables described in the SQL towards the bottom of this page, +3)Create a view named "managetables" and paste the view code from the bottom of this page into it. +4)??? +5)Profit! + +Here are the functions required: + +The _manageFields function is an internal function called using xajax: + +[code] +function _manageFields($table){ + $table = $this->input->xss_clean($table); + $fields = $this->db->list_fields($table); + foreach($fields as $field){ + $fieldQuery = $this->db->getWhere('Management_fields',array('FieldName' => $field, 'InTable' => $table)); + if($fieldQuery->num_rows() > 0){ + $fieldRow = $fieldQuery->result(); + $fieldRow = $fieldRow[0]; + if($fieldRow->AllowManagement){ + $displayFields[$field][$field] = '
' + .anchor('#','Make Unmanaged','onclick="xajax_toggleManagement(\''.$table.'\',\''.$field.'\');return false;"') + .'
'; + }else{ + $displayFields[$field][$field] = '
' + .anchor('#','Make Managed','onclick="xajax_toggleManagement(\''.$table.'\',\''.$field.'\');return false;"') + .'
'; + } + } + } + $objResponse = new xajaxResponse(); + $objResponse->addAssign($table."manageFields","innerHTML", ul($displayFields)); + return $objResponse->getXML(); +} +[/code] + +The _addTabletoManagementTable function in an internal function called using xajax: + +[code] +function _addTableToManagementTable($table){ + $table = $this->input->xss_clean($table); + $tableQuery = $this->db->getWhere('Management_tables',array('TableName' => $table)); + if($tableQuery->num_rows() == 0){ + $dbInsert = array('TableName' => $table, + 'AllowManagement' => 1); + $this->db->insert('Management_tables',$dbInsert); + $fields = $this->db->list_fields($table); + foreach($fields as $field){ + $dbInsert = array('FieldName' => $field, + 'InTable' => $table, + 'AllowManagement' => 1); + $this->db->insert('Management_fields',$dbInsert); + } + } + $display = anchor('#','Make Unmanaged','onclick="xajax_toggleManagement(\''.$table.'\');return false;"'); + $objResponse = new xajaxResponse(); + $objResponse->addAssign($table."manageToggle","innerHTML", $display); + return $objResponse->getXML(); +} +[/code] + +Simple xajax toggle for table management + +[code] +function _toggleManagement($table,$field = FALSE){ + $objResponse = new xajaxResponse(); + if(!$field){ + $tableQuery = $this->db->getWhere('Management_tables',array('TableName' => $table)); + if($tableQuery->num_rows() > 0){ + $tableRow = $tableQuery->result(); + $tableRow = $tableRow[0]; + if($tableRow->AllowManagement){ + $this->db->set('AllowManagement',0); + $display = anchor('#','Make Managed','onclick="xajax_toggleManagement(\''.$table.'\');return false;"'); + $objResponse->addAssign($table.'manageFields',"innerHTML", ''); + }else{ + $this->db->set('AllowManagement',1); + $display = anchor('#','Make Unmanaged','onclick="xajax_toggleManagement(\''.$table.'\');return false;"'); + $fieldDisplay = anchor('#','Manage Fields','onclick="xajax_ManageFields(\''.$table.'\');return false;"'); + $objResponse->addAssign($table.'manageFields',"innerHTML", $fieldDisplay); + } + $this->db->where('TableName',$table); + $this->db->update('Management_tables'); + } + $objResponse->addAssign($table."manageToggle","innerHTML", $display); + }else{ + $fieldQuery = $this->db->getWhere('Management_fields',array('FieldName' => $field, 'InTable' => $table)); + if($fieldQuery->num_rows() > 0){ + $fieldRow = $fieldQuery->result(); + $fieldRow = $fieldRow[0]; + if($fieldRow->AllowManagement){ + $this->db->set('AllowManagement',0); + $display = anchor('#','Make Managed','onclick="xajax_toggleManagement(\''.$table.'\',\''.$field.'\');return false;"'); + }else{ + $this->db->set('AllowManagement',1); + $display = anchor('#','Make Unmanaged','onclick="xajax_toggleManagement(\''.$table.'\',\''.$field.'\');return false;"'); + } + $this->db->where('FieldName',$field); + $this->db->where('InTable',$table); + $this->db->update('Management_fields'); + } + $objResponse = new xajaxResponse(); + $objResponse->addAssign($field."manageToggle","innerHTML", $display); + } + return $objResponse->getXML(); +} +[/code] + +This is the function you want to reference from your browser in order to start the magic rolling. + +[code] +function managetables(){ + $this->load->library('xajax'); + $this->xajax->registerFunction(array('toggleManagement',&$this,'_toggleManagement')); + $this->xajax->registerFunction(array('addTableToManagementTable',&$this,'_addTableToManagementTable')); + $this->xajax->registerFunction(array('ManageFields',&$this,'_ManageFields')); + $this->xajax->processRequests(); + + $tables = $this->db->list_tables(); + foreach($tables as $table){ + if($table != 'Management_tables' && $table != 'Management_fields'){ + $tableQuery = $this->db->getWhere('Management_tables',array('TableName' => $table)); + if($tableQuery->num_rows() > 0){ + $tableRow = $tableQuery->result(); + $tableRow = $tableRow[0]; + if($tableRow->AllowManagement){ + $displayTables[$table][$table] = '
' + .anchor('#','Make Unmanaged','onclick="xajax_toggleManagement(\''.$table.'\');return false;"') + .'
' + .'
' + .anchor('#','Manage Fields','onclick="xajax_ManageFields(\''.$table.'\');return false;"') + .'
'; + }else{ + $displayTables[$table][$table] = '
' + .anchor('#','Make Managed','onclick="xajax_toggleManagement(\''.$table.'\');return false;"') + .'
' + .'
' + .'
'; + } + }else{ + $displayTables[$table][$table] = '' + .anchor('#','Add to Management_tables table','onclick="xajax_addTableToManagementTable(\''.$table.'\');return false;"') + .''; + } + } + } + $data['xajax_js'] = $this->xajax->getjavascript(null, '/_js/xajax.js'); + $data['content'] = ul($displayTables); + $this->load->view('managetables',$data); +} +[/code] + +I have made this an internal function so I can just call it from other functions and have it return the basic form elements. Can work as a url-addressable function with some minor tweaks. This function depends on the table being passed into to already being in the management tables (see SQL code below). I have debated making it automatically suck the table and fields into the management tables but have not yet taken that step since I like to be a bit more hands-on with this kind of thing. + +[code] +function _formBuilder($table,$values=array(),$valuesAsHidden=FALSE){ + $columns = $this->db->query($this->db->_list_columns($table)); + if($columns->num_rows() > 0){ + foreach ($columns->result_array() as $columnInfo){ + foreach($columnInfo as $key => $val){ + if($key == 'Field'){ + $fieldName = $val; + if(!$this->data->getManagementStatus($table,$fieldName)) break; + } + $arrTableInfo[$fieldName][$key] = $val; + } + } + $formDisplay = ''; + foreach($arrTableInfo as $fieldName => $arrInfo){ + $arrFormField = ''; + if(isset($values[$fieldName])){ + $arrFormField[$fieldName] = $values[$fieldName]; + $formFunction = 'form_hidden'; + }else{ + if($fieldName == 'InCity' && $table == 'minisites'){ + $selectName = $fieldName; + $selectExtra = ' class="cms_form_dropdown"'; + $retval[$fieldName] = form_dropdown($selectName,$this->data->getCityArray(),'',$selectExtra); + continue; + } + $arrFormField['name'] = $fieldName; + $arrFormField['id'] = $fieldName; + foreach($arrInfo as $key => $val){ + switch($key){ + case 'Type': + $formType = explode('(',$val); + switch($formType[0]){ + case 'varchar': //always has a size + case "char": + $formFunction = 'form_input'; + $arrFormField['maxlength'] = str_replace(')','',$formType[1]); + break; + case "tinyint": + case "smallint": + case "mediumint": + case "int": + case "bigint": + case "year": + $formFunction = 'form_input'; + $numericInfo = explode(' ',$formType[1]); + $arrFormField['maxlength'] = str_replace(')','',$numericInfo[0]); + if(isset($numericInfo[1])){ + $validationExtras = $numericInfo[1]; + } + break; + case "datetime": + case "timestamp": + $formFunction = 'form_input'; + $arrFormField['maxlength'] = '19'; + break; + case "float": + $formFunction = 'form_input'; + $arrFormField['maxlength'] = '23'; + break; + case "double": + $formFunction = 'form_input'; + $arrFormField['maxlength'] = '53'; + break; + case "decimal": + $formFunction = 'form_input'; + $arrFormField['maxlength'] = '64'; + break; + case "date": + $formFunction = 'form_input'; + $arrFormField['maxlength'] = '10'; + break; + case "year": + $formFunction = 'form_input'; + $arrFormField['maxlength'] = '4'; + break; + case "time": + $formFunction = 'form_input'; + $arrFormField['maxlength'] = '8'; + break; + case 'tinytext': + $formFunction = 'form_input'; + if(isset($formType[1])){ + $arrFormField['maxlength'] = str_replace(')','',$formType[1]); + }else{ + $arrFormField['maxlength'] = '255'; + } + break; + case 'text': + $formFunction = 'form_textarea'; + if(isset($formType[1])){ + $arrFormField['maxlength'] = str_replace(')','',$formType[1]); + }else{ + $arrFormField['maxlength'] = '65535'; + } + break; + case 'mediumtext': + case 'longtext': + $formFunction = 'form_textarea'; + if(isset($formType[1])){ + $arrFormField['maxlength'] = str_replace(')','',$formType[1]); + }else{ + $arrFormField['maxlength'] = '16777215'; + } + break; + case 'set': + $formFunction = 'form_dropdown'; + $selectExtra = 'multiple="multiple"'; + $setVals = explode(',',$val); + $totalVals = count($setVals); + $setVals[0] = str_replace("set('",'',$setVals[0]); + $setVals[($totalVals - 1)] = str_replace("')",'',$setVals[($totalVals - 1)]); + foreach($setVals as $key => $val){ + $setVals[$key] = str_replace("'",'',$setVals[$key]); + $arrFormField[$setVals[$key]] = $setVals[$key]; + } + break; + case 'enum': + $formFunction = 'form_dropdown'; + $selectExtra = ''; + $enumVals = explode(',',$val); + $totalVals = count($enumVals); + $enumVals[0] = str_replace("enum('",'',$enumVals[0]); + $enumVals[($totalVals - 1)] = str_replace("')",'',$enumVals[($totalVals - 1)]); + $arrFormField['selectone'] = 'Select One'; + foreach($enumVals as $key => $val){ + $enumVals[$key] = str_replace("'",'',$enumVals[$key]); + $arrFormField[$enumVals[$key]] = $enumVals[$key]; + } + break; + } + break; + case 'Null': + //todo: should there be a "required" validation rule based on this? + // currently I'm leaning towards "no" and making them specify + // validation rules separately and deliberately + break; + case 'Key': + if($val != ''){ + if(@$validationExtras != ''){ + $validationExtras .= '|'.$val; + }else{ + $validationExtras = $val; + } + } + break; + case 'Default': + //$arrFormField['value'] = $val; //considering leaving this out since the default is going + //to be populated if there is no value. Would have to unset + //the value before inserting/updating the DB record + break; + case 'Extra': + break; + } + } + } + if($formFunction != "form_dropdown"){ + if($formFunction != 'form_hidden'){ + $arrFormField['class'] = 'css_'.$formFunction; + } + $retval[$fieldName] = $formFunction($arrFormField); + }else{ + $selectName = $arrFormField['name']; + unset($arrFormField['name']); + unset($arrFormField['id']); + $selectExtra .= ' class="css_'.$formFunction.'"'; + $retval[$fieldName] = $formFunction($selectName,$arrFormField,'selectone',$selectExtra); + } + } + }else{ + $retval = FALSE; + } + return $retval; +} +[/code] + +Here is the SQL (exported from mySQL) to create the management tables: + +[code] +-- +-- Table structure for table `Management_fields` +-- + +CREATE TABLE `Management_fields` ( + `FieldName` varchar(255) NOT NULL, + `InTable` varchar(255) NOT NULL, + `AllowManagement` tinyint(1) NOT NULL default '1', + PRIMARY KEY (`FieldName`,`InTable`) +) TYPE=MyISAM; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `Management_tables` +-- + +CREATE TABLE `Management_tables` ( + `TableName` varchar(255) NOT NULL, + `AllowManagement` tinyint(1) NOT NULL default '1', + PRIMARY KEY (`TableName`) +) TYPE=MyISAM; +[/code] + +My simple view for the "managetables" function: + +[code] + +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<?=$xajax_js;?> +</head> +<body><?=$this->load->view('tabletestheader','',TRUE);?> +<?=$content;?> +</body> +</html> +[/code] \ No newline at end of file