Magento2 - Custom Admin Module with Grid Serializer - how to post more than 1 input fields
-
21-10-2020 - |
Question
I have successfully implemented serialized grid in my custom module. Steps are same as this - Grid serialization in magento 2
However there is only 1 input field - position
. I need 2 input fields - position
and qty
. But when i write 2 input_names
only 1 field gets posted in POST data. I want data of both.
Here is what I have tried so far:
File: /app/code/Vendor/Modulename/Block/Adminhtml/Customgrid/Edit/Tab/Gridfile.php
_prepareColumns
function:
$this->addColumn(
'qty',
[
'header' => __('Qty'),
'name' => 'qty',
'type' => 'number',
'validate_class' => 'validate-number',
'index' => 'qty',
'editable' => true,
'edit_only' => false,
'header_css_class' => 'col-qty',
'column_css_class' => 'col-qty'
]
);
$this->addColumn(
'position'
[
'header' => __('Position'),
'name' => 'position',
'type' => 'number',
'validate_class' => 'validate-number',
'index' => 'position',
'editable' => true,
'edit_only' => false,
'header_css_class' => 'col-position',
'column_css_class' => 'col-position'
]
);
File: /app/code/Vendor/Modulename/view/adminhtml/layout/frontname_controller_action.xml
WAY 1
<argument name="input_names" xsi:type="array">
<item name="position" xsi:type="string">position</item>
<item name="qty" xsi:type="string">qty</item>
</argument>
WAY 2
<argument name="input_names" xsi:type="string">position,qty</item>
</argument>
WAY 3
<argument name="input_names" xsi:type="string">position</item>
</argument>
None of these work. First way only posts qty. Second way gives a blank page. Third way only posts position and not qty.
Any ideas as to what the correct syntax is ?
I have checked core files but all of them only use one input field.
Solution
By default, Magento allows more than 1 input field. It is only possible if serialized grid is set to Multi-dimensional mode.
--SOLUTION--
It can be achieved in following way:
File: /Vendor/Module/view/adminhtml/layout/folder_controller_action.xml
<block class="Magento\Backend\Block\Widget\Grid\Serializer" name="custom_grid_serializer">
<arguments>
<argument name="input_names" xsi:type="array">
<item name="0" xsi:type="string">qty</item>
<item name="1" xsi:type="string">sort_order</item>
</argument>
</arguments>
</block>
--TRACING--
File: /lib/web/mage/adminhtml/grid.js
In grid.js
If you notice rowinit
function, it checks the length of inputs
. If total no. of inputs
is greater then zero then it will execute a for
loop:
if(this.multidimensionalMode){
var inputs = $(row).select.apply($(row), selectors.flatten());
if(checkbox && inputs.length > 0) {
//some core JS code
for(var i = 0; i < inputs.length; i++) {
//some other core JS code
}
}
}
Now, this for
loop is only executed if multidimensionalMode
is set to true
. If you trace back, you will find that multidimensionalMode
is set in initialize
function in following code:
initialize: function(hiddenDataHolder, predefinedData, inputsToManage, grid, reloadParamName){
//some core JS code
this.inputsToManage = inputsToManage;
this.multidimensionalMode = inputsToManage.length > 0;
//some other core JS code
}
So, multidimensionalMode
uses length
property on inputsToManage
which is the JSON
form of our input_names
argument defined in our layout xml
file.
So, you have to declare xsi:type
of input_names
as array
in layout xml
file and assign values to the name
attribute of item
starting from zero(as array indices are numbered). This will form a JSON
as below:
var inputsToManage = [{0:'qty',1:"sort_order"}];
inputsToManage.length = 1
Hence, this.multidimensionalMode
will now be set to true