Multilevel Boostrap Menu in Yii 2 - twitter-bootstrap-3

I want my menu to have more than 2 levels. Looks like Yii 2 only renders up to 2 levels. For example this:
NavBar::begin();
echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right'],
'items' => [
[
'label' => 'Level 1',
'items' => [
['label' => 'Level 2 - 1', 'url' => '#'],
['label' => 'Level 2 - 2', 'url' => '#'],
[
'label' => 'Level 2 - 3',
'items' => [
['label' => 'Level 3 - 1', 'url' => '#'],
['label' => 'Level 3 - 2', 'url' => '#'],
],
],
]
],
],
]);
NavBar::end();
will not display the Level 3 - x menu items. How do I add more levels to the menu?

This is not Yii 2 limitation, it's Boostrap 3 limitation.
Here is quote from mdo (one of the main Boostrap 3 contributors):
We haven't seen anyone using submenus in meaningful ways and the code
necessary to make them work well is just too much overhead. Submenus
just don't have much of a place on the web right now, especially the
mobile web. They will be removed with 3.0.
It's taken from here.
However you can find some alternatives to use more levels. For example take a look this extension.
Also this question is discussed with more details and examples here.

1) Add Css in /web/css/site.css
.dropdown-submenu {
position: relative;
}
.dropdown-submenu>.dropdown-menu {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px;
border-radius: 0 6px 6px 6px;
min-width: 200px;
}
.dropdown-submenu:hover>.dropdown-menu {
display: block;
}
.dropdown-submenu>a:after {
display: block;
content: " ";
float: right;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 5px 0 5px 5px;
border-left-color: #ccc;
margin-top: 5px;
margin-right: -10px;
}
.dropdown-submenu:hover>a:after {
border-left-color: #fff;
}
.dropdown-submenu.pull-left {
float: none;
}
.dropdown-submenu.pull-left>.dropdown-menu {
left: -100%;
margin-left: 10px;
-webkit-border-radius: 6px 0 6px 6px;
-moz-border-radius: 6px 0 6px 6px;
border-radius: 6px 0 6px 6px;
}
2) Add submenu and attributes 'itemsOptions' , 'submenuOptions', 'items':
...
[
'label' => 'Level 2 - 3',
'itemsOptions'=>['class'=>'dropdown-submenu'],
'submenuOptions'=>['class'=>'dropdown-menu'],
'items' => [
['label' => 'Level 3 - 1', 'url' => '#'],
['label' => 'Level 3 - 2', 'url' => '#'],
],
],
....
3) ok !!

Try to use this extension of Nav widget.

Related

Highlighting parent menu from router-link in VueJS

I have developed a split sidebar menu. On the left there is icons which when pressed activate the menu bar on the right side for the submenu items. The submenu contains the router-link tags which I am able to tap into the active class of the selected link to highlight it. The issue is I need to apply the active class to the left icon bar as well since that is the parent menu. Once the application is loaded when you click the icons the active class will become active if the item is selected. My issue is purely during load because if someone types in the URL the custom router link the left sidebar does not have any functionality linking it to the router since the links are in the right part of the sidebar. Any methodology built into vue to handle something like this? If not is there another method I could try?
My sidebar component code is below. The code basically creates two sides, the icon side and the menu side. The icons and menu's are developed using v-for and looping through the data set which provides the links and icons to use.
<template id="side-navigation">
<div :class="theme">
<nav :class="sidebarcontainer">
<div class="sidebar-left">
<div class="arms-icon">
</div>
<div class="main-menu-items">
<ul>
<li v-for="(item,i) in MainNavLinks"
:key="i"
:class="{'active-main-menu-item': i === activeIconIndex}"
v-on:click="selectIconItem(i)">
<a>
<i :class="item.icon"></i>
</a>
</li>
</ul>
</div>
<div class="bottom-menu-items">
<ul>
<li v-for="(item,i) in FeaturesNavLinks"
:key="i"
:class="{ 'active-main-menu-item': i+MainNavLinks.length === activeIconIndex}"
v-on:click="selectIconItem(i+MainNavLinks.length)">
<a>
<i :class="item.icon"></i>
</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-right" :class="{'active-right-sidebar' : isIconActive}">
<div class="sidebar-content">
<div class="searchbarcontent">
<div class="inputWithIcon">
<input placeholder="Search" id="sub-nav-seachbar" class="searchbar" type="text">
<i class="fas fa-search" id="searchicon-btn"></i>
</div>
</div>
<div v-for="(item,i) in MainNavLinks"
:key="i"
:class="{'active-sub-menu-item' : i === activeIconIndex}"
class="right-menu-content">
<ul>
<li v-for="(SubNavLink,i) in item.SubNavLinks"
class="sub-nav-group">
<h4 class="sub-nav-header">
{{SubNavLink.SubNavHeader}}
</h4>
<ul>
<li v-for="(SubNavMenuItem,i) in SubNavLink.SubNavMenuItems"
class="sub-nav-items">
<router-link :to="SubNavMenuItem.link"><span class="sub-menu-icons"><i :class="SubNavMenuItem.icon"></i></span>{{SubNavMenuItem.title}}</router-link>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</nav>
</div>
</template>
<script>
Vue.component('side-navigation', {
template: '#side-navigation',
methods: {
selectIconItem(i) {
if (this.activeIconIndex === i) {
if (this.isIconActive === true) {
this.isIconActive = false;
} else {
this.isIconActive = true;
}
} else {
this.activeIconIndex = i;
this.isIconActive = true;
}
},
},
data() {
return {
theme: 'color',
activeIconIndex: null,
isIconActive: false,
sidebarcontainer: 'sidebar-container',
MainNavLinks: [
{
name: 'Dashboard',
link: '/',
icon: 'fa fa-th-large fa-lg',
SubNavLinks: [
{
SubNavHeader: 'Dash Category 1',
SubNavMenuItems: [{
title: 'Item 1',
link: '/',
icon: 'fas fa-list-ul'
},
{
title: 'Item 2',
link: '/item2',
icon: 'fas fa-list-ul'
}]
},
{
SubNavHeader: 'Dash Category 2',
SubNavMenuItems: [{
title: 'Item 3',
link: '/item3',
icon: 'fas fa-list-ul'
},
{
title: 'Item 4',
link: '/item4',
icon: 'fas fa-list-ul'
}]
}
]
},
{
name: 'Reviews',
link: '/Reviews',
icon: 'far fa-clipboard fa-lg',
SubNavLinks: [
{
SubNavHeader: 'Reviews Category 1',
SubNavMenuItems: [{
title: 'Item 1',
link: '/item1',
icon: 'fas fa-list-ul'
},
{
title: 'Item 2',
link: '/item2',
icon: 'fas fa-list-ul'
}]
},
{
SubNavHeader: 'Reviews Category 2',
SubNavMenuItems: [{
title: 'Item 3',
link: '/item3',
icon: 'fas fa-list-ul'
},
{
title: 'Item 4',
link: '/item4',
icon: 'fas fa-list-ul'
}]
}
]
},
{
name: 'Upload',
link: '/Upload',
icon: 'fa fa-upload fa-lg',
SubNavLinks: [
]
},
{
name: 'Analytics',
link: '/Analytics',
icon: 'fas fa-chart-line fa-lg',
SubNavLinks: [
]
},
{
name: 'Files',
link: '/Files',
icon: 'far fa-folder-open fa-lg',
SubNavLinks: [
]
}
],
FeaturesNavLinks: [
{
name: 'Notifications',
link: '/',
icon: 'fas fa-bell fa-lg'
},
{
name: 'Chat',
link: '/',
icon: 'fas fa-comment-alt fa-lg'
},
{
name: 'Email',
link: '/',
icon: 'fas fa-envelope fa-lg'
},
{
name: 'Profile',
link: '/',
icon: 'fas fa-user fa-lg'
}
]
}
}
})
</script>
<style scoped>
.sidebar-container {
display: flex;
flex-direction: row;
box-shadow: 2px 0px 4px -1px rgb(0 0 0 / 15%);
position: sticky;
}
/*left icon section of sidebar*/
.sidebar-left {
display: flex;
flex-direction: column;
align-items: center;
width: 100px;
position: relative;
height: 100vh;
overflow-y: auto;
overflow-x: hidden;
}
.color .sidebar-left {
background-color: #ff7100;
}
.light .sidebar-left {
border-right: 1px solid #ebedf3;
}
.main-menu-items {
padding: 20px 20px;
flex-grow: 1;
}
.sidebar-left ul {
padding: 0px;
}
.sidebar-left li {
list-style-type: none;
text-align: center;
margin-bottom: 10px;
}
.sidebar-left a {
height: 50px;
width: 50px;
display: flex;
justify-content: center;
align-items: center;
text-decoration: none;
border-radius: .42rem;
}
.color .sidebar-left a:hover > *, .color .sidebar-left a:hover {
background-color: #da6000f7;
color: #fff !important;
}
.light .sidebar-left a:hover > *, .light .sidebar-left a:hover {
background-color: #f3f6f9;
color: #ff7d44 !important;
}
.color .active-main-menu-item a > *, .color .active-main-menu-item a {
background-color: #da6000f7;
color: #fff !important;
}
.light .active-main-menu-item a > *, .light .active-main-menu-item a {
background-color: #f3f6f9;
color: #ff7d44 !important;
}
.color .sidebar-left i {
color: #fff;
}
.light .sidebar-left i {
color: #a5a5a5;
}
/*right sidebar styling*/
.sidebar-right {
width: 0px;
position: relative;
transition: all 1s;
overflow: hidden;
height: 100vh;
overflow-y: auto;
}
.active-right-sidebar {
width: 325px;
transition: all 1s;
}
.sidebar-content{
padding:20px;
}
.right-menu-content {
display: none;
overflow: hidden;
white-space: nowrap;
padding: 0px 20px;
}
.active-sub-menu-item {
display: block;
}
/*sidebar searchbar*/
.searchbar {
width: 100%;
height: 40px;
border: 0px;
border-radius: 40px;
outline: none;
padding: 8px;
box-sizing: border-box;
transition: 0.3s;
letter-spacing: 2px;
background-color: #e6e6e6;
}
.inputWithIcon input[type="text"], .inputWithIcon input[type="password"] {
padding-left: 35px;
}
.inputWithIcon {
position: relative;
height: 40px;
overflow: hidden;
width: 100%;
}
.searchbarcontent {
padding: 0px 20px;
display: flex;
height: 50px;
width: 100%;
justify-content: center;
align-items: center;
margin-bottom: 10px;
}
#searchicon-btn {
padding: 9px 25px 9px 5px;
top: 4px;
color: #aaa;
position: absolute;
right: 0px;
cursor: pointer;
}
.sidebar-right ul {
padding: 0px;
}
.sidebar-right li {
list-style-type: none;
}
.sidebar-right a {
text-decoration: none;
}
.sub-nav-header {
display: flex;
align-items: center;
height: 50px;
font-size: 1rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .3px;
color: #7e8299;
}
.sub-nav-items {
display: flex;
align-items: center;
height: 45px;
font-size: .9rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: .3px;
}
.sub-nav-items a {
color: #7f818d;
}
.sub-nav-group{
margin-bottom: 15px;
}
.sub-menu-icons {
width: 30px;
padding-right: 20px;
}
.router-link-exact-active {
color: #ff7100 !important;
}
/*scrollbar*/
/* custom scrollbar */
::-webkit-scrollbar {
width: 20px;
}
::-webkit-scrollbar-track {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: #00000014;
border-radius: 20px;
border: 6px solid transparent;
background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover {
background-color: #0000001f;
}
</style>
Use nested routes.
Parent <router-link>'s should have the class .router-link-active.
The exact <router-link> should have .router-link-exact-active.
Check out this code for an interactive example.

Vuejs doesn't show icon in component

I try to use Vuejs with jquery. I don't why this is not working. When first loading, icons doesn't seem. I don't know what is wrong. when you click on items, plus and minus icons seen and it is working as expected. But why it is not working in first loading ?
Any help will be appreciated.
var data = {
name: 'My Tree',
children: [{
name: 'hello'
}, {
name: 'wat'
}, {
name: 'child folder',
children: [{
name: 'child folder',
children: [{
name: 'hello'
}, {
name: 'wat'
}]
}, {
name: 'hello'
}, {
name: 'wat'
}, {
name: 'child folder',
children: [{
name: 'hello'
}, {
name: 'wat'
}]
}]
}]
}
// define the item component
Vue.component('item', {
template: '#item-template',
props: {
model: Object
},
computed: {
isFolder: function() {
return this.model.children &&
this.model.children.length
}
},
});
// boot up the demo
var demo = new Vue({
el: '#demo',
ready: function() {
},
data: {
treeData: data
}
});
Vue.nextTick(function() {
$('.tree li:has(ul)').addClass('parent_li').find(' > span').attr('title', 'Collapse this branch');
$('.tree li.parent_li > span').on('click', function(e) {
var children = $(this).parent('li.parent_li').find(' > ul > li');
if (children.is(":visible")) {
children.hide('fast');
$(this).attr('title', 'Expand this branch').find(' > i').addClass('icon-plus-sign').removeClass('icon-minus-sign');
} else {
children.show('fast');
$(this).attr('title', 'Collapse this branch').find(' > i').addClass('icon-minus-sign').removeClass('icon-plus-sign');
}
e.stopPropagation();
});
})
.tree {
min-height: 20px;
padding: 19px;
margin-bottom: 20px;
background-color: #fbfbfb;
border: 1px solid #999;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05)
}
.tree li {
list-style-type: none;
margin: 0;
padding: 10px 5px 0 5px;
position: relative
}
.tree li::before,
.tree li::after {
content: '';
left: -20px;
position: absolute;
right: auto
}
.tree li::before {
border-left: 1px solid #999;
bottom: 50px;
height: 100%;
top: 0;
width: 1px
}
.tree li::after {
border-top: 1px solid #999;
height: 20px;
top: 25px;
width: 25px
}
.tree li span {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border: 1px solid #999;
border-radius: 5px;
display: inline-block;
padding: 3px 8px;
text-decoration: none
}
.tree li.parent_li>span {
cursor: pointer
}
.tree>ul>li::before,
.tree>ul>li::after {
border: 0
}
.tree li:last-child::before {
height: 30px
}
.tree li.parent_li>span:hover,
.tree li.parent_li>span:hover+ul li span {
background: #eee;
border: 1px solid #94a0b4;
color: #000
}
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<ul id="demo">
<div class="tree well">
<item :model="treeData"></item>
</div>
</ul>
<script type="text/x-template" id="item-template">
<li>
<span><i v-if="isFolder" class="icon-minus-sign"></i> {{model.name}}</span>
<ul v-if="isFolder">
<item v-for="model in model.children" :model="model"></item>
</ul>
</li>
</script>
Actually it was my fault. I called wrong class name for the icon. I am updating and everything will work fine. I hope this vue recursive tree model will be useful for others.

How remove "No files selected" in CMultiFileUpload in Yii?

Just starting to learn the Yii. I do not know how to change the button and remove the "No files selected" in the widget
"CMultiFileUpload" in Yii framework?
$this->widget('CMultiFileUpload', array(
'model'=>$model,
'attribute'=>'photos',
'accept'=>'jpg|jpeg|gif|png',
'name'=>'photos',
'remove'=>'remove',
'options'=>array(
),
'denied'=>'File is not allowed',
'max'=>4, // max 10 files
));
This is browser dependent. Ex. Mozilla shows the input file type field with "No files selected". In IE it will come defferently.
If you want to hide the message "No files selected", do it with CSS
input[type='file']
{
color: transparent;
}
If you want to customize more, Try this bellow code.
Add this CSS code in your CSS file
#multFileUpload button#fileAlt
{
border: 3px solid #cccccc;
background-color: #FF7B10 !important;
color: #ffffff;
font-size: 14px;
padding: 10px 5px;
cursor: pointer;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
#multFileUpload input[type='file']
{
display: none;
}
Add this jQuery code in your javascript file
$(document).ready(function()
{
var maxFiles = 4;
var fileCountStart = 0;
$("#fileAlt").on('click', function()
{
fileCountStart += 1;
if (maxFiles >= fileCountStart)
{
$('#photos').trigger('click');
if (fileCountStart == maxFiles)
$("#fileAlt").attr('disabled', 'disabled');
}
});
});
Now Yii code
<div id="multFileUpload">
<button id="fileAlt">Select an Image</button>
<?php
$this->widget('CMultiFileUpload', array(
'model' => $model,
'id'=>'photos',
'attribute' => 'photos',
'accept' => 'jpg|jpeg|gif|png',
'name' => 'photos',
'remove' => 'remove',
'options' => array(
),
'denied' => 'File is not allowed',
'max' => 4, // max 10 files
));
?>
</div>

Ext JS 4: How to get clicked cell of grid using checkbox selection model?

I've spent most of the past few days researching how to convert an application written in Ext JS 3 to Ext JS 4. Unfortunately, I see in the API documentation that the following methods/events do not exist any more in Ext JS 4: cellclick, getColumnModel().
With that said I have a grid panel that is using a checkbox selection model to select the rows in the grid you want to delete. Works as expected but the issue is I have cells in the grid that contain links (a href's) that require me to capture the "cellclick" event which no longer exists. So, I notice that I can use the "itemclick" event for the grid panel but the issue is this events parameters only pertain to the row of the grid.
I need the column index as well, so I can determine if the "itemclick" event occurred in the column containing all of the links (a href's) and if so I want to handle what should happen next.
Here is the code I am trying to convert to Ext JS 4
cellclick: function(grid,rowIndex,colIndex,e) {
if (colIndex == 3) {
var rec = grid.getStore().getAt(rowIndex);
var fieldname = grid.getColumnModel().getDataIndex(colIndex + 1);
var filename = rec.get(fieldname);
if (!filename) return;
var download_iframe = Ext.getCmp("report-download");
if (!download_iframe) {
download_iframe = document.createElement('iframe');
download_iframe.id = 'report-download';
download_iframe.style.display = 'none';
download_iframe.height = '100';
download_iframe.width = '600';
document.body.appendChild(download_iframe);
download_iframe.src = script to download file
} else {
download_iframe.src = script to download file
}
e.stopEvent();
}
}
I've been able to convert this to Ext JS 4 but am missing one MAJOR piece of the code which is the ability to check what cell the "itemclick" event occurred in.
Ext JS 4 version:
this.control({
'casereportGridPanel sgrid': {
itemclick: this.downloadReport,
selectionchange: this.toggleDelReportsBtn
},
.
.
.
.
}
downloadReport: function(view, record, item, rowIndex, e) {
var filename = record.data.file_name;
if (filename) {
if (!filename) return;
var download_iframe = this.getDownloadContainer();
if (!download_iframe) {
download_iframe = document.createElement('iframe');
download_iframe.id = 'downloadReportContainer';
download_iframe.style.display = 'none';
download_iframe.height = '100';
download_iframe.width = '600';
document.body.appendChild(download_iframe);
download_iframe.src = script to download file
} else {
download_iframe.src = script to download file
}
e.stopEvent();
}
},
Grid Configuration:
{
xtype: 'sgrid',
autoScroll: true,
border: true,
columnLines: true,
id: 'myreportsgrid',
loadMask: true,
minHeight: 100,
selModel: Ext.create('Ext.selection.CheckboxModel',{checkOnly: true}),
plugins: [{
ptype: 'rowexpander',
rowBodyTpl: [
'<div style="border: 1px solid #CFCFCF; margin-left: 48px; padding: 0 0 8px 0;">',
'<div style="border: 0px solid #000; font-weight: bold; margin-left: 5px; padding: 5px 0 5px 5px; width: 200px;"><u>' + _t("case.report.grid.rowexpander.title") + '</u></div>',
'<table border="0" style="border-color: #666; margin-left: 5px; width: 575px;">',
'<tbody>',
'<tr>',
'<td style="border-color: #666; font-weight: bold; text-align: right; vertical-align: bottom; width: 75px;">' + _t("case.report.grid.rowexpander.casestatus") + ':</td>',
'<td style="border-color: #666; padding-left: 3px; vertical-align: bottom; width: 60px;">{case_status}</td>',
'<td style="border-color: #666; font-weight: bold; text-align: right; vertical-align: bottom; width: 70px;">' + _t("case.report.grid.rowexpander.startdate") + ':</td>',
'<td style="border-color: #666; padding-left: 3px; vertical-align: bottom;">{start_date}</td>',
'</tr>',
'<tr>',
'<td style="border-color: #666; font-weight: bold; text-align: right; vertical-align: bottom;">' + _t("case.report.grid.rowexpander.systemid") + ':</td>',
'<td style="border-color: #666; padding-left: 3px; vertical-align: bottom;">{system_ids}</td>',
'<td style="border-color: #666; font-weight: bold; text-align: right; vertical-align: bottom;">' + _t("case.report.grid.rowexpander.enddate") + ':</td>',
'<td style="border-color: #666; padding-left: 3px; vertical-align: bottom;">{end_date}</td>',
'</tr>',
'<tr>',
'<td style="border-color: #666; font-weight: bold; text-align: right; vertical-align: bottom;">' + _t("case.report.grid.rowexpander.parties") + ':</td>',
'<td style="border-color: #666; padding-left: 3px; vertical-align: bottom;" colspan="3">{parties}</td>',
'<tr>',
'</tbody>',
'</table>',
'</div>'
]
}],
store: 'CaseReports',
columns: [
{
dataIndex: 'id',
hidden: true,
renderer: this.renderText,
sortable: true,
text: _t('case.report.grid.id'),
width: 30
}, {
dataIndex: 'report_name',
flex: 1,
sortable: true,
text: _t('case.report.grid.reportName')
}, {
dataIndex: 'file_name',
hidden: true,
sortable: true,
text: _t('case.report.grid.filename'),
width: 200
}, {
dataIndex: 'date_requested',
renderer: this.renderDate,
sortable: true,
text: _t('case.report.grid.requested'),
width: 195
}, {
dataIndex: 'report_status',
renderer: this.renderText,
sortable: true,
text: _t('case.report.grid.reportStatus'),
width: 80
}
],
emptyText: '<div style="font-size: 11px; font-weight: bold; padding: 5px 0px; text-align: center;">' + _t('case.report.grid.noreports.available') + '</div>',
dockedItems: [{
xtype: 'toolbar',
items: [{
disabled: true,
action: 'deleteReport',
icon: SC.Url.image('delete.gif'),
text: _t('case.report.grid.deleteReports.btn'),
tooltip: _t('case.report.grid.deleteReports.btn.tooltip')
}, '->', { // begin using the right-justified button container
iconCls: 'x-tbar-loading',
action: 'refresh',
tooltip: _t('case.report.grid.refresh.tooltip')
}]
}]
I would be very thankful if anyone could help shine some light on how to get this work in Ext JS 4.
Thank all of you in advance,
Shawn
I answered a similar question not too long ago: ExtJS 4 - Grid - Disable rowselection for specific column
The grid view has an event called cellmousedown which receives the following parameters:
view: The view of your grid
cell: The cell that was clicked
cellIndex: Index of the cell
record: The store record associated with the cell
row: The row of the cell
rowIndex: Index of the row
eOpts: Standard event option object
It's undocumented, and I only found it by source diving, but it's there. There's also a beforecellmousedown event that works the same way, but fired before events and returning false stops any further events. You can do something like:
viewConfig: {
listeners: {
cellmousedown: function(view, cell, cellIdx, record, row, rowIdx, eOpts){
if(cellIdx === 3){
// Your converted code here
}
}
}
}
I think the problem is that checkboxmodel extends from rowselect which selects the entire row not a single cell.
I was able to pickup the target of the click even by using the event object that is supplied with every selection event regardless whether its cell or row type. kinda like this:
event.getTarget().hash -- here i was after the hash property of a link. Hope this helps.

wicked_pdf and wkhtmltopdf page size issue

I used these settings
WickedPdf::config = {
:layout => 'application.pdf.html', # use 'pdf.html' for a pfd.html.erb file
:wkhtmltopdf => '/bin/wkhtmltopdf', # path to binary
:orientation => 'Portrait', # default , Landscape
:page_size => 'A4',
:dpi => '300',
:print_media_type => true,
:no_background => true,
:margin => {:top => 0, # default 10 (mm)
:bottom => 0,
:left => 0,
:right => 0},
}
and set the body style to
body {
margin: 0;
padding: 0;
background-color: #FFF;
width: 210mm;
height: 297mm;
}
and a div of class .page
.page {
display: inline-block;
clear: both;
border: 2px solid #FF0000;
width: 210mm;
height: 297mm;
page-break-after: auto;
}
but when the pdf is created, the .page divs are almost half of the pdf page.
If you are floating your page container, then it won't work. I had the exact same problem and once I removed the floating pro.
So your page container should be:
.page {
display: block;
clear: both;
border: 2px solid #FF0000;
page-break-after: auto;}
Because the inline-block is just like floating it left.
Try putting in your css
#media print
{ .page {
display: inline-block;
clear: both;
border: 2px solid #FF0000;
width: 210mm;
height: 297mm;
page-break-after: auto;
}
}
Also make sure you add media="all" if you are referencing external stylesheet:
<link href="/stylesheets/scaffold.css?1304060088"
media="all" rel="stylesheet" type="text/css">