Hello.
Some time ago I was need to add possibility to filter in grid by multiple values. Seems this is not possible in Magento out of box, so I made small research in
the web and found interesting solution

SELECTMULTIPLE

Ok, seems that’s what we need – so, let’s integrate in into our grid…

First of all we need to download all js and css files and connect it to Magento in the layout:

  1. <layout>
  2. <default>
  3. <reference name="head">
  4. <action method="addJs"><file>selectmultiple.js</file></action>
  5. <action method="addCss"><stylesheet>bro_multy.css</stylesheet></action>
  6. </reference>
  7. </default>
  8. </layout>

After that we should create render for our new filter:

  1. class Bro_Selectmultiple_Block_Adminhtml_Widget_Grid_Column_Filter_Multyselect extends Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Abstract
  2. {
  3. protected function _getOptions()
  4. {
  5. $emptyOption = array('value' => null, 'label' => '');
  6.  
  7. $optionGroups = $this->getColumn()->getOptionGroups();
  8. if ($optionGroups) {
  9. array_unshift($optionGroups, $emptyOption);
  10. return $optionGroups;
  11. }
  12.  
  13. $colOptions = $this->getColumn()->getOptions();
  14. if (!empty($colOptions) && is_array($colOptions) ) {
  15. $options = array($emptyOption);
  16. foreach ($colOptions as $value => $label) {
  17. $options[] = array('value' => $value, 'label' => $label);
  18. }
  19. return $options;
  20. }
  21. return array();
  22. }
  23.  
  24. /**
  25.   * Render an option with selected value
  26.   *
  27.   * @param array $option
  28.   * @param string $value
  29.   * @return string
  30.   */
  31. protected function _renderOption($option, $value)
  32. {
  33. $selected = (($option['value'] == $value && (!is_null($value))) ? ' selected="selected"' : '' );
  34. return '<option value="'. $this->escapeHtml($option['value']).'"'.$selected.'>'.$this->escapeHtml($option['label']).'</option>';
  35. }
  36.  
  37. public function getHtml()
  38. {
  39. $storeModel = Mage::getSingleton('adminhtml/system_store');
  40. $storeCollection = $storeModel->getStoreCollection();
  41.  
  42. $html = '<div id="select_two_container"> <select name="'.$this->_getHtmlName().'" id="select_multiple_two" class="no-changes">';
  43. $value = $this->getValue();
  44. $selected = $value == '' ? ' selected="selected"' : '';
  45. $html .= '<option value=""' . $selected . '></option>';
  46. if(strpos($value, ',')){
  47. $multi = explode(',',$value);
  48. $multiLabel = array();
  49. }
  50.  
  51. foreach ($storeCollection as $store) {
  52. $selected = $value == $store->getId() ? ' selected="selected"' : '';
  53. $html .= '<option value="' . $store->getId() . '"' . $selected . '>&nbsp;&nbsp;&nbsp;&nbsp;'
  54. . $this->escapeHtml($store->getName()) . '</option>';
  55. if(isset($multi) && in_array($store->getId(), $multi)){
  56. $multiLabel[] = $this->escapeHtml($store->getName());
  57. }
  58. }
  59. if(isset($multi)){
  60. $html .= '<option value="' . $value . '" selected="selected">&nbsp;&nbsp;&nbsp;&nbsp;'
  61. . implode(',',$multiLabel) . '</option>';
  62. }
  63.  
  64. $html.='</select>';
  65. $html .= '<a id="select_multiple_two_open" href="">Select Multiple</a>';
  66. $html .= $this->getMultyTableHtml();
  67. $html .= $this->getScript();
  68. return $html;
  69. }
  70.  
  71.  
  72. protected function getMultyTableHtml()
  73. {
  74. $storeModel = Mage::getSingleton('adminhtml/system_store');
  75. $storeCollection = $storeModel->getStoreCollection();
  76.  
  77. $html = '<div class="select_multiple_container" id="select_multiple_two_options" style="overflow: visible; display: none;">
  78. <div class="select_multiple_header">Select Multiple</div>
  79. <table cellspacing="0" cellpadding="0" width="100%" class="select_multiple_table">
  80. <tbody>';
  81. $i=1;
  82. foreach ($storeCollection as $store) {
  83. $html .= '<tr class="'.(($i%2==0)?'odd':'even').'">
  84. <td class="select_multiple_name">'.$this->escapeHtml($store->getName()).'</td>
  85. <td class="select_multiple_checkbox"><input type="checkbox" value="'.$store->getId().'"></td>
  86. </tr>';
  87. $i++;
  88. }
  89. $html .= '</tbody></table>
  90. <div class="select_multiple_submit"><input type="button" id="select_multiple_two_close" value="Done"></div>
  91. </div>';
  92.  
  93. return $html;
  94. }
  95.  
  96. public function getCondition()
  97. {
  98. if (is_null($this->getValue())) {
  99. return null;
  100. }
  101. return array('eq' => $this->getValue());
  102. }
  103.  
  104. protected function getScript()
  105. {
  106. return "<script>
  107. var select_multiple_two = new Control.SelectMultiple('select_multiple_two','select_multiple_two_options',{
  108. checkboxSelector: 'table.select_multiple_table tr td input[type=checkbox]',
  109. nameSelector: 'table.select_multiple_table tr td.select_multiple_name',
  110. afterChange: function(){
  111. if(select_multiple_two && select_multiple_two.setSelectedRows)
  112. select_multiple_two.setSelectedRows();
  113. }
  114. });
  115.  
  116. //adds and removes highlighting from table rows
  117. select_multiple_two.setSelectedRows = function(){
  118. this.checkboxes.each(function(checkbox){
  119. var tr = $(checkbox.parentNode.parentNode);
  120. tr.removeClassName('selected');
  121. if(checkbox.checked)
  122. tr.addClassName('selected');
  123. });
  124. }.bind(select_multiple_two);
  125. select_multiple_two.checkboxes.each(function(checkbox){
  126. $(checkbox).observe('click',select_multiple_two.setSelectedRows);
  127. });
  128. select_multiple_two.setSelectedRows();
  129.  
  130. //link open and closing
  131. $('select_multiple_two_open').observe('click',function(event){
  132. $(this.select).style.visibility = 'hidden';
  133. new Effect.BlindDown(this.container,{
  134. duration: 0.3
  135. });
  136. Event.stop(event);
  137. return false;
  138. }.bindAsEventListener(select_multiple_two));
  139. $('select_multiple_two_close').observe('click',function(event){
  140. $(this.select).style.visibility = 'visible';
  141. new Effect.BlindUp(this.container,{
  142. duration: 0.3
  143. });
  144. Event.stop(event);
  145. return false;
  146. }.bindAsEventListener(select_multiple_two));
  147. </script> ";
  148. }
  149.  
  150. }

