Add Template to Custom Adminhtml Button in Magento 1.9

adminhtmlcontrollersevent-observerjavascriptmagento-1.9

I am currently creating a button for a single order in Magento(next to invoice, ship, reorder etc.). I would like the button to link to a javascript function inside a template with variables from that order passed to the function.

The way I currently have is I call a custom controller which goes to a new page("setLocation('{$block->getUrl('*/shiprush_orderbutton/indexaction')}')").

Is there any way I could avoid this and just call the function straight on the click of the button.

app\code\local\MyApp\OrderButton\etc\config.xml

<config>
<modules>
    <MyApp_OrderButton>
        <version>0.0.1</version>
    </MyApp_OrderButton>
</modules>
<global>
    <models>
        <myapp_orderbutton>
            <class>MyApp_OrderButton_Model</class>
        </myapp_orderbutton>
    </models>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <modules>
                        <myapp_orderbutton before="Mage_Adminhtml">
                        MyApp_OrderButton_Adminhtml
                        </myapp_orderbutton>
                    </modules>
                </args>
            </adminhtml>
        </routers>
    </admin>
</global>
<adminhtml>
    <events>
        <adminhtml_widget_container_html_before>
            <observers>
                <myapp_orderbutton>
                    <class>myapp_orderbutton/observer</class>
                    <method>adminhtmlWidgetContainerHtmlBefore</method>
                    <type>singleton</type>
                </myapp_orderbutton>
            </observers>
        </adminhtml_widget_container_html_before>
    </events>
    <layout>
        <updates>
            <orderbutton>
                <file>mybutton.xml</file>
            </orderbutton>
        </updates>
    </layout>
</adminhtml>
</config>

app\design\adminhtml\default\default\layout\mybutton.xml

<layout>
    <adminhtml_sales_order_view>
        <reference name="head">
            <action method="setTemplate><template>shiprush/sales/order/view/info.phtml</template>
            </action>
        </reference>
    </adminhtml_sales_order_view>

app\code\local\MyApp\OrderButton\Model\Observer.php:

class MyApp_OrderButton_Model_Observer {
public function adminhtmlWidgetContainerHtmlBefore($event) {

    $block = $event->getBlock();
    $magemodel = Mage::getModel('sales/order');
    $orderid = $magemodel->getIncrementId();
    $order = $magemodel->loadByIncrementId($orderid);
    if ($block instanceof Mage_Adminhtml_Block_Sales_Order_View) {
        // $block->prepareLayout();
        $block->addButton('do_something_crazy', array(
            'label'     => 'my button',
            'onclick'   => "setLocation('{$block->getUrl('*/myapp_orderbutton/indexaction')}')",
            'class'     => 'go'
        ));           
    }
}
}

app\code\local\MyApp\OrderButton\controllers\Adminhtml\ButtonController.php:

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

Best Answer

Assuming that you have created a custom module for this, in your config.xml add

<adminhtml>
    <layout>
        <updates>
            <magepal module="magepal">
                <file>magepal.xml</file>
            </magepal>
        </updates>
    </layout>
</adminhtml>

JS file location

skin/adminhtml/default/default/[companyName]/[moduel]/js/my.js

In magepal.xml add

<adminhtml_sales_order_view>
    <reference name="head">
         <action method="addItem"><type>skin_js</type><script>[companyName]/[module]/js/my.js</sc‌​ript></action>
    </reference>
</adminhtml_sales_order_view>  

Then call the function from your block

$block->addButton('do_something_crazy', array(
   'label'     => 'my button',
   'onclick'   => "(function(e){callMyFunction()}'; })(event)",
   'class'     => 'go'
));  
Related Topic