Magento + JQuery + Ajax - Làm cách nào để tôi tải lại chỉ một phần của Mô-đun tùy chỉnh thay vì toàn bộ Khối?


7

Gần đây tôi đã được giao nhiệm vụ tạo một bộ cấu hình Sản phẩm đơn giản cho Mẫu Magento của chúng tôi trong 5 ngày, nơi bạn có thể chọn một số thuộc tính và nó tính giá cho bạn, làm mờ hình ảnh mới và thay đổi nút thêm vào giỏ hàng thành mới sản phẩm.

Trước đó, tôi không có kinh nghiệm về PHP hoặc JQuery và chỉ có một số điều cơ bản về Magento (chưa bao giờ thực hiện một mô-đun tùy chỉnh nào trước đây.) Nền tảng lập trình duy nhất của tôi là OOP Games trong Action Script 3.

Cho đến nay mã của tôi hoạt động bằng cách nào đó. Tôi có một số biến mà tôi có thể thay đổi khi nhấp vào một số nút radio và các biến được cập nhật thông qua phương pháp ajax. Khi URL, phương thức chỉ mục khối của tôi được gọi, chỉ tải và hiển thị bố cục của tôi. Sau khi tôi thêm HTML được trả về (là toàn bộ khối của tôi) vào cha mẹ của div ngoài cùng trong khối của tôi. Nó hoạt động nhưng dường như tôi không thể tìm ra cách để làm động các thay đổi và có vẻ hơi chậm nếu ajax xây dựng lại toàn bộ khối mỗi khi người dùng chỉ thay đổi một tùy chọn.

Có cách nào thanh lịch hơn để chỉ tải lại các phần đã thay đổi, làm mượt các thay đổi và làm cho khối của tôi ghi nhớ các thay đổi trong đầu vào của tôi không?

Dưới đây là tất cả các tệp để tải xuống: http://www.roflxd.de/doorconfig.zip

Nếu bạn cần truy cập vào trang web để xem nó hiện như thế nào, xin vui lòng nhắn tin cho tôi :)

Cảm ơn trước!

Khối của tôi 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>

Khối php của tôi:

    <?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';
    }
}

?>

Và AjaxControll.php của tôi

    <?php

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

}
?>

Tôi đang tìm ra lý thuyết từng mảnh. Hành vi hiện tại có ý nghĩa hoàn hảo, khi tôi gọi bộ điều khiển của mình để hiển thị bố cục trên bất kỳ sự kiện ajax nào, html được tải lại mỗi lần. Vì vậy, tôi cần một cái gì đó giống như một hành động hoặc mô hình bộ điều khiển thứ hai để trả lời các cuộc gọi ajax của tôi và cung cấp cho tôi các giá trị sản phẩm mới. Sau khi DOM được thay đổi thông qua jQuery và tiếp tục lắng nghe những thay đổi. Phtml sẽ chỉ lấy dữ liệu ban đầu từ Magento và khởi tạo các trường chọn và màu cho bộ cấu hình. Nhưng vẫn còn câu hỏi: tôi cần gì, mô hình, hành động của bộ điều khiển mới hay bộ điều khiển mới?
ericstumper

Có phải là thực hành tốt để thu thập dữ liệu trong một hành động điều khiển khác? Tôi có quyền truy cập vào các chức năng từ Block.php của mình không? Rất nhiều câu hỏi, xin vui lòng cho tôi một gợi ý để giải quyết vấn đề này một cách chính xác :)
ericstumper

Câu trả lời:


2

Vì vậy, tôi đã đưa ra một giải pháp hoạt động tuyệt vời. Tôi đã thêm một hành động điều khiển khác và một mô hình để thực hiện Tương tác Magento trong các cuộc gọi ajax của tôi. Vì vậy, hãy để tôi chỉ cho bạn cách nó được thực hiện, tôi hy vọng ai đó có thể kiếm lợi từ việc này sớm hay muộn :)

Hành động mới của tôi:

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

Mô hình của tôi chỉ có hầu hết logic kinh doanh từ khối của tôi, vì vậy không có gì đặc biệt để chỉ ra điều đó.

Và cuối cùng, phần Ajax được cập nhật hiện kích hoạt hành động điều khiển mới của tôi, nhận kết quả dưới dạng mã hóa JSON và thay đổi các giá trị trong 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>

Nếu bạn cần bất kỳ lời giải thích thêm hoặc muốn cải thiện một cái gì đó xin vui lòng bình luận :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.