Ok, seems thats’ it. We can use our new filter in any grid:

  1. $this->addColumn('status', array(
  2. 'header' => Mage::helper('sales')->__('Status'),
  3. 'index' => 'status',
  4. 'type' => 'options',
  5. 'width' => '70px',
  6. 'options' => Mage::getSingleton('sales/order_config')->getStatuses(),
  7. 'filter'=>'selectmultiple/adminhtml_widget_grid_column_filter_multyselect',
  8. ));

For filtering you can use such function (in my example I filter by stores):

  1. /**
  2.   * Modify column filter if needed by custom implementation of IN() and NOT IN() MySQL statement
  3.   *
  4.   */
  5. protected function _addColumnFilterToCollection($column)
  6. {
  7.  
  8. if (($column->getId() === 'store_id') && $column->getFilter()->getValue() && strpos($column->getFilter()->getValue(), ',')) {
  9.  
  10. $ids = explode(',', $column->getFilter()->getValue());
  11. if(count($ids)>0){
  12. $this->getCollection()->addFieldToFilter($column->getId(), array('in' => $ids));
  13. }
  14. } else {
  15. parent::_addColumnFilterToCollection($column);
  16.  
  17. }
  18. return $this;
  19. }

 

Enjoy yourself :)

If you’d like – you can download all files in complete module multiselect