Refreshing the parent node when a child changes
From Achievo/ATK Wiki
|
ATK Howto: Refreshing the parent node when a child changes
|
Summary
As of this writing, when you add an item to a one-to-many node from the parent node, ATK would not automatically obtain the latest values from the parent node when it returns to it. If your child node does not affect the values of the parent node, then this is fine, however, if some values of your parent node get updated by your child node, then this could cause major inconsistency and potential problems.
In this document, I'm going to illustrate some of the steps taken to force the parent node to refresh when returning from a child node.
Problem
In my case I'm currently building an Online e-Commerce Store, which has an “Order” and a “Order Detail” (or Order Line as sometimes called).
When I add a new “Order Detail” to the order, I update the "Grand Total" field of the parent "Order" node to reflect the new addition of the “subtotal” of the "Order Detail" node.
The problem was, after adding or updating the “Order Detail” the parent, “Order” node would still show the “Grand Total”, “Shipping Charge” and “Tax Amount” located on the page prior to my new addition, even though the fresh values would be on the database table.
To make matters worse, when I would save the parent “Order”, the correct values on the database table (updated by the “Order Detail” node) would be overwritten by the old values on the screen, which would throw off my calculations completely.
Solution
The way I solved this problem was by calling a function called “_redirectOrder()” after “postUpdate()”, “postDelete()” and “postAdd()” to make sure my “Order” totals would be updated during updates, deletion and addition of new “Order Detail”.
Below is the code snippet I used. Variables are used in the “_redirectOrder()” function to make it easier to replace the values to anything of your convenient:
// this function is automatically called after a record has been updated public function postUpdate($record) { $this->_redirectOrder($record); return true; }
// this function is automatically called after a record has been deleted public function postDelete($record) { $this->_redirectOrder($record); return true; }
// this function is automatically called after a record has been added public function postAdd(&$record) { $this->_redirectOrder($record); return true; }
/*
Force direct of master node
*/
protected function _redirectOrder($record)
{
$master_node_primary_field = "wbiz_order_id";
$master_node_id_value = $record[$master_node_primary_field][$master_node_primary_field];
$master_node_name = "wbiz_order";
$master_node_module = $this->module;
if (!empty($master_node_id_value)) {// force master redirect, since ATK currently does not
$pparams["atktab"] = "some_tab_name";// Optional - sets focus to this tab in the master node
// NOTE: tab name is CASE SENSITIVE !!
$pparams["wbiz_order_id"] = $master_node_id_value;
$pparams["atkselector"] = $master_node_name.".".$master_node_primary_field."='".$master_node_id_value."'";
$pparams["atknodetype"] = $master_node_module.".".$master_node_name;
// link name
$url = dispatch_url($this->module.".".$master_node_name, "edit", $pparams);
$this->redirect($url);
die();
}// end if
} // end function
I’m sure there are solutions, but this is the one that worked best for me.
Until next time,
The above solution only displays a "Save" button and NOT "Save and close" + "Cancel" because no atklevel or stack values are used
To use levels and display these buttons see the forum posting http://forum.achievo.org/viewtopic.php?f=2&t=12781
It involves adding in extra $pparams values - eg
$pparams["atkprevlevel"] = 0 ; $pparams["atklevel"] = 1 ; $pparams["atkstackid"] = atkStackID();
Note that you will need to hardcode the level values for each particular situation
Wayne