var jobs;var valid;function init(){	//debugger;	jobs = new dhtmlXGridObject('grid_jobs');	jobs.setImagePath(dbPath);	jobs.setOnEditCellHandler(doOnCellEdit);	jobs.setHeader("Date,Reference,Net Cost, VAT, Gross Cost");	jobs.setInitWidths("100,200,70,70,70");	jobs.setColTypes("ed,ed,ed,ro,ro");	jobs.setColAlign("left,left,right,right,right");	jobs.enableAutoHeigth(true);	jobs.setSizes();	jobs.enableLightMouseNavigation(true);	jobs.enableKeyboardSupport(true);	jobs.init();	if ($F("jobXML") == ""){		addRow(jobs, true);	}else{		jobs.loadXMLString($F("jobXML"));	}	jobs.setImagePath(dbPath);	valid = new Validation(document.forms[0], {immediate : true});	}function submitInvoice(){		if (valid.validate()) {			//First serialize the grid data			jobs.setSerializationLevel(); 			var myXmlStr = jobs.serialize();			$("jobXML").value = myXmlStr;						//Now use the generic submit function			document.forms[0].submit();		}}function doOnCellEdit(stage,rowId,cellInd){	var checkValue;	// stage 0 is entering the cell	if (stage == 0) {		}	// stage 2 is the point at which we leave the cell	if (stage == 2) {		checkValue = jobs.cells(rowId,cellInd).getValue();		if (cellInd == 2){			if (IsNumericComma(checkValue, true) || checkValue == "") {				jobs.cells(rowId, cellInd).setValue(FormatNumber(checkValue, ",", ".", 2, true));				var net = parseFloat(editReplace(checkValue, ",", ""));				var vat = parseFloat(editReplace($F("vatrate"), ",", "")) / 100 * net;				jobs.cells(rowId, 3).setValue(FormatNumber(vat, ",", ".", 2, true));				var gross = vat + net;				jobs.cells(rowId, 4).setValue(FormatNumber(gross, ",", ".", 2, true));				//Now Update the Totals				var totalnet = 0;				var totalvat = 0;				var totalgross = 0;				for (var iRow=0; iRow<jobs.getRowsNum(); iRow++){					totalnet = totalnet + parseFloat(editReplace(jobs.cells2(iRow, 2).getValue(), ",", ""));					totalvat = totalvat + parseFloat(editReplace(jobs.cells2(iRow, 3).getValue(), ",", ""));					totalgross = totalgross + parseFloat(editReplace(jobs.cells2(iRow, 4).getValue(), ",", ""));				}				$("jobNetTotal").value = FormatNumber(totalnet, ",", ".", 2, true);				$("jobVATTotal").value = FormatNumber(totalvat, ",", ".", 2, true);				$("jobGrandTotal").value = FormatNumber(totalgross, ",", ".", 2, true);				return true;			}else{				alert("Must be a numeric value");				jobs.cells(rowId,cellInd).setValue("");				return false;			}		}else{			return true;		}	}}function IsNumericComma(strString, bIncludePercent) {   //  check for valid numeric strings   var strValidChars = "0123456789.,";   if (bIncludePercent)        strValidChars += "%";   var strChar;   var blnResult = true;   if (strString.length == 0) return false;   //  test strString consists of valid characters listed above   for (i = 0; i < strString.length && blnResult == true; i++){      strChar = strString.charAt(i);      if (strValidChars.indexOf(strChar) == -1){            blnResult = false;        }    }    return blnResult;}function addRow(grid){	var newindex;	try {		newindex = grid.getRowsNum();	}catch (e){		newindex = 0;	}	grid.addRow(Date.parse(new Date()),"",newindex);	grid.cells2(newindex, 0).setValue(getToday());}function deleteRow(grid){	var whichRow = grid.getSelectedId();	if (whichRow < 0){		alert ("ERROR: No row selected. \n\nPlease highlight the row to be deleted and click Delete Selected Row again.");	}else{		if (confirm("You can not undo this operation. Do you really want to delete this row?")) {			grid.deleteRow(whichRow);		}	}}function getToday(){	// Array of month Names	var monthNames = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");	var now = new Date();	return (now.getDate() + "-" + monthNames[now.getMonth()] + "-" + now.getFullYear());}//====FUNCTION=======================================================================function formatNoWrapper(objField){	return FormatNumber(objField, ',', '.', 2)}//====FUNCTION=======================================================================function FormatNumber(objFieldOrVal, ThousandSep, Decimal, noDecPlaces, isStandardFormat){       		//If an object then get the value 		if(typeof(objFieldOrVal) == 'object')		{			  num = objFieldOrVal.value;			  retVal = false;		}		else		{			num = objFieldOrVal + '';			retVal = true;		}		        var sVal='';        var minus='';			var length = num.length;		var lastChar = num.substring(length - 1 ,length);			if(lastChar.toLowerCase() == 'm')		{			num = num.substring(0, length - 1) + '000000';		}			        if (num.lastIndexOf("-") == 0) 		{ 			minus = '-'; 			num = num.substring(1)		}             		//If the number of Decimal Places is 0 then remove anything after the decimal delimiter in the number   		if(isStandardFormat == true )		{			var intPosDec = num.indexOf('.')		}		else		{			var intPosDec = num.indexOf(Decimal);		}				//alert('Decimal ' + Decimal);	//alert('intPosDec ' +  intPosDec);	if(intPosDec  == -1)		{			numMain = num			 numDec  = ''		}	else	{			var numMain = num.substring(0, intPosDec)			var numDec =  num.substring(intPosDec + 1, num.length)		}		  numMain = FormatClean(numMain);	  numDec = FormatClean(numDec);	  	  //alert('numDec ' + numDec)              if(num == '')       {        sVal = '';        }        else       {       if(noDecPlaces == 0)       {        	sVal = minus + FormatMain(numMain,ThousandSep, noDecPlaces);         }        else        {      	  sVal = minus + FormatMain(numMain,ThousandSep, 0) + Decimal + FormatDecimals(numDec, noDecPlaces);         }   }        if(retVal == true)        {        		return sVal;        }        else        {       	 	objFieldOrVal.value= sVal;        }  }//====FUNCTION=======================================================================function FormatClean(num){	num = unescape(Trim(num));     var sVal='';     var nVal = num.length;     var sChar='';        try   {       for(i=0;i<nVal;i++)      {         sChar = num.charAt(i);         nChar = sChar.charCodeAt(0);              if (((nChar >=48) && (nChar <=57)) | (nChar == 46) | (nChar == 45) )  { sVal += num.charAt(i);   }        //if (nChar >=48)  { sVal += num.charAt(i);   }            	}   }    catch (exception) { AlertError("Format Clean",e); }    return sVal;} //====FUNCTION=======================================================================function FormatDecimals(amount, noDecPlaces){      try      {            	var decNo = ('0.' + amount)      	decNo++;  //Increment to ensure we have a number			amount = Math.round(decNo*Math.pow(10,noDecPlaces))/Math.pow(10,noDecPlaces) + '';		//We want to return everything after the decimal place     	amount = amount.substring(2);     	     	var zeros = '00000000000000000000000'     	var length = amount.length      	     	//If the value we have is samller than the number of decimal places we need to return we should append zeros     	     	if(length  < noDecPlaces)     	{     		amount = amount + zeros.substring(0, noDecPlaces - length)     	}     	          if(isNaN(amount)) amount = '00'     	      }      catch (exception) { AlertError("Format Decimals",e); }                                                                                                                   return amount;      }//====FUNCTION=======================================================================function FormatMain(amount,ThousandSepDelimiter, noDecPlaces){   try    {          amount = parseInt(amount);   	  if(isNaN(amount)) amount = '0'        var samount = new String(amount);       // if (samount.length < 3) { return 0; }          samount =  samount.substring(0,samount.length - noDecPlaces);                     for (var i = 0; i < Math.floor((samount.length-(1+i))/3); i++)        {           samount = samount.substring(0,samount.length-(4*i+3)) + ThousandSepDelimiter + samount.substring(samount.length-(4*i+3));         }     	          //if(isNaN(samount)) samount = '0'   }    catch (exception) { AlertError("Format Comma",e); }    return samount;}//====FUNCTION======================================================================= function AlertError(MethodName,e) {            if (e.description == null) { alert(MethodName + " Exception: " + e.message); }            else {  alert(MethodName + " Exception: " + e.description); } }//====FUNCTION=======================================================================//ConvertEuroFormatToStandardNofunction ConvertEuroFormatToStandardNo(strVal){	var s = strVal;	var intComma = s.lastIndexOf(',');	var main = s.substring(0, intComma);	var Dec = s.substring(intComma + 1, s.length);	var main2 = main.replace(/\./g , '');//	alert('Main2 ' + main2);	s = main2 + '.' + Dec	return s}//====FUNCTION=======================================================================function totalFieldContents(objField){	var intTotal = 0;	var aryField = objField.value.split(';');	for(var w = 0;  w < aryField.length; w++)	{		var newVal = parseFloat(FormatClean(aryField[w]));		newVal = isNaN(newVal) ? 0 : newVal;		intTotal = parseFloat(intTotal) + newVal;	}		return intTotal}//====FUNCTION===========================================================function editReplace(strTest, strFrom, strTo){	var re = new RegExp(strFrom, "gim");	if ( ! re.exec(strTest) )		return strTest;	return strTest.replace(re,strTo);}function Trim(varString) {try{  		while ((varString.substring(0,1) == ' ') || (varString.substring(0,1) == '\n') || (varString.substring(0,1) == '\r')) {		    varString = varString.substring(1,varString.length);  		}  		while ((varString.substring(varString.length-1,varString.length) == ' ') || (varString.substring(varString.length-1,varString.length) == '\n') || (varString.substring(varString.length-1,varString.length) == '\r')){    			varString = varString.substring(0,varString.length-1); 		}  		return varString;	}catch(e){	genJSError('Trim',e)}}