Magento 1.9 Customer Grid – Split Address Lines Guide

customergridmagento-1.9

I've got some code in place on the Customer Grid that feeds in default_billing address lines:

->joinAttribute('billing_street', 'customer_address/street', 'default_billing', null, 'left')

I need to know how to split these into separate columns, for example instead of having "Address 1 Address 2" in the same column I need – | Address 1 | Address 2 | in 2 different columns.

Thanks

Best Answer

If I do understand correctly you would like to have two "true" separated columns.

Here is a quick solution.

Join the billing street two times in _prepareCollection() of your grid so you can use them as separate columns:

->joinAttribute('billing_street_first_line', 'customer_address/street', 'default_billing', null, 'left')
->joinAttribute('billing_street_second_line', 'customer_address/street', 'default_billing', null, 'left')

Define the two columns in _prepareColumns() of your grid:

$this->addColumn('billing_street_first_line', array(
    'header'    => Mage::helper('customer')->__('Billing Street First Line'),
    'width'     => '150',
    'index'     => 'billing_street_first_line',
    'filter_condition_callback' => array($this, '_filterFirstLine'),
    'renderer' => 'mzeis_grid/adminhtml_widget_grid_column_renderer_address_firstline'
));

$this->addColumn('billing_street_second_line', array(
    'header'    => Mage::helper('customer')->__('Billing Street Second Line'),
    'width'     => '150',
    'index'     => 'billing_street_second_line',
    'filter_condition_callback' => array($this, '_filterSecondLine'),
    'renderer' => 'mzeis_grid/adminhtml_widget_grid_column_renderer_address_secondline',
    'sortable' => false
));

Notice that I disabled sorting on the second line as this isn't possible with my suggestion. With a little bit more time you may be able to work out a sortable solution, though.

Add the two filter condition callback methods in your grid in order to be able to filter for the columns. The syntax may be MySQL-specific but you may get away with it as long as you don't plan to use other databases:

protected function _filterFirstLine($collection, $column)
{
    if (!$value = $column->getFilter()->getValue()) {
        return;
    }
    $this->getCollection()->getSelect()->where("SUBSTRING_INDEX(`at_billing_street_first_line`.`value`, \"\\n\", 1) LIKE ?", '%' . $value . '%');
}

protected function _filterSecondLine($collection, $column)
{
    if (!$value = $column->getFilter()->getValue()) {
        return;
    }
    $sql = $this->getCollection()->getSelect()->__toString();
    $this->getCollection()->getSelect()->where("SUBSTRING_INDEX(`at_billing_street_second_line`.`value`, \"\\n\", -1) LIKE ?", '%' . $value . '%');
}

And finally, create the two renderer classes for rendering the first line in the one column and the second line in the other column. Let's assume that your Extension is called Mzeis_Grid and has been configured to be in the local code pool. In the config.xml you write:

<config>
    <global>
        <blocks>
            <mzeis_grid>Mzeis_Grid_Block</mzeis_grid>
        </blocks>
    </global>
</config>

Your first column renderer, app/code/local/Mzeis/Grid/Block/Adminhtml/Widget/Grid/Column/Renderer/Address/Firstline.php:

<?php

class Mzeis_Grid_Block_Adminhtml_Widget_Grid_Column_Renderer_Address_Firstline extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Text
{
    public function _getValue(Varien_Object $row)
    {
        $value = parent::_getValue($row);
        $lines = explode("\n", $value);
        return $lines[0];
    }
}

Your second column renderer, app/code/local/Mzeis/Grid/Block/Adminhtml/Widget/Grid/Column/Renderer/Address/Secondline.php:

<?php

class Mzeis_Grid_Block_Adminhtml_Widget_Grid_Column_Renderer_Address_Secondline extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Text
{
    public function _getValue(Varien_Object $row)
    {
        $value = parent::_getValue($row);
        $lines = explode("\n", $value);
        if (count($lines) > 1) {
            return $lines[1];
        }
        return '';
    }
}