The normal behaviour for the grid checkbox is to bind a js event to it, and action the checkbox check/uncheck. Normally this would be to populate a hidden field with the selected values, and then that field is what gets posted to your controller action.
See varienGrid.prototype /js/mage/adminhtml/grid.js : (this.checkboxCheckCallback) and also setCheckboxChecked method in that class.
For this reason the checkbox element generally do not get a name assigned to it, which you can see if you view your element properties.
This is thus the reason why you cannot get the selected options in your post action, since elements with no name will not post in the form, and you most likely do not have the required callback set to deal with the check/uncheck of the box. Using the callback js, you could also effect other actions in your gui, to enhance the user experience.
However, looking at your usage requirements, you may just get away with setting a name for the checkbox element, which will then post the data to your action.
Thus if you adjust your element definition to this (adding in the 'field_name' property), you will get your data in an array called 'selectedproducts'
$this->addColumn('in_category', array(
'header_css_class' => 'a-center',
'type' => 'checkbox',
'values' => $this->_getSelectedProducts(),
'align' => 'center',
'index' => 'entity_id',
'name' => 'in_category',
'field_name' => 'selectedproducts[]'
));
Hope that helps.
Update your assign-products.js
define([
'mage/adminhtml/grid'
], function () {
'use strict';
return function (config) {
var selectedProducts = config.selectedProducts,
categoryProducts = $H(selectedProducts),
gridJsObject = window[config.gridJsObjectName],
tabIndex = 1000;
$('in_category_products').value = Object.toJSON(categoryProducts);
/**
* Register Category Product
*
* @param {Object} grid
* @param {Object} element
* @param {Boolean} checked
*/
function registerCategoryProduct(grid, element, checked) {
if (checked) {
categoryProducts.set(element.value, '');
} else {
categoryProducts.unset(element.value);
}
$('in_category_products').value = Object.toJSON(categoryProducts);
grid.reloadParams = {
'selected_products[]': categoryProducts.keys()
};
}
/**
* Click on product row
*
* @param {Object} grid
* @param {String} event
*/
function categoryProductRowClick(grid, event) {
var trElement = Event.findElement(event, 'tr'),
isInput = Event.element(event).tagName === 'INPUT',
checked = false,
checkbox = null;
if (trElement) {
checkbox = Element.getElementsBySelector(trElement, 'input');
if (checkbox[0]) {
checked = isInput ? checkbox[0].checked : !checkbox[0].checked;
gridJsObject.setCheckboxChecked(checkbox[0], checked);
}
}
}
/**
* Change product position
*
* @param {String} event
*/
function positionChange(event) {
var element = Event.element(event);
if (element && element.checkboxElement && element.checkboxElement.checked) {
categoryProducts.set(element.checkboxElement.value, element.value);
$('in_category_products').value = Object.toJSON(categoryProducts);
}
}
/**
* Initialize category product row
*
* @param {Object} grid
* @param {String} row
*/
function categoryProductRowInit(grid, row) {
var checkbox = $(row).getElementsByClassName('checkbox')[0];
}
gridJsObject.rowClickCallback = categoryProductRowClick;
gridJsObject.initRowCallback = categoryProductRowInit;
gridJsObject.checkboxCheckCallback = registerCategoryProduct;
if (gridJsObject.rows) {
gridJsObject.rows.each(function (row) {
categoryProductRowInit(gridJsObject, row);
});
}
};
});
Then remove position field from Company/Mymodule/Block/Adminhtml/Mymodule/Tab/Product.php
Best Answer
Issue is you are calling a wrong method with product object in
Just comment following code block in above example,