Disable massaction checkbox checked on grid row click
-
12-12-2019 - |
Question
I want to cancel default behavior on grid row click - checking massaction checkboxes. The another default action - is redirecting to an editing page, and I've disabled it in this way - add this method to my grid -
public function getRowUrl($row)
{
return '';
}
I've also tried to use openGridRow()
function, but it didn't work (I've placed it in my own js file).
But I need to disable checkbox checking too. Does anybody know, how to do it?
If it's possible to do with openGridRow()
, where I need to place it?
Solution 2
Thanks to previous answer, I've finally find a solution - by adding this method
getRowClickCallback
to my grid class (that overrides a core grid Mage_Adminhtml_Block_Catalog_Product_Grid
), that returns some fake JS function, like this
public function getRowClickCallback()
{
return 'fakeJsFunction';
}
OTHER TIPS
With openGridRow
you were already close to the solution. This is the default JS callback, but you can change it with the row_click_callback
property of the grid widget. For no action at all, use:
$this->setRowClickCallback(null);
The default value is set in Mage_Adminhtml_Block_Widget_Grid::__construct()
, so you can override the constructor and add this line after parent::__construct()
I've recently had a similar need--to alter the default behavior of a click in a row on a grid. I added a custom grid column renderer using a <textarea>
field. Every time I clicked inside the textarea to type in some text, the row's "enabled"/"massaction" checkbox would toggle, and that was frustrating from a user perspective.
When any element is clicked in a grid row, varienGrid
's rowClickCallback
is called. However, there's more to it than that. When Magento's grid.js
is loaded, it has more than just a varienGrid
object. It also has a serializerController
object. When this object is instantiated (after varienGrid
), it overwrites a few of varienGrid's event handlers, including the rowClickCallback
handler, but not before saving references to the "old" handlers in it's oldCallback
array. So when varienGrid
's rowMouseClick
calls this.rowClickCallback(this, event)
, it's actually firing serializerController
's rowClick
method. Just before that method finishes, it calls the previous handler for the same event, which it stored in it's oldCallback
array. In this way, both varienGrid.rowClickCallback
and serializerController.rowClick
are fired when any element is clicked in a grid row.
So, there's at least two methods that you'll need to consider. If you want to add behavior to a grid row click, you can either override the openGridRow
function with your own, or you can write an entirely new function, and set it's name in your grid block's __constructor method using $this->setRowClickCallback('function_name')
as @fschmengler mentioned. Note that calling $this->setRowClickCallback(null);
will only disable varienGrid
's rowClickCallback
method, but serializerController
's rowClick
will still fire.
For my issue, I wanted clicks on textarea
s to not toggle the row's "enabled"/"massaction" checkbox. I therefore had to change the behavior of serializerController.rowClick
by loading my own JS file as part of my module's adminhtml layout, and including this bit:
if(typeof tmpSerializerController == 'undefined') {
var tmpSerializerController = {};
}
tmpSerializerController = Class.create(serializerController, {
rowClick : function(grid, event) {
var trElement = Event.findElement(event, 'tr');
var isControl = ['a', 'input', 'select', 'option', 'textarea', 'img', 'label'].indexOf(Event.element(event).tagName.toLowerCase()) != -1;
if(trElement){
var checkbox = Element.select(trElement, 'input');
if (checkbox[0] && !checkbox[0].disabled) {
var checked = isControl ? checkbox[0].checked : !checkbox[0].checked;
this.grid.setCheckboxChecked(checkbox[0], checked);
}
}
this.getOldCallback('row_click')(grid, event);
},
rowInit : function(grid, row) {
if(this.multidimensionalMode){
var checkbox = $(row).select('.checkbox')[0];
var selectors = this.inputsToManage.map(function (name) { return ['input[name="' + name + '"]', 'input[type="file"]', 'select[name="' + name + '"]', 'textarea[name="' + name + '"]']; });
var inputs = $(row).select.apply($(row), selectors.flatten());
if(checkbox && inputs.length > 0) {
checkbox.inputElements = inputs;
for(var i = 0; i < inputs.length; i++) {
inputs[i].checkboxElement = checkbox;
if(this.gridData.get(checkbox.value) && this.gridData.get(checkbox.value)[inputs[i].name]) {
inputs[i].value = this.gridData.get(checkbox.value)[inputs[i].name];
}
inputs[i].disabled = !checkbox.checked;
inputs[i].tabIndex = this.tabIndex++;
Event.observe(inputs[i],'keyup', this.inputChange.bind(this));
Event.observe(inputs[i],'change', this.inputChange.bind(this));
}
}
}
this.getOldCallback('init_row')(grid, row);
},
});
serializerController = tmpSerializerController;
I also added links, select menus, images and labels to cancel the row's toggling, as clicking on those don't really suggest an intention to toggle a row to me. EDIT: I added the rowInit method above to include the file inputs and textarea
fields in the list of row inputs. This will allow them to be automatically disabled when the row is disabled, and re-enabled when the row is enabled.
To complete this answer, I should also mention varienGridMassaction
's onGridRowClick
. To be honest, I'm not quite sure how or when this is used. The varienGridMassaction
instance does store and replace varienGrid
's existing rowClickCallback
function, but it's own onRowClickCallback
method doesn't call the stored method. Perhaps someone can enlighten us on that point. Nonetheless, I updated it's logic to be consistent with the previous change made.
if (typeof tmpVarienGridMassaction == 'undefied') {
var tmpVarienGridMassaction = {};
}
tmpVarienGridMassaction = Class.create(varienGridMassaction, {
onGridRowClick: function(grid, evt) {
var tdElement = Event.findElement(evt, 'td');
var trElement = Event.findElement(evt, 'tr');
if(!$(tdElement).down('input')) {
if($(tdElement).down('a') || $(tdElement).down('select')) {
return;
}
if (trElement.title) {
setLocation(trElement.title);
}
else{
var checkbox = Element.select(trElement, 'input');
var isControl = ['a', 'input', 'select', 'option', 'textarea', 'img', 'label'].indexOf(Event.element(event).tagName.toLowerCase()) != -1;
var checked = isControl ? checkbox[0].checked : ! checkbox[0].checked;
if (checked) {
this.checkedString = varienStringArray.add(checkbox[0].value, this.checkedString);
} else {
this.checkedString = varienStringArray.remove(checkbox[0].value, this.checkedString);
}
this.grid.setCheckboxChecked(checkbox[0], checked);
this.updateCount();
}
return;
}
if(Event.element(evt).isMassactionCheckbox) {
this.setCheckbox(Event.element(evt));
} else if (checkbox = this.findCheckbox(evt)) {
checkbox.checked = !checkbox.checked;
this.setCheckbox(checkbox);
}
}
});
varienGridMassaction = tmpVarienGridMassaction;