codinglimo
codinglimo

Reputation: 707

Add Dynamic JS Code on Magento Product Page

On my magento product page I need to add a dynamic JavaScript array base on display upselling products on the product page. The goal is to change the images of the upselling products when the user change the color of the main product.

To achieve my goal I need a custom JavaScript array on every product page that give me information about crossselling product and the associated product image.

What is the best way to do this?

I try this

add a observer event in my config.xml

<controller_action_layout_load_before>
    <observers>
       <crossselling_product_view>
           <type>singleton</type>
           <class>XXXXXXXX_Crossselling_Model_Observer</class>
           <method>productview</method>
        </crossselling_product_view>
    </observers>
</controller_action_layout_load_before>

add observer to add specific JS Code

<?php
class XXXXXXXX_Crossselling_Model_Observer {

    public function productview(Varien_Event_Observer $observer) {

        $product = Mage::registry('current_product');

        //only on product page
        if (!($product instanceof Mage_Catalog_Model_Product)) {
            return;
        }

        $controller = $observer->getAction();
        $layout = $controller->getLayout();
        $block = $layout->createBlock('core/text');
        $block->setText(
            '<script type="text/javascript">
            function main_pulsestorm_hellojavascript()
            {
                alert("Foo");
            }
            main_pulsestorm_hellojavascript();
        </script>'
        );
        $layout->getBlock('head')->append($block);
    }

}

My error: Fatal error: Call to a member function append() on a non-object

What is my problem and is it the right way to add dynamic js code?

Upvotes: 1

Views: 1182

Answers (2)

fantasticrice
fantasticrice

Reputation: 1621

I would probably approach this from a different angle. Since you are only interested in interacting with data and output for the upsell block, you could change the behavior of just that block by observing its output and appending your extra JavaScript. For the purposes of brevity this answer assumes that you understand the basics of Magento extensions.

  1. Observe the core_block_abstract_to_html_after event:

etc/config.xml

<core_block_abstract_to_html_after>
    <observers>
        <addCustomUpsellFormat>
            <class>XXXXXXXX_Crossselling_Model_Observer</class>
            <method>addCustomUpsellFormat</method>
        </addCustomUpsellFormat>
    </observers>
</core_block_abstract_to_html_after>
  1. Act upon instances of Mage_Catalog_Block_Product_List_Upsell by appending the output of a new block that will read their data:

Model/Observer.php

public function addCustomUpsellFormat(Varien_Event_Observer $observer)
{
    /* @var Mage_Core_Block_Abstract $block */
    $block = $observer->getBlock();
    if ($block instanceof Mage_Catalog_Block_Product_List_Upsell) {
        /* @var Varien_Object $transport */
        $transport = $observer->getTransport();
        // Receive the standard output for the block.
        $output = $transport->getHtml();

        /* @var Mage_Core_Model_Layout $layout */
        $layout = $block->getLayout();
        $json = $layout->createBlock('core/template')
            ->setTemplate('catalog/product/list/upsell_json.phtml')
            ->setItems($block->getItems())
            ->toHtml();

        // Append new JSON data to block output.
        $transport->setHtml($output . $json);
    }
    return $this;
}
  1. Create a template that interprets the upsell data and outputs it in your desired way, in my example above I created a template that could do something like this (my example creates a new template, so it should go into the base theme):

app/design/frontend/base/default/template/catalog/product/list/upsell_json.phtml

<?php
$_json = array(); // Add data in here to convert to JSON for output.
$_items = $this->getItems();
/* @var Mage_Catalog_Model_Product $_product */
foreach ($_items as $_product) {
    $_json[$_product->getId()] = array(
        'image' => (string)Mage::helper('catalog/image')->init($_product, 'image')
    );
}
?>
<script type="text/javascript">var upsellData = <?php echo json_encode($_json) ?>;</script>

Upvotes: 1

Use

$controller = $observer->getEvent()->getAction();

instead of

$controller = $observer->getAction();

Upvotes: 0

Related Questions