3

I tried to create category and subcategory image widget.I got first level of categories with category images.

app/code/Customcategory/CatewithimgWidget/Block/Widget CatewithimgWidget.php

class CatewithimgWidget extends 
\Magento\Framework\View\Element\Template implements 
\Magento\Widget\Block\BlockInterface
 {
protected $_template = 'widget/categorywidget.phtml';

/**
 * Default value for products count that will be shown
 */
 protected $_categoryHelper;
 protected $categoryFlatConfig;

 protected $topMenu;
 protected $_categoryFactory;

 protected $mainTitle;
 protected $tagLine;

/**
 * @param \Magento\Framework\View\Element\Template\Context $context
 * @param \Magento\Catalog\Helper\Category $categoryHelper
 * @param array $data
 */
public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Catalog\Helper\Category $categoryHelper,
    \Magento\Catalog\Model\Indexer\Category\Flat\State $categoryFlatState,
    \Magento\Catalog\Model\CategoryFactory $categoryFactory,
    \Magento\Theme\Block\Html\Topmenu $topMenu
) {
    $this->_categoryHelper = $categoryHelper;
    $this->categoryFlatConfig = $categoryFlatState;
    $this->topMenu = $topMenu;
    $this->_categoryFactory = $categoryFactory;
    parent::__construct($context);
}
/**
 * Return categories helper
 */
public function getCategoryHelper()
{
    return $this->_categoryHelper;
}

public function getCategorymodel($id)
{
     $_category = $this->_categoryFactory->create();
        $_category->load($id);
        return $_category;
}
/**
 * Retrieve current store categories
 *
 * @param bool|string $sorted
 * @param bool $asCollection
 * @param bool $toLoad
 * @return \Magento\Framework\Data\Tree\Node\Collection|\Magento\Catalog\Model\Resource\Category\Collection|array
 */

/**
 * Retrieve collection of selected categories
*/
  public function getCategoryCollection()
{
     $rootCat = $this->getData('parentcat');


    $category = $this->_categoryFactory->create();
    $collection = $category
                  ->getCollection()
                  ->addAttributeToSelect('image')
                  ->addIdFilter($rootCat);
    return $collection;
}

public function getMainTitle()
{
    $mainTitle = $this->getData('blocktitle');
    return $mainTitle;
}
}

app/code/Customcategory/CatewithimgWidget/etc module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation="../../../../../lib/internal
/Magento/Framework/Module/etc/module.xsd">
<module name="Customcategory_CatewithimgWidget" setup_version="1.0.0">
</module>

app/code/Customcategory/CatewithimgWidget/etc widget.xml

<?xml version="1.0" encoding="UTF-8"?>
<widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Widget:etc/
widget.xsd">
<widget id="Customcategory_catewithimgwidget" 
 class="Customcategory\CatewithimgWidget\Block\Widget
 \CatewithimgWidget">
    <label translate="true">Category List with image Widget</label>
    <description>Store Default 1st level Category List 
  Widget</description>
    <parameters>
        <parameter name="blocktitle" xsi:type="text"  visible="true" 
required="true" sort_order="1">
            <label translate="true">Block Title</label>
        </parameter>
        <parameter name="tagline" xsi:type="text"  visible="true" 
  required="true" sort_order="2">
            <label translate="true">class</label>
        </parameter>
        <parameter name="parentcat"  xsi:type="multiselect"  
  visible="true" sort_order="3" 

 source_model="Customcategory\CatewithimgWidget\Model\Config\Source
 \Categorylist">
            <label translate="true">Select Categories</label>
            <description translate="true">Category must have image 
  uploaded</description>
        </parameter>
    </parameters>
   </widget>
 </widgets>

app/code/Customcategory/CatewithimgWidget/Model/Config/Source/Categorylist.php

        <?php
  namespace Customcategory\CatewithimgWidget\Model\Config\Source;
  use Magento\Framework\Option\ArrayInterface;
  use Magento\Catalog\Helper\Category;

  class Categorylist implements ArrayInterface
  {
   protected $_categoryHelper;

public function __construct(\Magento\Catalog\Helper\Category 
$catalogCategory)
{
    $this->_categoryHelper = $catalogCategory;
}

/*
 * Return categories helper
 */

public function getStoreCategories($sorted = false, $asCollection = false, $toLoad = true)
{
    return $this->_categoryHelper->getStoreCategories($sorted , $asCollection, $toLoad);
}

/*
 * Option getter
 * @return array
 */
public function toOptionArray()
{


    $arr = $this->toArray();
    $ret = [];

    foreach ($arr as $key => $value)
    {

        $ret[] = [
            'value' => $key,
            'label' => $value
        ];
    }

    return $ret;
}

/*
 * Get options in "key-value" format
 * @return array
 */
public function toArray()
{

    $categories = $this->getStoreCategories(true,false,true);

    $catagoryList = array();
    foreach ($categories as $category){

        $catagoryList[$category->getEntityId()] = __($category->getName());
    }

    return $catagoryList;
}

 }
  ?>

