且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在可配置的产品视图Magento上显示动态SKU

更新时间:2023-11-30 12:25:04

脚本几乎正确,除了 $ simple_product-> getSelectLabel()是一个错误的键。在简单的产品模型中不存在这样的方法/属性。为了使脚本工作,该键应该被替换为正确的 - 产品标识。使用产品ID,可以找到所选产品的sku。





所以,首先你需要重组 itemId 数组,使其成为productId => productSku映射:

  $ productMap = array(); 
foreach($ col as $ simpleProduct){
$ productMap [$ simpleProduct-> getId()] = $ simpleProduct-> getSku();
}



那么你需要更改onchange函数调用将Configurable的属性id传递给 changeSku()函数。因此,基础逻辑能够搜索适当的简单产品的属性。

  onchange =return changeSku(<?php echo $ _attribute - > getAttributeId()?> this);> 



之后,您需要使用可配置的配置,以便映射所选的简单产品属性id选择产品ID:

  function changeSku(confAttributeId,sel){
var productMap = ?php echo Mage :: helper('core') - > jsonEncode($ productMap);?&gt ;;
var selectedAttributeId = sel.options [sel.selectedIndex] .value;
if(selectedAttributeId){
var options = spConfig.config.attributes [confAttributeId] .options;
var productId = options.find(function(option){return option.id == selectedAttributeId})。products [0]
$(sku-container)。update(< strong>产品编号:< / strong>+ productMap [productId]);
} else {
$(sku-container)。update(< strong> Product Id:< / strong>选择显示产品ID的选项);
}
}



为了您的参考,以下是整个模板的样子总结(我已经美化了一下):

 <?php 
$ _product = $ this-> getProduct();
$ _attributes = Mage :: helper('core') - > decorateArray($ this-> getAllowAttributes());
?>
<?php if($ _product-> isSaleable()&& count($ _ attributes)):?>
< dl>
<?php foreach($ _属性为$ _attribute):?>
< dt>< label class =required>< em> *< / em><?php echo $ _attribute-> getLabel()?>< / label>&lt ; / DT&GT;
< dd<?php if($ _attribute-> decoratedIsLast){?> class =last<?php}?>>
< div class =input-box>
< select name =super_attribute [<?php echo $ _attribute-> getAttributeId()?>]id =attribute<?php echo $ _attribute-> getAttributeId()?& class =required-entry super-attribute-select
onchange =return changeSku(<?php echo $ _attribute-> getAttributeId()?> this);>
< option><?php echo $ this-> __('选择选项...')?>< / option>
< / select>
< / div>
< / dd>
<?php endforeach; ?&GT;
< / dl>
< script type =text / javascript>
var spConfig = new Product.Config(<?php echo $ this-> getJsonConfig()?>);
< / script>

<?php endif;?>

< div id =sku-container>< / div>

<?php
$ conf = Mage :: getModel('catalog / product_type_configurable') - > setProduct($ _ product);
$ col = $ conf-> getUsedProductCollection() - > addAttributeToSelect('*') - > addFilterByRequiredOptions();

$ productMap = array();
foreach($ col as $ simpleProduct){
$ productMap [$ simpleProduct-> getId()] = $ simpleProduct-> getSku();
}
?>

< script type =text / javascript>

document.observe(dom:loaded,function(){
$(sku-container)。update(< strong> Product Id:< / strong&选择一个选项显示产品编号);
});

函数changeSku(confAttributeId,sel){
var productMap =<?php echo Mage :: helper('core') - > jsonEncode($ productMap);?&
var selectedAttributeId = sel.options [sel.selectedIndex] .value;
if(selectedAttributeId){
var options = spConfig.config.attributes [confAttributeId] .options;
var productId = options.find(function(option){return option.id == selectedAttributeId})。products [0]
$(sku-container)。update(< strong>产品编号:< / strong>+ productMap [productId]);
} else {
$(sku-container)。update(< strong> Product Id:< / strong>选择显示产品ID的选项);
}
}
< / script>

这将完成您最初需要的任务。






