Note that there are some explanatory texts on larger screens.

plurals
  1. POMagento + JQuery + Ajax - How do I reload just parts of my custom Module instead of the whole Block?
    primarykey
    data
    text
    <p>I was just recently given the task to create a simple Product configurator for our Magento Template in 5 days, where you can choose some attributes and it calculates the price for you, fades over a new image and changes the add to cart button to the new product.</p> <p>Before this I had no experience in PHP or JQuery and just some basics in Magento (never done a custom module before.) My only programming Background is OOP Games in Action Script 3.</p> <p>So far my code works somehow. I have some variables that I can change on click of some radio buttons and the variables are updated via the ajax method. As URL my block index method is called which does just load and render my layout. After I add the returned HTML (which is my whole block) to the parent of my outermost div in my block. It works but I can't seem to find a way to animate the changes and it seems kind of slow if the ajax rebuilds the whole block each time the user just changes one option.</p> <p>Is there a more elegant way to just reload the changed parts, smoothly animate the changes and make my block remember the inputs that were made?</p> <p>Here are the source files for download: <a href="http://www.roflxd.de/doorconfig.zip" rel="nofollow">http://www.roflxd.de/doorconfig.zip</a></p> <p>If you need to see the site itself, please message me :)</p> <p>Thanks in advance!</p> <p>My Block phtml:</p> <pre><code> &lt;?php $type = 'Simple'; $color = 'FFFFFF'; $size = '2500x1800'; if (isset($_POST['color'])) { $color = "#" . $_POST['color']; } if (isset($_POST['type'])) { $type = $_POST['type']; } if (isset($_POST['size'])) { $size = $_POST['size']; } $currentStoreUrl = Mage::getBaseUrl(); $currentProduct = $this-&gt;getProduct($type,$color,$size); $currentId = $currentProduct-&gt;getId(); $currentUrl = $currentProduct-&gt;getProductUrl(); $currentPrice = $this-&gt;getPrice($currentId); $currentImgUrl = $this-&gt;getDoorBaseImgUrl($type, $size); ?&gt; &lt;div id="door_wrapper" class=""&gt; &lt;div id="door_left_wrapper" class="mj-grid48"&gt; &lt;form id="testform"&gt; &lt;div id="door_colors"&gt; &lt;label id="FFFFFF"&gt;White&lt;input type="radio" name="toggle" value="FFFFFF"&gt;&lt;/label&gt; &lt;label id="000000"&gt;Black&lt;input type="radio" name="toggle" value="000000"&gt;&lt;/label&gt; &lt;label id="736D6C"&gt;Grey&lt;input type="radio" name="toggle" value="736D6C"&gt;&lt;/label&gt; &lt;/div&gt; &lt;div id="door_model" &gt; &lt;?php print_r($_POST); ?&gt; &lt;?php echo $type;?&gt; &lt;?php echo $color;?&gt; &lt;?php echo $size;?&gt; &lt;br&gt; &lt;?php echo $currentImgUrl;?&gt; &lt;/div&gt; &lt;div id="door_size"&gt; &lt;select name="doorsizes"&gt; &lt;/select&gt; &lt;/div&gt; &lt;?php if ($currentProduct-&gt;isSaleable()): ?&gt; &lt;button type="button"&gt; &lt;a href="&lt;?php echo $currentStoreUrl . "checkout/cart/add?product=" . $currentId . "&amp;qty=1";?&gt;"&gt; Test &lt;/a&gt; &lt;/button&gt; &lt;?php else: ?&gt; &lt;button disabled&gt;Out of Stock&lt;/button&gt; &lt;?php endif;?&gt; &lt;/form&gt; &lt;/div&gt; &lt;div id="door_right_wrapper" class="mj-grid48"&gt; &lt;div id="door_img"&gt; &lt;img src="&lt;?php echo $currentImgUrl;?&gt;"&gt; &lt;/div&gt; &lt;div id="result"&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;script type="text/javascript"&gt; var $col = "000000"; var $type = "Advanced"; var $size = "3050x2150"; function ajaxUpdate() { $j.ajax({ url: "/doorconfig/ajax/index", type: "POST", data: {color : $col, type : $type, size : $size }, context: $j('#door_wrapper').parent(), success: function(data) { $j(this).html(data).$(this).fadeIn(slow); } }); }; $j(document).ready(function() { $j("input[name=toggle]:radio").change(function () { ajaxUpdate(); }) }); &lt;/script&gt; </code></pre> <p>My Block php:</p> <pre><code> &lt;?php class Geeklab_DoorConfig_Block_Doorconfig extends Mage_Core_Block_Template { public function getProduct($type,$color,$size) { //Get Product Collection $collection = Mage::getModel('catalog/product')-&gt;getCollection(); //Select needed Attributes $collection-&gt;addAttributeToSelect('doorconfig_enable'); $collection-&gt;addAttributeToSelect('doorconfig_color'); $collection-&gt;addAttributeToSelect('doorconfig_size'); $collection-&gt;addAttributeToSelect('doorconfig_type'); //Filter for Selected Product $collection-&gt;addFieldToFilter('doorconfig_enable', array( 'eq' =&gt; Mage::getResourceModel('catalog/product') -&gt;getAttribute('doorconfig_enable') -&gt;getSource() -&gt;getOptionId('Yes') ) ); $collection-&gt;addFieldToFilter('doorconfig_color', array( 'eq' =&gt; Mage::getResourceModel('catalog/product') -&gt;getAttribute('doorconfig_color') -&gt;getSource() -&gt;getOptionId($color) ) ); $collection-&gt;addFieldToFilter('doorconfig_size', array( 'eq' =&gt; Mage::getResourceModel('catalog/product') -&gt;getAttribute('doorconfig_size') -&gt;getSource() -&gt;getOptionId($size) ) ); $collection-&gt;addFieldToFilter('doorconfig_type', array( 'eq' =&gt; Mage::getResourceModel('catalog/product') -&gt;getAttribute('doorconfig_type') -&gt;getSource() -&gt;getOptionId($type) ) ); $product = $collection-&gt;getFirstItem(); return $product; } public function getPrice($id) { $product = Mage::getModel('catalog/product')-&gt;load($id); $_taxHelper = new Mage_Tax_Helper_Data; $finalprice = $_taxHelper-&gt;getPrice($product, $product-&gt;getFinalPrice(), true); $finalprice .= $this-&gt;getCurrency(); return $finalprice; } public function getCurrency() { return Mage::app()-&gt;getLocale()-&gt;currency(Mage::app()-&gt;getStore()-&gt;getCurrentCurrencyCode())-&gt;getSymbol(); } public function getDoorImageDir() { return Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA) . 'wysiwyg/geeklab/doorconfig/'; } public function getDoorBaseImgUrl($type, $size) { return $this-&gt;getDoorImageDir() . strtolower($size) . '_' . str_replace("\040", "\137", strtolower($type)) . '.png'; } public function getDoorColorImgUrl($color, $size) { return $this-&gt;getDoorImageDir() . strtolower($size) . '_' . strtolower($color) . '.png'; } } ?&gt; </code></pre> <p>And my AjaxController.php</p> <pre><code> &lt;?php class Geeklab_DoorConfig_AjaxController extends Mage_Core_Controller_Front_Action { public function indexAction () { $this-&gt;loadLayout(); $this-&gt;renderLayout(); } } ?&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. COI am figuring out the theory piece by piece. The current behaviour makes perfect sense, as I call my controller which renders the layout on any ajax event,the html is reloaded each time. So I need something like a second controller action or model which then answers my ajax calls and gives me the new product values. After the DOM is changed via jQuery and continues to listen for changes. The phtml would just get the initial data from Magento and initialize the select and color fields for the configurator . But still the question: what do I need, model, new controller action or new controller?
      singulars
    2. COIs it good practice to collect the data in another controller action? Do I have access to the functions from my Block.php there? So many questions, please give me a hint to solve this in a correct way :)
      singulars
    3. COI have had to do the exact sort of thing in Mage. A team member wrote the module and I hooked up the ajax. I used jQuery to post to an action method he wrote in the controller. [Alan Storm's](http://alanstorm.com/category/magento) site is great place to pick up some good info on writing modules. Hope this helps point you in the right direction.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload