2013-06-04 51 views
2

我剛剛獲得了5天內爲Magento模板創建一個簡單的產品配置器的任務,您可以在其中選擇一些屬性,併爲您計算價格,淡化新圖像並將添加到購物車按鈕更改爲新產品。Magento + JQuery + Ajax - 如何重新加載我的自定義模塊的一部分而不是整個塊?

此之前,我曾在PHP或JQuery的在Magento沒有經驗,只是一些基本的(以前從未做過一個自定義模塊。)我唯一的編程背景是OOP遊戲中的Action Script 3

到目前爲止我的代碼工作不知何故。我有一些變量,我可以通過單擊某些單選按鈕來更改變量,並通過ajax方法更新變量。作爲URL我的塊索引方法被調用,它只是加載和呈現我的佈局。將我返回的HTML(這是我的整個塊)添加到我的塊中最外面的div的父項之後。它的工作原理,但我似乎無法找到一種方式來動畫的變化,如果每次用戶只改變一個選項時,ajax重建整個塊,似乎有點慢。

是否有一種更加優雅的方式來重新加載已更改的零件,平滑地生成更改並使我的塊記住所做的輸入?

下面是源文件下載:http://www.roflxd.de/doorconfig.zip

如果你需要看網站本身,請留言給我:)

在此先感謝!

我的阻止PHTML:

<?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->getProduct($type,$color,$size); 

       $currentId = $currentProduct->getId(); 

       $currentUrl = $currentProduct->getProductUrl();   

       $currentPrice = $this->getPrice($currentId); 

       $currentImgUrl = $this->getDoorBaseImgUrl($type, $size); 

?> 

<div id="door_wrapper" class=""> 
    <div id="door_left_wrapper" class="mj-grid48"> 

     <form id="testform"> 

      <div id="door_colors"> 

       <label id="FFFFFF">White<input type="radio" name="toggle" value="FFFFFF"></label> 
       <label id="000000">Black<input type="radio" name="toggle" value="000000"></label> 
       <label id="736D6C">Grey<input type="radio" name="toggle" value="736D6C"></label> 

      </div> 

      <div id="door_model" > 

       <?php print_r($_POST); ?> 

       <?php echo $type;?> 
       <?php echo $color;?> 
       <?php echo $size;?> 

       <br> 

       <?php echo $currentImgUrl;?> 
      </div> 

      <div id="door_size"> 

       <select name="doorsizes"> 
       </select> 

      </div> 

      <?php if ($currentProduct->isSaleable()): ?> 
       <button type="button"> 
        <a href="<?php echo $currentStoreUrl . "checkout/cart/add?product=" . $currentId . "&qty=1";?>"> 
         Test 
        </a> 
       </button> 
      <?php else: ?> 
       <button disabled>Out of Stock</button> 
      <?php endif;?> 

     </form> 

    </div> 

    <div id="door_right_wrapper" class="mj-grid48"> 

     <div id="door_img"> 
      <img src="<?php echo $currentImgUrl;?>"> 
     </div> 

     <div id="result"></div> 
    </div> 

</div> 

<script type="text/javascript"> 

    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(); 
                   }) 
         }); 

</script> 

我的阻止PHP:

<?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')->getCollection(); 

     //Select needed Attributes 
     $collection->addAttributeToSelect('doorconfig_enable'); 
     $collection->addAttributeToSelect('doorconfig_color'); 
     $collection->addAttributeToSelect('doorconfig_size'); 
     $collection->addAttributeToSelect('doorconfig_type'); 

     //Filter for Selected Product 
     $collection->addFieldToFilter('doorconfig_enable', 
       array(
         'eq' => Mage::getResourceModel('catalog/product') 
            ->getAttribute('doorconfig_enable') 
            ->getSource() 
            ->getOptionId('Yes') 
        ) 
     ); 

     $collection->addFieldToFilter('doorconfig_color', 
       array(
         'eq' => Mage::getResourceModel('catalog/product') 
            ->getAttribute('doorconfig_color') 
            ->getSource() 
            ->getOptionId($color) 
        ) 
     ); 

     $collection->addFieldToFilter('doorconfig_size', 
       array(
         'eq' => Mage::getResourceModel('catalog/product') 
            ->getAttribute('doorconfig_size') 
            ->getSource() 
            ->getOptionId($size) 
        ) 
     ); 

     $collection->addFieldToFilter('doorconfig_type', 
       array(
         'eq' => Mage::getResourceModel('catalog/product') 
            ->getAttribute('doorconfig_type') 
            ->getSource() 
            ->getOptionId($type) 
        ) 
     ); 

     $product = $collection->getFirstItem(); 

     return $product; 
    } 

    public function getPrice($id) 
    { 
     $product = Mage::getModel('catalog/product')->load($id); 
     $_taxHelper = new Mage_Tax_Helper_Data; 
     $finalprice = $_taxHelper->getPrice($product, $product->getFinalPrice(), true); 
     $finalprice .= $this->getCurrency(); 
     return $finalprice; 
    } 

    public function getCurrency() 
    { 
     return Mage::app()->getLocale()->currency(Mage::app()->getStore()->getCurrentCurrencyCode())->getSymbol(); 
    } 

    public function getDoorImageDir() 
    { 
     return Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA) . 'wysiwyg/geeklab/doorconfig/'; 
    } 

    public function getDoorBaseImgUrl($type, $size) 
    { 
     return $this->getDoorImageDir() . strtolower($size) . '_' . str_replace("\040", "\137", strtolower($type)) . '.png'; 
    } 

    public function getDoorColorImgUrl($color, $size) 
    { 
     return $this->getDoorImageDir() . strtolower($size) . '_' . strtolower($color) . '.png'; 
    } 
} 