另请注意以下


  1. 您的方法将无法正常工作具有两个或多个可配置属性的可配置产品。对于该产品,直到用户选择所有选择输入的值为止,才知道最终的简单产品。因此,在输出SKU之前,应该更改一个方法来检查所有的选择。

  2. 当用户编辑产品配置时,代码不会考虑这种情况,而不是为新产品。您可以从购物车中单击编辑链接进入编辑模式。在这种情况下,所有选择输入将预先填充先前选择的值。但是文本会说选择一个选项来显示产品ID。脚本还可能在编辑模式下产生其他Javascript错误。该代码应稍作修改,以支持编辑模式。

  3. 模板已被逻辑过满。 Magento模板应该只有简单的打印,而 foreach -iterations。所有方法,如 $ conf-> getUsedProductCollection() - > addAttributeToSelect('*') - > addFilterByRequiredOptions()更好地被移动到块。这降低了代码复杂度。
    希望有帮助。


I have this script to show the dynamic sku on select option, but i cannot get working.

Is loading the correct sku, but on select nothing happen.

This code get list of sku on Javascript and update a div on select option for product on configurable product view.

<?php
$_product    = $this->getProduct();
$_attributes = Mage::helper('core')->decorateArray($this->getAllowAttributes());
?>
<?php if ($_product->isSaleable() && count($_attributes)):?>
    <dl>
    <?php foreach($_attributes as $_attribute): ?>
        <dt><label class="required"><em>*</em><?php echo $_attribute->getLabel() ?></label></dt>
        <dd<?php if ($_attribute->decoratedIsLast){?> class="last"<?php }?>>
            <div class="input-box">
                <select name="super_attribute[<?php echo $_attribute->getAttributeId() ?>]" id="attribute<?php echo $_attribute->getAttributeId() ?>" class="required-entry super-attribute-select" onchange="return changeSku(this);">
                    <option><?php echo $this->__('Choose an Option...') ?></option>
                  </select>
              </div>
        </dd>
    <?php endforeach; ?>
    </dl>
    <script type="text/javascript">
        var spConfig = new Product.Config(<?php echo $this->getJsonConfig() ?>);
    </script>

<?php endif;?>


<?php
$conf = Mage::getModel('catalog/product_type_configurable')->setProduct($_product);
$col = $conf->getUsedProductCollection()->addAttributeToSelect('*')->addFilterByRequiredOptions();

echo '<script type="text/javascript">';

echo '
document.observe("dom:loaded", function() {
  $("sku-container").update("<strong>Product Id: </strong> Select an option to display Product Id");
});
';
echo ' function changeSku(sel){';       

$itemId = array();           
foreach($col as $simple_product){
$itemId[] = array($simple_product->getSelectLabel() => $simple_product->getSku());
} 

//echo "<pre>";
//print_r($itemId);
//echo "</pre>";

foreach($itemId as $val){
 foreach($val as $k => $v){
echo "\n".'if(sel.options[sel.selectedIndex].value == "'.$k.'"){'."\n";
echo '$("sku-container").update("<strong>Product Id: </strong>'.$v.'");'. "\n";
echo '}';
    }
}

echo "\n".'if(sel.options[sel.selectedIndex].value == ""){'."\n";
echo '$("sku-container").update("<strong>Product Id: </strong> Select an option to display Product Id");'. "\n";
echo '}'; 

echo "}";
echo "\n</script>";
?>

I appreciate any help.

Thanks

The script is almost correct except for $simple_product->getSelectLabel() being a wrong key. No such method/property exists in a simple product model. In order to make the script work, this key should be replaced with a right one - a Product Id. Utilizing product id, it is possible to find the sku of the product being selected.


So, first of all you need to reorganize itemId array to make it a "productId => productSku" map:

$productMap = array();
foreach($col as $simpleProduct){
    $productMap[$simpleProduct->getId()] = $simpleProduct->getSku();
}


Then you need to change the "onchange" function call to pass Configurable's attribute id to the changeSku() function. Thus the underlying logic is able to search appropriate simple product's attributes.

