Friday, March 20, 2009

I've been using the Infragistics ASP.NET controls a bit recently and wanted to share a bit of code that I wrote. This code is used to take a Rate (could be a price), a discount, and calculate a Total using the Infragistics javascript client object model. How the calculation is done is up to you. I used a calculation that let's the end user enter a value like 5 (for 5%) and then the calculation converts to a decimal and calculate the total.



function beforeCellUpdate(gridClientId, cellId, newValue) {
var grid = igtbl_getGridById(gridClientId);
var band = igtbl_getBandById(cellId);
var bandKey = band.Key;

if (bandKey == 'Invoice') {
var invoiceRow = igtbl_getRowById(cellId);
var invoiceCell = igtbl_getCellById(cellId);
if (invoiceCell.Column.Key == 'Discount') {
var invoiceDiscount = newValue;
var childRowCount = invoiceRow.ChildRowsCount;
// Iterate over Invoice Items and update cell values.
for (var i = 0; i < childRowCount; i++) {
// Get InvoiceItem row from Invoice row.
var invoiceItemRow = invoiceRow.getChildRow(i);
// Get current rate value from InvoiceItem.Rate cell.
var rate = invoiceItemRow.getCellFromKey('Rate').getValue();
// Set InvioceItem.Discount cell to value entered into Invoice.Discount cell.
invoiceItemRow.getCellFromKey('Discount').setValue(invoiceDiscount);
// Get calculated InvoiceItem.Total.
invoiceItemTotal = getItemTotal(rate, invoiceDiscount);
// Set InvoiceItem.Total cell value to calculated value.
invoiceItemRow.getCellFromKey('Total').setValue(invoiceItemTotal);
}
// Get calculated Invoice total.
var invoiceTotal = getInvoiceTotal(invoiceRow);
// Set Invoice.Total cell value to calculated value.
invoiceRow.getCellFromKey('Total').setValue(invoiceTotal);
}
}

if (bandKey == 'InvoiceItem') {
var invoiceItemRow = igtbl_getRowById(cellId);
var invoiceItemCell = igtbl_getCellById(cellId);
var rate = invoiceItemRow.getCellFromKey('Rate').getValue();
var discount = invoiceItemRow.getCellFromKey('Discount').getValue();

if (invoiceItemCell.Column.Key == 'Rate') {
// If rate changed use newValue for rate.
rate = newValue;
}
else if (invoiceItemCell.Column.Key == 'Discount') {
// If discount changed use newValue for discount.
discount = newValue;
}

// Get calculated InvoiceItem.Total.
var invoiceItemTotal = getItemTotal(rate, discount);
invoiceItemRow.getCellFromKey('Total').setValue(invoiceItemTotal);

var invoiceRow = invoiceItemRow.ParentRow;
var invoiceTotal = getInvoiceTotal(invoiceRow);
// Set InvoiceItem.Total cell value to calculated value.
invoiceRow.getCellFromKey('Total').setValue(invoiceTotal);
}

if (bandKey == 'InvoiceItemCharge') {
var itemChargeRow = igtbl_getRowById(cellId);
var itemChargeCell = igtbl_getCellById(cellId);
var rate = itemChargeRow.getCellFromKey('Rate').getValue();
var discount = itemChargeRow.getCellFromKey('Discount').getValue();

if (itemChargeCell.Column.Key == 'Rate') {
// If rate changed use newValue for rate.
rate = newValue;
}
else if (itemChargeCell.Column.Key == 'Discount') {
// If discount changed use newValue for discount.
discount = newValue;
}

var itemTotal = getItemTotal(rate, discount);
itemChargeRow.getCellFromKey('Total').setValue(itemTotal);
}
}
// Calculates the total from the rate and discount.
function getItemTotal(rate, discount) {
var total = 0;
total = rate * (1 - discount / 100);
return total;
}
// Iterates over the InvoiceItem rows to sum the item totals.
function getInvoiceTotal(invoiceRow) {
var invoiceTotal = 0;
var invoiceItemCount = invoiceRow.ChildRowsCount;
// Iterate over the current Invoice.InvoiceItem row collection.
for (var i = 0; i < invoiceItemCount; i++) {
var invoiceItemRow = invoiceRow.getChildRow(i);
invoiceTotal += invoiceItemRow.getCellFromKey('Total').getValue();
}
return invoiceTotal;
}

This is specific to the Infragistics UltraWebGrid but it might not be too hard to change out for another grid.

InfoQ has a good article on Isolation Levels that I think is a good read. This is especially true for this who are not so familiar with them.

http://www.infoq.com/articles/eight-isolation-levels

Enjoy!