?> 

而且我AjaxController.php

<?php 

class Geeklab_DoorConfig_AjaxController extends Mage_Core_Controller_Front_Action 
{ 
    public function indexAction() 
    { 
     $this->loadLayout(); 
     $this->renderLayout(); 
    } 

} 
?> 
+0

我正在逐塊計算理論。當前的行爲非常有意義,因爲我稱之爲控制器,它在任何ajax事件上呈現佈局,每次都會重新加載html。所以我需要第二個控制器動作或模型,然後回答我的ajax調用,併爲我提供新的產品價值。通過jQuery更改DOM後,繼續監聽更改。 phtml只會從Magento獲取初始數據並初始化配置程序的選擇和顏色字段。但問題仍然存在:我需要什麼,型號,新控制器動作或新控制器? – ericstumper

+0

在另一個控制器操作中收集數據是否很好?我可以訪問我的Block.php中的功能嗎?如此多的問題,請給我一個提示,以正確的方式解決這個問題:) – ericstumper

+0

我必須在法師中做出確切的事情。一個團隊成員寫了這個模塊,然後我連接了ajax。我使用jQuery發佈到他在控制器中編寫的操作方法。 [Alan Storm's](http://alanstorm.com/category/magento)是編寫模塊的好地方。希望這有助於您指出正確的方向。 –

回答

5

於是我想出了工作得真棒的解決方案。我添加了另一個控制器動作和模型,以在我的ajax調用期間執行Magento交互。因此,讓我告訴你它是如何做的,我希望有人可以從這個遲早:)

我的新的行動中獲益:

public function updateAction() 
    { 

     //Instantiate Product Model 
     $productModel = Mage::getModel('doorconfig/product'); 

     //Get Updated Values from the Model 
     $currentProduct = $productModel->getProduct($_POST); 
     $currentProductId = $currentProduct->getId(); 
     $currentProductUrl = $currentProduct->getProductUrl(); 
     $currentPrice = $productModel->getPrice($currentProductId); 
     $currentType = $this->getRequest()->getPost('doorconfig_type'); 
     $currentSize = $this->getRequest()->getPost('doorconfig_size'); 
     $currentProductBaseImgUrl = $productModel->getDoorBaseImgUrl($currentType,$currentSize); 

     //Populate Resultarray 
     $result = array("currentProductId"=>$currentProductId,"currentPrice"=>$currentPrice,"currentProductUrl"=>$currentProductUrl,"currentProductBaseImgUrl"=>$currentProductBaseImgUrl); 

     //Encode Result in JSON 
     $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); 

     return $result; 
    } 

我的模型只是得到大多數從我的塊中的業務邏輯,所以沒有什麼特別的要指出的。

最後更新的Ajax部分現在觸發我的新控制器動作,接收結果作爲JSON編碼,並在DOM改變值:

<script type="text/javascript"> 

    var $price = ""; 
    var $baseImgUrl = ""; 
    var $productUrl = ""; 
    var $productId = ""; 
    var $f = $j("#attributeform"); 
    var $formData; 
    var $currentStoreUrl = "<?php echo $currentStoreUrl ?>"; 

    function ajaxUpdate() 
    { 

     $j.ajax({ 
     url: "/doorconfig/index/update", 
     type: "POST", 
     data: $formData, 
     dataType: "json", 
     success: function(data) 
       { 
        $productId = data.currentProductId; 
        $price = data.currentPrice; 
        $baseImgUrl = data.currentProductBaseImgUrl; 
        $productUrl = data.currentProductUrl; 
        $j("#result").text($price); 

        $j("#addtocart").attr('href', $currentStoreUrl + "checkout/cart/add?product=" + $productId + "&qty=1"); 
        $j("#productimg").attr('src', $baseImgUrl); 

        console.log(data); 

        }, 
      error: function(error) 
        { 
        console.log("Error:"); 
        console.log(error); 
        alert("ERROR"); 
        } 
     }); 
    }; 

    $j(document).ready(function() 
    { 

     $j("#result").text('<?php echo $defaultProductPrice; ?>'); 
     $j("#addtocart").attr('href', '<?php echo $currentStoreUrl . "checkout/cart/add?product=" . $defaultProductId . "&qty=1" ?>'); 
     $j("#moreinfo").attr('href', '<?php echo $defaultProductUrl; ?>'); 
     $j("#productimg").attr('src', '<?php echo $defaultProductImgUrl; ?>'); 
     $j("#attributeform")[0].reset(); 

     $j("form[name=attributeform]").change(function() 
     { 

     $formData = $f.serialize(); 
     ajaxUpdate(); 
     }) 
    }); 

</script> 

如果您需要任何進一步的解釋或想改善的東西請評論:)

+0

你能告訴我你的xml文件是什麼樣子的。謝謝 :) – 2013-08-29 09:33:35

相關問題