To run your JScript in debug, simply type debugger; on a line before the code you want to be able to step through (thank goodness for MSDN!).
You are using absolute XPath, so that is going to be one problem you are having. I notice a variable called 'handler' -- and you mention it is to prevent an infinite loop error? What was happening there?
The OnAfterChange event is going to fire twice when your field changes, so you should modify the first if statement to make sure that the calculation code only runs when the operation is = to Insert. So change this:
if (eventObj.IsUndoRedo)
To this:
if (eventObj.IsUndoRedo || eventObj.Operation != "Insert")
Then if the operation is Delete (which is going to run when you clear the existing value in the cell, before you fill in a new value), you'll just return and your caclulation code won't run.
Next, you'll want to use eventObj.Site and relative XPath to get your node values, so that you have the values for the same row as the one with the changed field. For example, instead of this:
var plQtyPer = XDocument.DOM.selectSingleNode("/dfs:myFields/dfs:dataFields/d:tblDetailsInfo/@plQtyPer");
Try this:
var plQtyPer = eventObj.Site.selectSingleNode("../@plQtyPer");
Since you are running you code when the plPartCost field changes, you'd reference that node simply as eventObj.Site, like this:
var plPartCost = eventObj.Site;
Finally, I'm not sure why your code isn't running every time the plPartCost field changes, my guess may be that the 'handler' variable isn't always what you think it is. Type debugger; right above that variable so that you can try stepping through your code.