-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Generate a form from a DB table
As is, this depends on XAJAX CI library. If you just want to produce forms based on DB tables then use the “_formBuilder” function by itself by commenting-out/removing one line of code for it to be independent (there is a comment beside the line in the code below).
This code is released under the same license under which CI is released.
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:
/**
* @author Bob Beauchamp
* @link http://www.codeigniter.com/wiki/Generate_a_form_from_a_DB_table/
*/
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] = '<div id="'.$field.'manageToggle">'
.anchor('#','Make Unmanaged','onclick="xajax_toggleManagement(\''.$table.'\',\''.$field.'\');return false;"')
.'</div>';
}else{
$displayFields[$field][$field] = '<div id="'.$field.'manageToggle">'
.anchor('#','Make Managed','onclick="xajax_toggleManagement(\''.$table.'\',\''.$field.'\');return false;"')
.'</div>';
}
}
}
$objResponse = new xajaxResponse();
$objResponse->addAssign($table."manageFields","innerHTML", ul($displayFields));
return $objResponse->getXML();
}
The _addTabletoManagementTable function in an internal function called using xajax:
/**
* @author Bob Beauchamp
* @link http://www.codeigniter.com/wiki/Generate_a_form_from_a_DB_table/
*/
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();
}
Simple xajax toggle for table management
/**
* @author Bob Beauchamp
* @link http://www.codeigniter.com/wiki/Generate_a_form_from_a_DB_table/
*/
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();
}
This is the function you want to reference from your browser in order to start the magic rolling.
/**
* @author Bob Beauchamp
* @link http://www.codeigniter.com/wiki/Generate_a_form_from_a_DB_table/
*/
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] = '<div id="'.$table.'manageToggle">'
.anchor('#','Make Unmanaged','onclick="xajax_toggleManagement(\''.$table.'\');return false;"')
.'</div>'
.'<div id="'.$table.'manageFields">'
.anchor('#','Manage Fields','onclick="xajax_ManageFields(\''.$table.'\');return false;"')
.'</div>';
}else{
$displayTables[$table][$table] = '<div id="'.$table.'manageToggle">'
.anchor('#','Make Managed','onclick="xajax_toggleManagement(\''.$table.'\');return false;"')
.'</div>'
.'<div id="'.$table.'manageFields">'
.'</div>';
}
}else{
$displayTables[$table][$table] = '<span id="'.$table.'manageToggle">'
.anchor('#','Add to Management_tables table','onclick="xajax_addTableToManagementTable(\''.$table.'\');return false;"')
.'</span>';
}
}
}
$data['xajax_js'] = $this->xajax->getjavascript(null, '/_js/xajax.js');
$data['content'] = ul($displayTables);
$this->load->view('managetables',$data);
}
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.
/**
* @author Bob Beauchamp
* @link http://www.codeigniter.com/wiki/Generate_a_form_from_a_DB_table/
*/
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; //comment this out if you are using only this function and not the supporting "management" fuctions
}
$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":
$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;
}
Here is the SQL (exported from mySQL) to create the management tables:
--
-- 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;
My simple view for the "managetables" function:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?=$xajax_js;?>
</head>
<body>
<?=$content;?>
</body>
</html>