app/code/Customcategory/CatewithimgWidget/view/frontend/layout/default.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
    <css src="Customcategory_CatewithimgWidget::css/widget.css" />
</head>

app/code/Customcategory/CatewithimgWidget/view/frontend/templates/widget/categorywidget.phtml

<?php
$categories = $this->getCategoryCollection();
$categoryHelper = $this->getCategoryHelper();
?>
<div class="widget block block-static-block cwiw" id="catewithimg">
<div class="block-content">
    <div class="content-heading">
        <h2 class="title"><?php echo $this->getMainTitle(); ?></h2>

    <div class="row">
    <?php
    foreach($categories as $category):
        $cat = $this->getCategorymodel($category->getId());
        $image = $cat->getImageUrl();
    ?>
        <?php if($image != null): ?>
            <div class="col-md-4">
                <a class="category_name" href="<?php echo $cat- 
 >getUrl(); ?>">
                   <img src="<?php echo $image; ?>" class="img-responsive category_image" alt="<?php echo $cat->getName(); ?>" />
                    <h3><span><?php echo $cat->getName(); ?></span></h3>
                </a>
            </div>
        <?php endif; ?>
    <?php endforeach; ?>
    </div>
</div>

app/code/Customcategory/CatewithimgWidget/view/frontend/web/css/widget.css

.cwiw{
width: 100%;
clear: both;
float: none;
text-align: center;
 }
.cwiw .row{
margin-bottom: 20px;
margin-right: -15px;
margin-left: -15px;
}
.cwiw .row:before,
.cwiw .row:after{
display: table;
content: " ";
}

.cwiw .row .col-md-4{
width: 33.33333333%;
float: left;
}

.cwiw a:hover{
 text-decoration: none;
}

the widget looks like enter image description here how to get a category tree instead of select category

  • @Sukumar Gorai can you please help me to figure out! – Nismath vi Aug 20 '18 at 13:19
  • Do you want to show the category tree like magento's default category tree or You want to add sub categories in your list? Also Do you want multiple select? – Sukumar Gorai Aug 20 '18 at 13:36
  • @SukumarGorai it have multiple select. i want to add category tree like magento's default category – Nismath vi Aug 20 '18 at 13:40
  • But that is not multi select? Do you want multi select? – Sukumar Gorai Aug 20 '18 at 13:40
  • @SukumarGorai yeah i want multi select also. – Nismath vi Aug 20 '18 at 13:41
1

You need to replace your widget.xml with below code:

<?xml version="1.0" encoding="UTF-8"?>
<widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Widget:etc/widget.xsd">
    <widget id="Customcategory_catewithimgwidget" class="Customcategory\CatewithimgWidget\Block\Widget\CatewithimgWidget">
        <label translate="true">Category List with image Widget</label>
        <description>Store Default 1st level Category List Widget</description>
        <parameters>
            <parameter name="blocktitle" xsi:type="text"  visible="true" required="true" sort_order="1">
                <label translate="true">Block Title</label>
            </parameter>
            <parameter name="tagline" xsi:type="text"  visible="true" required="true" sort_order="2">
                <label translate="true">class</label>
            </parameter>
            <parameter name="parentcat" xsi:type="block" visible="true" required="true" sort_order="10">
                <label translate="true">Categories</label>
                <description translate="true">Category must have image uploaded</description>
                <block class="Customcategory\CatewithimgWidget\Block\Adminhtml\Chooser" />
            </parameter>
        </parameters>
    </widget>
</widgets>

And need to create one more Block Class like below: Under

app/code/Customcategory/CatewithimgWidget/Block/Adminhtml/Chooser.php

<?php
namespace Customcategory\CatewithimgWidget\Block\Adminhtml; 

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

    protected $_elementFactory;

    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);
    }

    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;
    }
}

Thats it. Run di compile and other necessary commands.

Hope this helps!

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.