onchange="return changeSku(<?php echo $_attribute->getAttributeId() ?>, this);">


And after that you need utilize configurable's config in order to map selected simple product's attribute id to the product id selected:

function changeSku(confAttributeId, sel) {
    var productMap = <?php echo Mage::helper('core')->jsonEncode($productMap);?>;
    var selectedAttributeId = sel.options[sel.selectedIndex].value;
    if (selectedAttributeId) {
        var options = spConfig.config.attributes[confAttributeId].options;
        var productId = options.find(function (option) {return option.id == selectedAttributeId}).products[0]
        $("sku-container").update("<strong>Product Id: </strong>" + productMap[productId]);
    } else {
        $("sku-container").update("<strong>Product Id: </strong> Select an option to display Product Id");
    }
}


For your reference, below is the summary of how the whole template looks like (I've beautified it a little):

<?php
$_product    = $this->getProduct();
$_attributes = Mage::helper('core')->decorateArray($this->getAllowAttributes());
?>
<?php if ($_product->isSaleable() && count($_attributes)):?>
<dl>
    <?php foreach($_attributes as $_attribute): ?>
    <dt><label class="required"><em>*</em><?php echo $_attribute->getLabel() ?></label></dt>
    <dd<?php if ($_attribute->decoratedIsLast){?> class="last"<?php }?>>
        <div class="input-box">
            <select name="super_attribute[<?php echo $_attribute->getAttributeId() ?>]" id="attribute<?php echo $_attribute->getAttributeId() ?>" class="required-entry super-attribute-select"
                    onchange="return changeSku(<?php echo $_attribute->getAttributeId() ?>, this);">
                <option><?php echo $this->__('Choose an Option...') ?></option>
            </select>
        </div>
    </dd>
    <?php endforeach; ?>
</dl>
<script type="text/javascript">
    var spConfig = new Product.Config(<?php echo $this->getJsonConfig() ?>);
</script>

    <?php endif;?>

<div id="sku-container"></div>

<?php
$conf = Mage::getModel('catalog/product_type_configurable')->setProduct($_product);
$col = $conf->getUsedProductCollection()->addAttributeToSelect('*')->addFilterByRequiredOptions();

$productMap = array();
foreach($col as $simpleProduct){
    $productMap[$simpleProduct->getId()] = $simpleProduct->getSku();
}
?>

<script type="text/javascript">

document.observe("dom:loaded", function() {
  $("sku-container").update("<strong>Product Id: </strong> Select an option to display Product Id");
});

function changeSku(confAttributeId, sel) {
    var productMap = <?php echo Mage::helper('core')->jsonEncode($productMap);?>;
    var selectedAttributeId = sel.options[sel.selectedIndex].value;
    if (selectedAttributeId) {
        var options = spConfig.config.attributes[confAttributeId].options;
        var productId = options.find(function (option) {return option.id == selectedAttributeId}).products[0]
        $("sku-container").update("<strong>Product Id: </strong>" + productMap[productId]);
    } else {
        $("sku-container").update("<strong>Product Id: </strong> Select an option to display Product Id");
    }
}
</script>

This will do the task you originally needed.


Also note the following

  1. Your approach won't work for a configurable product with two or more configurable attributes. For that product a final simple product is not known until a user selects values for all the select inputs. So an approach should be changed to check all the selects before outputting SKU.
  2. The code doesn't consider a case, when user edits product configuration, rather than specifying configuration for a new product. You can go to editing mode from the Shopping Cart clicking the Edit link. In such a case all the select inputs will be pre-filled with previously chosen values. But the text will say "Select an option to display Product Id". The script might also produce other Javascript errors in Edit mode. The code should be slightly modified in order to support Edit mode as well.
  3. The template is overfilled with logic. A Magento template should have only simple prints and foreach-iterations. All the methods like $conf->getUsedProductCollection()->addAttributeToSelect('*')->addFilterByRequiredOptions() are better to be moved to block. This reduces code complexity. Hope it helps.