Php Magento+;JQuery+;Ajax—如何只重新加载自定义模块的一部分而不是整个模块?
最近,我的任务是在5天内为我们的Magento模板创建一个简单的产品配置程序,您可以在其中选择一些属性,它为您计算价格,淡出新图像,并将“添加到购物车”按钮更改为新产品 在此之前,我没有PHP或JQuery方面的经验,只有一些Magento方面的基础知识(以前从未做过自定义模块)。我唯一的编程背景是动作脚本3中的OOP游戏 到目前为止,我的代码以某种方式工作。我有一些变量可以通过单击一些单选按钮来更改,这些变量通过ajax方法更新。作为URL,调用我的块索引方法,它只加载和呈现我的布局。将返回的HTML(这是我的整个块)添加到块中最外层div的父级之后。它可以工作,但我似乎找不到一种方法来设置更改的动画,而且如果每次用户只更改一个选项时ajax就重建整个块,那么速度似乎有点慢 是否有一种更优雅的方式来重新加载更改的部分,平滑地设置更改的动画,并使我的块记住所做的输入 以下是供下载的源文件: 如果您需要查看网站本身,请发消息给我:) 提前谢谢 我的区块phtml:Php Magento+;JQuery+;Ajax—如何只重新加载自定义模块的一部分而不是整个模块?,php,ajax,magento,jquery,Php,Ajax,Magento,Jquery,最近,我的任务是在5天内为我们的Magento模板创建一个简单的产品配置程序,您可以在其中选择一些属性,它为您计算价格,淡出新图像,并将“添加到购物车”按钮更改为新产品 在此之前,我没有PHP或JQuery方面的经验,只有一些Magento方面的基础知识(以前从未做过自定义模块)。我唯一的编程背景是动作脚本3中的OOP游戏 到目前为止,我的代码以某种方式工作。我有一些变量可以通过单击一些单选按钮来更改,这些变量通过ajax方法更新。作为URL,调用我的块索引方法,它只加载和呈现我的布局。将返回的
<?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>
白色
黑色
灰色
缺货
">
var$col=“000000”;
var$type=“高级”;
var$size=“3050x2150”;
函数ajaxUpdate()
{
$j.ajax({
url:“/doorconfig/ajax/index”,
类型:“POST”,
数据:{color:$col,type:$type,size:$size},
上下文:$j(“#门包装器”).parent(),
成功:功能(数据)
{
$j(this.html(data)。$(this.fadeIn(slow);
}
});
};
$j(文档).ready(函数()
{
$j(“输入[名称=切换]:收音机”)。更改(函数()
{
ajaxUpdate();
})
});
我的区块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();
}
}
?>
所以我想出了一个非常有效的解决方案。我添加了另一个控制器操作和一个模型,在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>
var$price=“”;
var$baseImgUrl=“”;
var$productUrl=“”;
var$productId=“”;
var$f=$j(“属性形式”);
var$formData;
var$currentStoreUrl=“”;
函数ajaxUpdate()
{
$j.ajax({
url:“/doorconfig/index/update”,
类型:“POST”,
数据:$formData,
数据类型:“json”,
成功:功能(数据)
{
$productId=data.currentProductId;
$price=data.currentPrice;
$baseImgUrl=data.currentProductBaseImgUrl;
$productUrl=data.currentProductUrl;
$j(“#结果”).text($price);
$j(“#addtocart”).attr('href',$currentStoreUrl+”签出/购物车/添加?产品=“+$productId+”&qty=1”);
$j(“#productimg”).attr('src',$baseImgUrl);
控制台日志(数据);
},
错误:函数(错误)
{
日志(“错误:”);
console.log(错误);
警报(“错误”);
}
});
};
$j(文档).ready(函数()
{
$j(“#结果”)。文本(“”);
$j(“#addtocart”).attr('href','';
$j(“#moreinfo”).attr('href','';
$j(“#productimg”).attr('src',”);
$j(“#attributeform”)[0]。重置();
$j(“form[name=attributeform]”)。更改(函数()
{
$formData=$f.serialize();
ajaxUpdate();
})
});
如果您需要任何进一步的解释或想要改进某些内容,请发表评论:)我正在一点一点地弄清楚理论。当前的行为非常合理,因为我称我的控制器在任何ajax事件上呈现布局,html每次都会重新加载。因此我需要第二个控制器动作或模型,然后wers my ajax调用并给我新的产品值。在通过jQuery更改DOM并继续侦听更改后。phtml只需从Magento获取初始数据,并初始化配置程序的选择和颜色字段。但仍然存在问题:我需要什么,模型,新控制器操作还是新控制器?这是好的吗尝试在另一个控制器操作中收集数据?我是否有权访问Block.php中的函数?有这么多问题,请给我一个提示,以正确的方式解决:)我必须在Mage中完成类似的事情。一名团队成员编写了模块,我连接了ajax。我使用jQuery发布到他编写的操作方法在控制器中。