Q:

How to add a 'preview' column in magento grid?

I want to add a Column in grid with 'preview' text. Like in image :
 When I am over text with mouse I want to display a html page. The html page it is tacked from database(BLOB type).
I've tried:
RENDERER:
 public function render(Varien_Object $row)
            {
               //grid is filled with data from custom table page(id, title, html_code-BLOB)
                $aId =  $row->getData($this->getColumn()->getIndex());
                $a = Mage::getModel('page')->load($aId);

               //HtmlCode is a column from database that contains BLOB html page
                $sourcecode = $a->getHtmlCode();

            if(isset($sourcecode))
        {
            $value='<a href = "" value="">preview</a>';
        }

        return $value;

    }

but I don't know how to make to show $sourcecode on hover.

A:

It could be something simple like a CSS Tooltip or it could be more complex such as a full lightbox, or even a popup window. Honestly it depends on what data and how much.
NOTE: if its a lot of content, I would recommend using the onclick instead of the onmouseover event.
Here is some code for a custom grid column that displays a lightbox WITH AN AJAX controller request to load the data (sorry I don't have an example that loads the data directly):
        $this->addColumn(
            'action_poptop',
            array(
                'header'        => $this->__('Action'),
                'width'         => '50px',
                'filter'        => false,
                'sortable'      => false,
                'index'         => 'action_poptop',
                'renderer'      => 'root/adminhtml_grid_column_renderer_link',
                'allowed'       => 'getIsInProcess',
                'link_label'    => $this->__('Update'),
                'link_route'    => '*/*/action',
                'link_params'   => array('id' => 'id', 'popup' => 'id'), // key should be the param name, and val should be obj key
                'onclick'       => 'popTop(this.href, \'Ticket Actions\'); return false;',
                'column_css_class' => 'nowrap',
            )
        );

And calls the following function in the renderer:
const LINK_BLANK    = '_blank';
const LINK_SELF     = '_self';
const LINK_PARENT   = '_parent';
const LINK_TOP      = '_top';

/**
 * Render
 *
 * (non-PHPdoc)
 * @see Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract::render()
 */
public function render(Varien_Object $row)
{
    $value      = $this->_getValue($row);
    $column     = $this->getColumn();
    $label      = (string) ($column->hasLinkLabel()) ? $column->getLinkLabel() : $value;
    $labelKey   = (string) ($column->hasLinkLabelKey()) ? $column->getLinkLabelKey() : null;
    $allowed    = ($column->hasAllowed()) ? $column->getAllowed() : true;
    $target     = ($column->hasTarget()) ? $column->getTarget() : self::LINK_SELF;
    $onclick    = ($column->hasOnclick()) ? $column->getOnclick() : false;
    $button     = ($column->hasButton()) ? (boolean) $column->getButton() : false;
    $class      = ($column->hasClass()) ? $column->getClass() : false;
    $style      = ($column->hasStyle()) ? $column->getStyle() : false;

    // fully qualified link
    $link       = $column->getLink();

    // it is possible the label is being pulled from the object
    if (!empty($labelKey) && $row->hasData($labelKey)) {
        $label = $row->getData($labelKey);
    }

    // or build a link based on route and params
    $linkRoute  = ($column->hasLinkRoute()) ? $column->getLinkRoute() : null;
    $linkParams = ($column->hasLinkParams()) ? $column->getLinkParams() : array();
    $linkParams = (is_array($linkParams)) ? $linkParams : array();

    // allows string input for method or obj key
    if (is_string($allowed) && method_exists($row, $allowed)) {
        $allowed = (boolean) $row->$allowed();
    } elseif (is_string($allowed) && $row->hasData($allowed)) {
        $allowed = (boolean) $row->getData($allowed);
    }

    if ($allowed) {
        if (!empty($link)) {
            return $this->_outputHtml($label, $link, $class, $style, $onclick, $button, $target);

        } elseif (!empty($linkRoute)) {
            $params = array();

            // loop through all of the params and
            foreach ($linkParams as $key => $objKey) {
                $params[$key] = $row->getData($objKey);
            }

            return $this->_outputHtml(
                $label,
                $this->getUrl($linkRoute, $params),
                $class,
                $style,
                $onclick,
                $button,
                $target
            );
        }
    }

    return '';
}

/**
 * Outputs the contents of the link (or as button)
 *
 * @param string $label
 * @param string $url
 * @param string $class
 * @param string $style
 * @param string $onclick
 * @param boolean $renderAsButton
 * @param string|NULL $target
 * @return string
 */
protected function _outputHtml($label, $url, $class, $style, $onclick, $renderAsButton = false, $target = null)
{
    if ($renderAsButton) {
        if (empty($onclick) && !empty($url)) {
            $onclick = 'setLocation(\'' . $url . '\')';
        } elseif (!empty($url) && strpos($onclick, 'this.href') !== false) {
            $onclick = str_replace('this.href', '\'' . $url . '\'', $onclick);
        }

        return sprintf(
            '<button type="button" class="scalable%s"%s%s><span>%s</span></button>',
            (!empty($class)) ? ' ' . $class : '',
            (!empty($style)) ? ' style="' . $style . '"' : '',
            (!empty($onclick)) ? ' onclick="' . $onclick . '"' : '',
            $label
        );
    }

    return sprintf(
        '<a href="%s"%s%s%s%s>%s</a>',
        $url,
        (!empty($target) && $target != self::LINK_SELF) ? ' target="' . $target . '"' : '',
        (!empty($class)) ? ' class="' . $class . '"' : '',
        (!empty($style)) ? ' style="' . $style . '"' : '',
        (!empty($onclick)) ? ' onclick="' . $onclick . '"' : '',
        $label
    );
}

