Asked by:
Calculate difference between two fields

Question
-
I have two fields one is the value of what it costs to hire a resource, the second is what we bill the client. We want to know the margin or profit for this and sort by highest margin. I have spent way to much time on something so simple and it wont work, in CRM 4.0 it was easy I must be doing something wrong.
I have an onchange event that fires off when the billtoclient field is filled in.
The equation is ClientBillRate - ConsualtantBillRate = Margin
//Margin Calculation
}
function Margin()
{
var BillLWG = crmForm.all.new_hourlyratebilledtolwg.Datavalue;
var BillClient = crmForm.all.new_hourlyratebilledtoclient.DataValue;
var Result = BillClient - BillLWG;
crmForm.all.new_margin.Datavalue = Result;This isnt doing anything at all no errors but nothing works.
Tuesday, July 2, 2013 8:34 PM
All replies
-
Hi,
It's not recommended to use the crmForm object in CRM2011 - rather you should use the Xrm API (http://msdn.microsoft.com/en-us/library/jj602964.aspx)
I would expect that the quickest way to achieve this is to use N52 formual manager - there is a free edition that gives you 10 formulas!
http://www.north52.com/formulamanager.html
Scott Durow
Blog www.develop1.netFollow Me
Rockstar365
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful"- Edited by Scott Durow (MVP)MVP, Editor Tuesday, July 2, 2013 8:47 PM edit
Tuesday, July 2, 2013 8:46 PMAnswerer -
Ok I switched it to this
//Margin Calculation
function Margin() {
var BillLWG = Xrm.Page.data.entity.attributes.get("new_hourlyratebilledtolwg").getValue();
var BillClient = Xrm.Page.data.entity.attributes.get("new_hourlyratebilledtoclient").getValue();var Result = BillClient - BillLWG;
Xrm.Page.data.entity.attributes.get("new_margin").setvalue(Result);
}When I try to update the new_hourlyratebilledtoclient field it gives me the error: the value of the property 'Margin' is null or undefined, not a function object. I set it up as an onchange function and set it to enabled anything I am missing?
- Edited by pslager Tuesday, July 2, 2013 9:02 PM update code
Tuesday, July 2, 2013 8:50 PM -
Something like:
var new_hourlyratebilledtolwg = Xrm.Page.getAttribute('new_hourlyratebilledtolwg').getValue(); var new_hourlyratebilledtoclient = Xrm.Page.getAttribute('new_hourlyratebilledtoclient').getValue(); if (new_hourlyratebilledtolwg != null && new_hourlyratebilledtoclient != null) { var new_margin = new_hourlyratebilledtoclient - new_hourlyratebilledtoclient; Xrm.Page.getAttribute('new_margin').setValue(new_margin); }
hth
Scott Durow
Blog www.develop1.netFollow Me
Rockstar365
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful"- Proposed as answer by Scott Durow (MVP)MVP, Editor Tuesday, July 2, 2013 9:11 PM
Tuesday, July 2, 2013 9:02 PMAnswerer -
your code is ok except the setvalue (needs to be setValue), but is better to use the code written by Scott Durow because it checks also for null values.
the error "the value of the property 'Margin' is null or undefined, not a function object" makes me think that maybe you have several libraries inside this form and you chose the wrong one and not the one containing the function Margin.
My blog: www.crmanswers.net
- Edited by Guido PreiteMVP Wednesday, July 3, 2013 6:34 AM fixed
Tuesday, July 2, 2013 9:22 PM -
Hi,
you can use following javascript function on "OnLoad" of form / "OnChange" event of regarding field.
javascript function:
{
var BillLWG = Xrm.Page.getAttribute('new_hourlyratebilledtolwg').getValue();
alert(BillLWG);
var BillClient = Xrm.Page.getAttribute('new_hourlyratebilledtoclient').getValue();
alert(BillClient);if BillLWG != null && BillClient != null)
{
var Result = BillClient - BillLWG;
alert(Result);
Xrm.Page.getAttribute('new_margin').setValue(Result);
}//end if
}//end function marginHope this helps.
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful"
Wednesday, July 3, 2013 6:11 AM -
Thanks everyone for the code. I am still getting that error about null. Its only when I add this code. I have attached two screen shots showing my setup. I am only using one JavaScript library so I don't see the issue. If I delete the function from the javascript it works. I should also mention I have quite a bit of other javascript there for Google Maps and some other stuff ill post the entirety of it here.
function OnCrmPageLoad()
{
ReArangeTabIndex();
}function ReArangeTabIndex()
{
for( var i = 0 ; i < crmForm.all.length ; i++ )
{
var element = crmForm.all[ i ];
if (element.tabIndex)
{
if (element.className == "ms-crm-Hidden-NoBehavior" || element.tagName == "A")
{
continue;
}
element.tabIndex = 1000 + (i*10);
}
}
}OnCrmPageLoad();
function IFRAME_MapURL_onload()
{
}
function Form_onload()
{
crmForm.Save();function margin()
{
var BillLWG = Xrm.Page.getAttribute('new_hourlyratebilledtolwg').getValue();
alert(BillLWG);
var BillClient = Xrm.Page.getAttribute('new_hourlyratebilledtoclient').getValue();
alert(BillClient);
if BillLWG != null && BillClient != null)
{
var Result = BillClient - BillLWG;
alert(Result);
Xrm.Page.getAttribute('new_margin').setValue(Result);
}//end if
}//end function margin
// Load Map URL
{
var AccountStreet = crmForm.all.new_street1.DataValue;
var AccountSt2=crmForm.all.new_street2.DataValue;
var AccountCity= crmForm.all.new_city.DataValue;
var AccountState = crmForm.all.new_stateprovince.DataValue;
var AccountZip = crmForm.all.new_zippostalcode.DataValue;
var AccountCtry =crmForm.all.new_country.DataValue;var MapURL = "http://maps.google.com/?q=" + AccountStreet + ", " + AccountCity + ", " + AccountZip + " " + AccountCtry;
if (MapURL != null)
{
crmForm.all.IFRAME_MapURL.src = MapURL;
}
}
/**************************************************************
* Change the default view of a view selection combo box
**************************************************************/
SetDefaultView = function(viewCombo, viewName, appGrid) {/* If the view has already been set, we don't need to do it again. */
if (viewCombo.value != viewName) {/* Set the new view */
viewCombo.value = viewName;/* Call RefreshGridView to run the code in the DHTML control.
* Without this call, only the selection in the combo box changes,
* but not the content of the grid */
appGrid.RefreshGridView();
}
}/**************************************************************
* Event handler. Called whenever the ready state of the
* areaActivityHistoryFrame changes.
**************************************************************/
areaActivityHistoryFrame_OnReadyStateChange = function() {/* Waiting until the frame has finished loading */
if (this.readyState == "complete") {/* This is the frame we're interested in */
var frame = document.frames("areaActivityHistoryFrame");/* And this is the view combo box */
var viewCombo = frame.document.getElementById("actualend");/* This is the AppGridFilterContainer control we need to refresh the view */
var appGrid = frame.document.getElementById("AppGridFilterContainer");/* The view combo box uses a style sheet that references a HTML
* control. We have to wait until the htc file is loaded,
* otherwise the call to FireOnChange in the SetDefaultView
* method will fail. */
if (viewCombo.readyState == "complete") {/* If the control already has finished loading, we can
* directly set the new view. */
SetDefaultView(viewCombo, "All", appGrid);
}else {
/* Otherwise we have to register another event handler
* waiting until all of the include files used by the
* combo box are loaded as well. */
viewCombo.onreadystatechange = function() {
if (this.readyState == "complete") {
SetDefaultView(this, "All", appGrid);
}
}
}
}
}/* Set a new onclick event for the History navigation element
* This is where we register the onreadystatechange event handler */
if (document.getElementById('navActivityHistory') != null) {
document.getElementById('navActivityHistory').onclick = function() {
loadArea('areaActivityHistory');
document.frames('areaActivityHistoryFrame').document.onreadystatechange = areaActivityHistoryFrame_OnReadyStateChange;
}
}
crmForm.all.new_technicalbackground.title = "The level to which the expert has undertaken necessary training, developed his/her qualifications and accumulated techinical knowledge that would help LWG provide expert services to its clients";
crmForm.all.new_relevantexperience.title = "The level to which the expert can demonstrate work experience relevant to his/her area of expertise";
crmForm.all.new_forensicprocess.title = "The level to which the expert understands the application of the scientific method in forensic investigations, appreciates the legal ramifications of the job and can accurately apply recognized standards";
crmForm.all.new_forensicexperience.title = "The level to which the expert has successfully conducted forensic investigations into cause and origin of failures";
crmForm.all.new_testimonyexperience.title = "The level to which the expert has testified in different jurisdications";
crmForm.all.new_verbalpresentations.title = "The level to which the expert can present complex technical matters in a non-technical way that facilitates understanding by average non-technical persons";
crmForm.all.new_communicationskills.title = "The level to which the expert can present their thoughts coherently and clearly while staying focused on the area of discussion without distractors and digression";
crmForm.all.new_writtenpresentations.title = "The level to which the expert can explain and present technical matters clearly and concisely to non-technical readers in a written format";
}
function Form_onsave()
{
crmForm.all.new_membernumber.ForceSubmit = true;
}
function new_lastname_onchange()
{
var Year = crmForm.all.createdon.DataValue.getYear();
var Month = crmForm.all.createdon.DataValue.getMonth()+1;
var Day = crmForm.all.createdon.DataValue.getDate();
var Fn = crmForm.all.new_firstname.DataValue;
var Ln = crmForm.all.new_lastname.DataValue;
crmForm.all.new_membernumber.DataValue = Fn.substring(0,1)+Ln.substring(0,2)+Year.toString()+Month.toString()+Day.toString();
}
function new_stateprovince_onchange()
{}
function new_country_onchange()
{
// Load Map URL
{
var AccountStreet = crmForm.all.new_street1.DataValue;
var AccountSt2=crmForm.all.new_street2.DataValue;
var AccountCity= crmForm.all.new_city.DataValue;
var AccountState = crmForm.all.new_stateprovince.DataValue;
var AccountZip = crmForm.all.new_zippostalcode.DataValue;
var AccountCtry =crmForm.all.new_country.DataValue;var MapURL = "http://maps.google.com/?q=" + AccountStreet + ", " + AccountCity + ", " + AccountZip + " " + AccountCtry;
if (MapURL != null)
{
crmForm.all.IFRAME_MapURL.src = MapURL;
}
}
/**************************************************************
* Change the default view of a view selection combo box
**************************************************************/
SetDefaultView = function(viewCombo, viewName, appGrid) {/* If the view has already been set, we don't need to do it again. */
if (viewCombo.value != viewName) {/* Set the new view */
viewCombo.value = viewName;/* Call RefreshGridView to run the code in the DHTML control.
* Without this call, only the selection in the combo box changes,
* but not the content of the grid */
appGrid.RefreshGridView();
}
}/**************************************************************
* Event handler. Called whenever the ready state of the
* areaActivityHistoryFrame changes.
**************************************************************/
areaActivityHistoryFrame_OnReadyStateChange = function() {/* Waiting until the frame has finished loading */
if (this.readyState == "complete") {/* This is the frame we're interested in */
var frame = document.frames("areaActivityHistoryFrame");/* And this is the view combo box */
var viewCombo = frame.document.getElementById("actualend");/* This is the AppGridFilterContainer control we need to refresh the view */
var appGrid = frame.document.getElementById("AppGridFilterContainer");/* The view combo box uses a style sheet that references a HTML
* control. We have to wait until the htc file is loaded,
* otherwise the call to FireOnChange in the SetDefaultView
* method will fail. */
if (viewCombo.readyState == "complete") {/* If the control already has finished loading, we can
* directly set the new view. */
SetDefaultView(viewCombo, "All", appGrid);
}else {
/* Otherwise we have to register another event handler
* waiting until all of the include files used by the
* combo box are loaded as well. */
viewCombo.onreadystatechange = function() {
if (this.readyState == "complete") {
SetDefaultView(this, "All", appGrid);
}
}
}
}
}/* Set a new onclick event for the History navigation element
* This is where we register the onreadystatechange event handler */
if (document.getElementById('navActivityHistory') != null) {
document.getElementById('navActivityHistory').onclick = function() {
loadArea('areaActivityHistory');
document.frames('areaActivityHistoryFrame').document.onreadystatechange = areaActivityHistoryFrame_OnReadyStateChange;
}
}
}
function new_membernumber_onchange()
{}
- Proposed as answer by Thymio Barbatsis (MSFT) Thursday, June 5, 2014 12:11 AM
- Unproposed as answer by Thymio Barbatsis (MSFT) Thursday, June 5, 2014 12:11 AM
Wednesday, July 3, 2013 4:30 PM -
I think you are missing {} on your CRMForm.Save() line. I added them in the code below.
crmForm.Save();
{
}
function margin()
{
var BillLWG = Xrm.Page.getAttribute('new_hourlyratebilledtolwg').getValue();
alert(BillLWG);
var BillClient = Xrm.Page.getAttribute('new_hourlyratebilledtoclient').getValue();
alert(BillClient);
if BillLWG != null && BillClient != null)
{
var Result = BillClient - BillLWG;
alert(Result);
Xrm.Page.getAttribute('new_margin').setValue(Result);
}//end if
}//end function marginThursday, June 5, 2014 12:11 AM