Quick ListView customization
Monday, March 23rd, 2009As the next installment in the Sugar Tips and Tricks series from the Sugar engineering team, I will perform a quick and simple ListView customization which leverages the Carousel widget from the Yahoo UI (YUI) library. This customization completely changes the look and feel of the Contact ListView from a “rows and columns” view of your search results to a Yahoo UI Carousel view. The YUI library is included in SugarCRM and provides a ton of UI features beyond what we use in the core application.

I will only need to customize two files:
- view.list.php in the Contacts module
- ListViewContacts.tpl – a new smarty file which I have added to be used within the view.list.php file
Create a new file view.list.php file in custom/modules/Contacts/views. The beginning of the file including the constructor should look like:
require_once('include/MVC/View/views/view.list.php');
class ContactsViewList extends ViewList {
function ContactsViewList(){
parent::ViewList();
}
You can see that I am extending from the ViewList class as defined in ‘include/MVC/View/views/view.list.php’ so that I can take advantage of the methods which are already implemented and only override what I need. Since I only want to change how the ListView looks, I will do most of that in Smarty so I need to only override the method in ViewList which deals with rendering the template.
listViewProcess()
should do the trick.
Here is the full listing for the ContactsViewList class below:
require_once('include/MVC/View/views/view.list.php');
class ContactsViewList extends ViewList {
function ContactsViewList(){
parent::ViewList();
}
function listViewProcess(){
$this->processSearchForm();
$this->searchColumns = $this->searchColumns;
if(!$this->headers)
return;
if(empty($_REQUEST['search_form_only']) || $_REQUEST['search_form_only'] == false){
$this->lv->setup($this->seed, 'custom/modules/Contacts/tpls/ListViewContacts.tpl', $this->where, $this->params);
$savedSearchName = empty($_REQUEST['saved_search_select_name']) ? '' : (' - ' . $_REQUEST['saved_search_select_name']);
echo get_form_header($GLOBALS['mod_strings']['LBL_LIST_FORM_TITLE'] . $savedSearchName, '', false);
echo $this->lv->display();
}
}
}
Now that we have provided a way to get my own custom smarty template loaded on the Contacts ListView, I will create my Smarty file in custom/modules/Contacts/tpls/ListViewContacts.tpl. My goal here will be to remove most of the table rendering logic defined in ListViewGeneric.tpl and replace it with my own rendering logic to display the carousel.
link rel="stylesheet" type="text/css" href='{sugar_getjspath file='include/javascript/yui/build/fonts/fonts.css'}'>
<link type="text/css" rel="stylesheet" href='{sugar_getjspath file='include/javascript/yui/build/carousel/assets/skins/sam/carousel.css'}'>
<script src='{sugar_getjspath file='include/javascript/yui/build/utilities/utilities.js'}'></script>
<script src='{sugar_getjspath file='include/javascript/yui/build/carousel/carousel-beta-min.js'}'></script>
{literal}
<style type="text/css">
.yui-carousel-element li {
height: 158px;
text-align: left;
}
#container {
font-size: 13px;
margin: 0 auto;
}
#container a {
text-decoration: none;
}
#container .intro {
display: inline;
margin: 0px 14px 0px 4px;
width: 202px;
}
#container .item {
display: inline;
margin: 0 22px 0 12px;
overflow: hidden;
padding-right: 80px;
width: 106px;
}
#container .item .authimg {
bottom: 2px;
margin-left: 61px;
position: absolute;
z-index: 1;
}
#container .item h3 {
line-height: 85%;
margin-top: 4px;
}
#container .item h3 a {
font: 77% Arial, sans-serif;
position: relative;
text-transform: uppercase;
z-index: 2;
}
#container .item h3 a:link {
color:#35a235;
}
#container .item h4 {
margin-top:5px;
}
#container .item h4 a {
font: 100% Georgia, Times, serif;
position: relative;
z-index:2;
}
#container .item h4 a:link {
color:#00639b;
}
#container .item cite {
color: #888;
display: block;
font-size: 77%;
line-height: normal;
margin-bottom: 30px;
}
#container .item p.all {
bottom: 25px;
position: absolute;
z-index: 2;
}
#container .item p.all a {
font-weight: bold;
font-size: 85%;
}
</style>
{/literal}
<div class="yui-skin-sam">
<div id="container">
<ol id="carousel">
{foreach name=rowIteration from=$data key=id item=rowData}
<li class="item">
<a href='index.php?module={$pageData.bean.moduleDir}&action=detailview&record={$rowData.ID}'>
{foreach from=$displayColumns key=col item=params}
{if $params.link &!$params.customCode}
<{$pageData.tag.$id[$params.ACLTag]|default:$pageData.tag.$id.MAIN} href="#" onMouseOver="javascript:lvg_nav('{if $params.dynamic_module}{$rowData[$params.dynamic_module]}{else}{$params.module|default:$pageData.bean.moduleDir}{/if}', '{$rowData[$params.id]|default:$rowData.ID}', 'd', {$offset}, this)" onFocus="javascript:lvg_nav('{if $params.dynamic_module}{$rowData[$params.dynamic_module]}{else}{$params.module|default:$pageData.bean.moduleDir}{/if}', '{$rowData[$params.id]|default:$rowData.ID}', 'd', {$offset}, this)">{$rowData.$col}</{$pageData.tag.$id[$params.ACLTag]|default:$pageData.tag.$id.MAIN}>
{elseif $params.customCode}
{sugar_evalcolumn_old var=$params.customCode rowData=$rowData}
{elseif $params.currency_format}
{sugar_currency_format
var=$rowData.$col
round=$params.currency_format.round
decimals=$params.currency_format.decimals
symbol=$params.currency_format.symbol
convert=$params.currency_format.convert
currency_symbol=$params.currency_format.currency_symbol
}
{elseif $params.type == 'bool'}
<input type='checkbox' disabled=disabled class='checkbox'
{if !empty($rowData[$col])}
checked=checked
{/if}
/>
{elseif $params.type == 'multienum'}
{if !empty($rowData.$col)}
{counter name="oCount" assign="oCount" start=0}
{assign var="vals" value='^,^'|explode:$rowData.$col}
{foreach from=$vals item=item}
{counter name="oCount"}
{sugar_translate label=$params.options select=$item}{if $oCount != count($vals)},{/if}
{/foreach}
{/if}
{else}
{$rowData.$col}
{/if}
{/foreach}
</a>
</li>
{/foreach}
</ol>
</div>
</div>
{literal}
<script>
(function () {
var carousel;
YAHOO.util.Event.onDOMReady(function (ev) {
var carousel = new YAHOO.widget.Carousel("container", {
animation: { speed: 0.5 }
});
carousel.render(); // get ready for rendering the widget
carousel.show(); // display the widget
});
})();
</script>
{/literal}
You can see from the above I have stripped out the table HTML and now the meat of the display is done here:
<div id="container">
<ol id="carousel">
{foreach name=rowIteration from=$data key=id item=rowData}
<li class="item">
We simply loop through each of our rows and output it into the <li> tags and then once this has rendered the JavaScript:
(function () {
var carousel;
YAHOO.util.Event.onDOMReady(function (ev) {
var carousel = new YAHOO.widget.Carousel("container", {
animation: { speed: 0.5 }
});
carousel.render(); // get ready for rendering the widget
carousel.show(); // display the widget
});
})();
will render the widget.




