0

I have category id in phtml file. how to display all products under this category using category id and foreach loop.

I tried this code but it shows invalid variable in foreach

$categoryId = 6; // fetching products in category id 6   
$categoryProducts = $block->getCategoryProducts($categoryId);  
foreach ($categoryProducts as $product){
echo $product->getName() . ' - ' . $product->getProductUrl() . '<br/>';
}

I have a category chooser in block

<?php
namespace Product\Widget\Block\Adminhtml\Category\Widget;

class Chooser extends \Magento\Backend\Block\Template {

protected $_elementFactory;
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param \Magento\Framework\Data\Form\Element\Factory $elementFactory
* @param array $data
*/
public function __construct(
  \Magento\Backend\Block\Template\Context $context,
  \Magento\Framework\Data\Form\Element\Factory $elementFactory, array 
$data = []
) {
  $this->_elementFactory = $elementFactory;
  parent::__construct($context, $data);
}

/**
* Prepare chooser element HTML
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element 
Form Element
 * @return \Magento\Framework\Data\Form\Element\AbstractElement
*/
public function 
prepareElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element) {
  $htmlId = $element->getId();
  $data = $element->getData();

  $data['after_element_js'] = $this->_afterElementJs($element);
  $data['after_element_html'] = $this->_afterElementHtml($element);
  $data['readonly'] = 'readonly';
  $htmlItem = $this->_elementFactory->create('text', ['data' => $data]);
  $htmlItem
          ->setId("{$htmlId}")
          ->setForm($element->getForm())
          ->addClass('required-entry')
          ->addClass('entities');
  $return = <<<HTML
           <div id="{$htmlId}-container" class="chooser_container">{$htmlItem->getElementHtml()}</div>
HTML;
   $element->setData('after_element_html', $return);
  return $element;
 }

 protected function _afterElementHtml($element)
  {
      $htmlId = $element->getId();
    $return = <<<HTML
      <a href="javascript:void(0)" onclick="MultiCategoryChooser.displayChooser('{$htmlId}-container')" class="widget-option-chooser" title="{__('Open Chooser')}">
          <img src="{$this->getViewFileUrl('images/rule_chooser_trigger.gif')}" alt="{__('Open Chooser')}" />
      </a>
      <a href="javascript:void(0)" onclick="MultiCategoryChooser.hideChooser('{$htmlId}-container')" title="{__('Apply')}">
          <img src="{$this->getViewFileUrl('images/rule_component_apply.gif')}" alt="{__('Apply')}">
      </a>
      <div class="chooser"></div>
   HTML;
  return $return;
  }

  protected function _afterElementJs($element)
  {
  $chooserUrl = $this->getUrl('adminhtml/widget_instance/categories', 
  []);
  $htmlId     = $element->getId();
  $return = <<<HTML
      <script>
              require([
              'jquery',
              'Magento_Ui/js/modal/alert',
              "prototype"
          ], function (jQuery, alert) {
              var MultiCategoryChooser = {
                  displayChooser : function(chooser) {
                          chooser  = $(chooser).down('div.chooser');
                          entities = chooser.up('div.chooser_container').down('input[type="text"].entities').value;
                          postParameters = {selected: entities};
                          url = '{$chooserUrl}';

                          if (chooser && url) {
                          if (chooser.innerHTML == '') {
                                  new Ajax.Request(url, {
                                  method  : 'post',
                                  parameters : postParameters,
                                  onSuccess  : function(transport) {
                                          try {
                                          if (transport.responseText) {
                                              Element.insert(chooser, transport.responseText);
                                              chooser.removeClassName('no-display');
                                              chooser.show();
                                          }
                                          } catch (e) {
                                          alert({
                                             content: 'Error occurs during loading chooser.'
                                          });
                                          }
                                  }
                              });
                          } else {
                              chooser.removeClassName('no-display');
                              chooser.show();
                          }
                          }
                 },
                  hideChooser : function(chooser) {
                          chooser = $(chooser).down('div.chooser');
                          if (chooser) {
                          chooser.addClassName('no-display');
                          chooser.hide();
                          }
                  },
                  checkCategory : function(event) {
                          node    = event.memo.node;
                          container = event.target.up('div.chooser_container');
                          value   = container.down('input[type="text"].entities').value.strip();
                          if (node.attributes.checked) {
                          if (value) ids = value.split(',');
                          else ids = [];
                          if (-1 == ids.indexOf(node.id)) {
                              ids.push(node.id);
                              container.down('input[type="text"].entities').value = ids.join(',');
                          }
                          } else {
                          ids = value.split(',');
                          while (-1 != ids.indexOf(node.id)) {
                              ids.splice(ids.indexOf(node.id), 1);
                              container.down('input[type="text"].entities').value = ids.join(',');
                          }
                          }
                  }
                }
              window.MultiCategoryChooser = MultiCategoryChooser;
              jQuery(function() {
                  var container = $('{$htmlId}-container');
                  if (container) {
                      container.up(0).down('.control-value').hide();
                  }

                  Event.observe(document, 'node:changed', function(event){
                      MultiCategoryChooser.checkCategory(event);
                  });
                  Event.observe(document, 'category:beforeLoad', function(event) {
                          container = event.target.up('div.chooser_container');
                          value   = container.down('input[type="text"].entities').value.strip();
                      event.memo.treeLoader.baseParams.selected = value;
                  });
              });
          });
      </script>
 HTML;
     return $return;
    }
    }
  • Which phtml file is being used? The block refers to the function of the .php file located in the module Block folder of same name. Do you have getCategoryProducts function within that which needs categoryId arguments. If yes better to share .php code as well. – Gagan Jul 26 '18 at 6:56
  • Please refer this link stackoverflow.com/questions/49382355/…. Thanks. – Raj Jul 26 '18 at 6:57
  • 1
    Please check this link too magento.stackexchange.com/questions/125086/… – Ansar Husain Jul 26 '18 at 6:58
  • The answer by Rakesh in the link shared by Ansar seems best to be used. – Gagan Jul 26 '18 at 7:00
0

You can get products by category id by below code

$objectManager =  \Magento\Framework\App\ObjectManager::getInstance();
$categoryFactory = $objectManager->get('\Magento\Catalog\Model\CategoryFactory');
$categoryId = 6;
$category = $categoryFactory->create()->load($categoryId);
$categoryProducts = $category->getProductCollection()->addAttributeToSelect('*');

foreach ($categoryProducts as $product)
{
    echo $product->getName();
}

You should not use the ObjectManager directly!

|improve this answer|||||
  • Is that need any additional functionalities in php file that i have written block folder? – Nismath vi Jul 26 '18 at 7:29
  • Yes you can also create function in block file and call to phtml – Suresh Chikani Jul 26 '18 at 7:33
  • public function getCategory($categoryId) { $category = $this->_categoryFactory->create(); $category->load($categoryId); return $category; } public function getCategoryProducts($categoryId) { $products = $this->getCategory($categoryId)->getProductCollection(); $products->addAttributeToSelect('*'); return $products; } – Nismath vi Jul 26 '18 at 7:35
  • how to use object manager – Nismath vi Jul 26 '18 at 7:40
  • This is not a correct approach. Magento recommend not to use the object manager directly like this. Instead use DI approach. This will lead to other dependency errors if not found. Because you have created object of model directly. Instead of model you should create object of service contract. – Rahul Anand Sep 5 '19 at 1:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.