0

The module I'm working on has a form with three inputs, Low Range, High Range and Sort By Price. For some reason it's not returning the product collection at all.

I'm getting the following error:

Exception #0 (Exception): Warning: Invalid argument supplied for foreach() in \app\code\Vendor\CustPriceRange\view\frontend\templates\custpricerange.phtml on line 24

It looks to me like the product collection isn't being loaded properly. Is there a way to prevent the catalog from loading until the form is submitted? Maybe a second controller?

Any help would be appreciated.

Block\CustPriceRange.php

<?php
namespace Vendor\CustPriceRange\Block;
class CustPriceRange extends \Magento\Framework\View\Element\Template

{    
   protected $_productCollectionFactory;

    public function __construct(
       \Magento\Backend\Block\Template\Context $context,
       \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
       \Magento\Catalog\Model\Product\Attribute\Source\Status $productStatus,
       \Magento\Catalog\Model\Product\Visibility $productVisibility,
       \Magento\Framework\Registry $registry,
       array $data = []
     )
     {
       $this->_productCollectionFactory = $productCollectionFactory;
       parent::__construct($context, $data);
     }

     public function getProductCollection()
     {
       try {

         $collection = $this->_productCollectionFactory->create();
         $collection->addAttributeToSelect('*')
             ->addPriceDataFieldFilter('%s >= %s', ['final_price', $lowrange])
             ->addPriceDataFieldFilter('%s <= %s', ['final_price', $highrange])
             ->addFinalPrice()
             ->addAttributeToFilter('entity_id', ['neq' => $product->getId()])
             ->addAttributeToFilter('status', ['in' => $this->productStatus->getVisibleStatusIds()])
             ->setVisibility($this->productVisibility->getVisibleInSiteIds())
             ->setPageSize(10);

         if ($sortbyprice == 'D') {
            $collection->getSelect()->order('price_index.final_price DSC');
         } elseif ($sortbyprice == 'A') {
             $collection->getSelect()->order('price_index.final_price ASC');
         }

         return $collection;

       } catch (\Exception $e) {

         var_dump($e->getMessage());
       }
     }

}
?>

Controller\Customer\index.php

<?php 
namespace Vendor\CustPriceRange\Controller\Customer;  

use Magento\Framework\View\Result\PageFactory;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Controller\Result\JsonFactory;

class Index extends \Magento\Framework\App\Action\Action { 


    public function execute() { 

        $post = (array) $this->getRequest()->getPost();

        if (!empty($post)) {
            $lowrange     = $post['lowrange'];
            $highrange    = $post['highrange'];
            $sortbyprice  = $post['sortbyprice'];

            $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);

            return $resultJson;
        }

        $this->_view->loadLayout();
        $this->_view->renderLayout(); 

    } 
} 

?>

view\frontend\templates\custpricerange.phtml

<?php 

?>
<span> Custom Price Range </span>
<div id="formarea">

   <form id="pricerange" name="pricerange" method="post">
      <input type="number" id="lowrange" name="lowrange" min="0" data-validate="{required:true}" placeholder="Low Range">
      <input type="number" id="highrange" name="highrange" min="0" data-validate="{required:true}" placeholder="High Range">
      <select name="sortbyprice" id="sortbyprice">
         <option value="A">Ascending</option>
         <option value="D">Descending</option>
      </select>
      <input type="submit">
   </form>
</div>


<div id="catalogarea">
   <?php

   $collection = $block->getProductCollection();

foreach ($collection as $_product) {
    echo $_product->getThumbnail()  . ' - ' . $_product->getSku() . ' - ' . $_product->getName() . ' - ' . $_product->getQty()  . ' - ' . $_product->getPrice() . ' - ' . $_product->getProductUrl() . '<br />';
}

    ?>
</div>


<script>
   $(document).ready(function() {
      $("#pricerange").submit(function() {

         var dataForm = $('#pricerange');
         dataForm.mage('validation', {});

         var lowrange = dataForm.find('input[name="lowrange"]').val();
         var highrange = dataForm.find('input[name="highrange"]').val();


         if ((highrange >= lowrange) && (highrange <= (lowrange * 5))) {

            jQuery.ajax({
               url: "/custpricerange/customer/index",
               type: "POST",
               data: {
                  lowrange: lowrange,
                  highrange: highrange,
                  sortbyprice: sortbyprice
               },
               success: function(response) {
                  console.log(response);
               }
            })
         } else {
            return false;
         };
      });
   });

</script>

Your Answer

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

Browse other questions tagged or ask your own question.