I started with webform module but the built in grid element did not work. Then I tried webform_table_element module, it had some bugs but I managed to configure it. But, unfortunately, it was not able to produce a similar form. I was on a tight deadline (as usual) and did not have time to do something custom, so I decided to try some workaround and after spending a little time I got acceptable result.
I am writing some simple steps to re-generate similar result. I know this is not an ideal solution but it can save a little time if you have to add a couple of similar forms in your Drupal based project.
You need to install webform and webform_table_element module modules first.
a) Add a field of type table_element in webform. table_element type requires you to put key|value pairs in 'Rows' textarea there, convert your 'value' to a simple JSON so it can be accessed later, something like:
1|{"ID":"001", "title":"My Item 1", "rate":"245"}
2|{"ID":"002", "title":"My Item 2", "rate":"460"}
3|{"ID":"003", "title":"My Item 3", "rate":"740"}
And here is a screenshot:
b) Add these child elements under newly created table_element type item:
- Item Name
- Type: markup
- Label: Item Name
- Field Key: item_name
- Value: Name
- Item Rate
- Type: markup
- Label: Item Rate
- Field Key: item_rate
- Value: Rate
- Quantity
- Type: textfield
- Label: Quantity
- Field Key: quantity
- Item Rate
c) We are done with form building here, now time to add some code in template.php file:
// This will display form element in a multi column table
function adibf_table_element($variables) {
$element = $variables['element'];
$header = array();
$header_complete = false;
$rows = array();
foreach (element_children($element) as $child) {
$child_element = $element[$child];
$rowCustomData = $child_element['#row_title'];
$rowCustomData = json_decode($rowCustomData);
$row = array($rowCustomData->ID);
foreach (element_children($child_element) as $grandchild) {
if (!$header_complete && isset($element['#row_titles'])) {
if($child_element[$grandchild]['#type'] == 'markup') {
$theKey = trim(strip_tags($child_element[$grandchild]['#markup']));
$theTitle = '';
switch($theKey) {
case 'Name':
$theTitle = t('Item');
break;
case 'Rate':
$theTitle = t('Rate (usd)');
break;
case 'Quantity':
$theTitle = t('Quantity');
break;
}
if($element['#column_titles'][$grandchild] == 'sub-total')
$theTitle = t('Sub Total');
$header[] = array('data' => $theTitle, 'class' => $element['#column_titles'][$grandchild]);
} else {
$header[] = array('data' => t($element['#row_titles'][$grandchild]), 'class' => $element['#column_titles'][$grandchild]);
}
}
if($child_element[$grandchild]['#type'] == 'markup') {
if(trim(strip_tags($child_element[$grandchild]['#markup'])) == 'Name')
$child_element[$grandchild]['#markup'] = $rowCustomData->title;
if(trim(strip_tags($child_element[$grandchild]['#markup'])) == 'Rate')
$child_element[$grandchild]['#markup'] = $rowCustomData->rate;
if(trim(strip_tags($child_element[$grandchild]['#markup'])) == 'Color')
$child_element[$grandchild]['#markup'] = $rowCustomData->color;
if(trim(strip_tags($child_element[$grandchild]['#markup'])) == 'Dimension')
$child_element[$grandchild]['#markup'] = $rowCustomData->dimension;
}
$row[] = array('data' => drupal_render($child_element[$grandchild]));
}
$header_complete = true;
$rows[] = $row;
}
array_unshift($header, array('class' => 'row-title', 'data' => t('Code')));
return theme('table', array('header' => $header, 'rows' => $rows));
}
// This will show posted results in multi column table
function adibf_webform_submission_render_alter(&$renderable) {
if (isset($renderable['#submission'])) {
foreach (element_children($renderable) as $key) {
$tableRows = array();
if ($renderable[$key]['#webform_component']['type'] == 'table_element') {
$cid = $renderable[$key]['#webform_component']['cid'];
foreach($renderable['#submission']->data[$cid]['value']['rows'] as $row) {
$data = strip_tags($row[0]);
$quantity = $row['quantity'];
$objData = json_decode($data);
$subTotal = $objData->rate * $quantity;
$tableRows[] = array($objData->ID, $objData->title, $objData->rate, $quantity, $subTotal);
}
$tableHeader = array('ID', 'Title', 'Rate', 'Quantity', 'Sub Total');
$theTable = array(
'header' => $tableHeader,
'rows' => $tableRows,
);
$renderable[$key]['#markup'] = theme('table', $theTable);
}
}
}
}
First code block will display form element visually in a multi column table with one text field for quantity in each row, the second block is for the posted results.
d) The last step is to add a little jQuery somewhere in the theme so after entering quantity, sub total column value would be changed. You can also add a feature to show Net Total somewhere on the page:
jQuery('.webform-component-table_element .form-text').change(function() {
var elems = jQuery('.webform-component-table_element .form-text');
var totalAmount = 0;
for(var i=0; i<elems.length; i++) {
totalAmount += table_element_calculate(elems[i]);
}
jQuery('#net_total').html(totalAmount);
});
function table_element_calculate(elem) {
var sPrice = jQuery(elem).parents('td').prev().text();
var hTotal = jQuery(elem).parents('td').next();
var p = 0;
try {
p = sPrice * jQuery(elem).val();
if(isNaN(p))
p = 0;
if(p > 0)
hTotal.find('.sub-total').html(p);
// alert(p);
} catch(e) {}
return p;
}
Note: I just copied pasted these codes from a project that I did some months ago, so if something don't work please post in comments. Thanks.



Hello just came upon your website from Bing after I typed in, "Blogger: Helper Class" or something similar (can't quite remember exactly). Anyways, I'm happy I found it simply
ReplyDeletebecause your subject material is exactly what I'm searching for (writing a college paper) and I hope you don't mind if I collect some material from here and I will of course credit
you as the reference. Appreciate it., see additional reading []!