Friday, July 7, 2017

How to use Rendere with HTML conent in UI Component Grid in Magento 2

In my custom module grid i have to use custom grid column which render a field and create custom html content how to implement it in Magento 2 1. in ui listing xml add below code in side columns tag
<column name="manufacturers" class="NAMEPACE\MODULENAME\Ui\Component\Listing\Column\Product\Manufacturers">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">NAMEPACE_MODULENAME/js/columns/html</item>
                    <item name="sortable" xsi:type="boolean">false</item>
                    <item name="altField" xsi:type="string">name</item>
                    <item name="label" xsi:type="string" translate="true">Manufacturers</item>
                    <item name="sortOrder" xsi:type="number">90</item>
                </item>
            </argument>
        </column>

2. Create Column file (path as per class name)

<?php
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace NAMEPACE\MODULENAME\Ui\Component\Listing\Column\Product;

use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\View\Element\UiComponent\ContextInterface;

class Manufacturers extends \Magento\Ui\Component\Listing\Columns\Column
{
    /**
     * Column name
     */
    const NAME = 'column.manufacturers';
    /**
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @param \Magento\Framework\Locale\CurrencyInterface $localeCurrency
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param array $components
     * @param array $data
     */
    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        array $components = [],
        array $data = []
    ) {
        parent::__construct($context, $uiComponentFactory, $components, $data);
    }

    /**
     * Prepare Data Source
     *
     * @param array $dataSource
     * @return array
     */
    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource['data']['items'])) {

            $fieldName = $this->getData('name');
            foreach ($dataSource['data']['items'] as & $item) {
                if (isset($item[$fieldName])) {
                    $html = '';
                    $manufacturers = unserialize($item[$fieldName]);
                    if (!empty($manufacturers)) {
                        foreach ($manufacturers as $manufacturer) {
                            if ($manufacturer['primary'] == 'Y') {
                                $html .= '<strong>';
                            }

                            $html .= $manufacturer['name'];

                            if (!empty($manufacturer['product_code'])) {
                                $html .= ' | ' . __('SKU') . ': ' . $manufacturer['product_code'];
                            }

                            if ($manufacturer['primary'] == 'Y') {
                                $html .= '</strong>';
                            }

                            $html .= '<br />';
                        }
                    }
                    $item[$fieldName] = $html;
                }
            }
        }

        return $dataSource;
    }
}
3. create custom js file to reneder html conent path :- NAMESPACE/MODULENAME/view/adminhtml/web/js/columns/html.js
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
define([
    'underscore',
    'uiRegistry',
    'mageUtils',
    'uiElement'
], function (_, registry, utils, Element) {
    'use strict';

    return Element.extend({
        defaults: {
            headerTmpl: 'ui/grid/columns/text',
            bodyTmpl: 'ui/grid/cells/html',
            disableAction: false,
            controlVisibility: true,
            sortable: true,
            sorting: false,
            visible: true,
            draggable: true,
            fieldClass: {},
            ignoreTmpls: {
                fieldAction: true
            },
            statefull: {
                visible: true,
                sorting: true
            },
            imports: {
                exportSorting: 'sorting'
            },
            listens: {
                '${ $.provider }:params.sorting.field': 'onSortChange'
            },
            modules: {
                source: '${ $.provider }'
            }
        },

        /**
         * Initializes column component.
         *
         * @returns {Column} Chainable.
         */
        initialize: function () {
            this._super()
                .initFieldClass();

            return this;
        },

        /**
         * Initializes observable properties.
         *
         * @returns {Column} Chainable.
         */
        initObservable: function () {
            this._super()
                .track([
                    'visible',
                    'sorting',
                    'disableAction'
                ])
                .observe([
                    'dragging'
                ]);

            return this;
        },

        /**
         * Extends list of field classes.
         *
         * @returns {Column} Chainable.
         */
        initFieldClass: function () {
            _.extend(this.fieldClass, {
                _dragging: this.dragging
            });

            return this;
        },

        /**
         * Applies specified stored state of a column or one of its' properties.
         *
         * @param {String} state - Defines what state should be used: saved or default.
         * @param {String} [property] - Defines what columns' property should be applied.
         *      If not specified, then all columns stored properties will be used.
         * @returns {Column} Chainable.
         */
        applyState: function (state, property) {
            var namespace = this.storageConfig.root;

            if (property) {
                namespace += '.' + property;
            }

            this.storage('applyStateOf', state, namespace);

            return this;
        },

        /**
         * Sets columns' sorting. If column is currently sorted,
         * than its' direction will be toggled.
         *
         * @param {*} [enable=true] - If false, than sorting will
         *      be removed from a column.
         * @returns {Column} Chainable.
         */
        sort: function (enable) {
            if (!this.sortable) {
                return this;
            }

            enable !== false ?
                this.toggleSorting() :
                this.sorting = false;

            return this;
        },

        /**
         * Sets descending columns' sorting.
         *
         * @returns {Column} Chainable.
         */
        sortDescending: function () {
            if (this.sortable) {
                this.sorting = 'desc';
            }

            return this;
        },

        /**
         * Sets ascending columns' sorting.
         *
         * @returns {Column} Chainable.
         */
        sortAscending: function () {
            if (this.sortable) {
                this.sorting = 'asc';
            }

            return this;
        },

        /**
         * Toggles sorting direction.
         *
         * @returns {Column} Chainable.
         */
        toggleSorting: function () {
            this.sorting === 'asc' ?
                this.sortDescending() :
                this.sortAscending();

            return this;
        },

        /**
         * Checks if column is sorted.
         *
         * @returns {Boolean}
         */
        isSorted: function () {
            return !!this.sorting;
        },

        /**
         * Exports sorting data to the dataProvider if
         * sorting of a column is enabled.
         */
        exportSorting: function () {
            if (!this.sorting) {
                return;
            }

            this.source('set', 'params.sorting', {
                field: this.index,
                direction: this.sorting
            });
        },

        /**
         * Checks if column has an assigned action that will
         * be performed when clicking on one of its' fields.
         *
         * @returns {Boolean}
         */
        hasFieldAction: function () {
            return !!this.fieldAction || !!this.fieldActions;
        },

        /**
         * Applies action described in a 'fieldAction' property
         * or actions described in 'fieldActions' property.
         *
         * @param {Number} rowIndex - Index of a row which initiates action.
         * @returns {Column} Chainable.
         *
         * @example Example of fieldAction definition, which is equivalent to
         *      referencing to external component named 'listing.multiselect'
         *      and calling its' method 'toggleSelect' with params [rowIndex, true] =>
         *
         *      {
         *          provider: 'listing.multiselect',
         *          target: 'toggleSelect',
         *          params: ['${ $.$data.rowIndex }', true]
         *      }
         */
        applyFieldAction: function (rowIndex) {
            if (!this.hasFieldAction() || this.disableAction) {
                return this;
            }

            if (this.fieldActions) {
                this.fieldActions.forEach(this.applySingleAction.bind(this, rowIndex), this);
            } else {
                this.applySingleAction(rowIndex);
            }

            return this;
        },

        /**
         * Applies single action
         *
         * @param {Number} rowIndex - Index of a row which initiates action.
         * @param {Object} action - Action (fieldAction) to be applied
         *
         */
        applySingleAction: function (rowIndex, action) {
            var callback;

            action = action || this.fieldAction;
            action = utils.template(action, {
                column: this,
                rowIndex: rowIndex
            }, true);

            callback = this._getFieldCallback(action);

            if (_.isFunction(callback)) {
                callback();
            }
        },

        /**
         * Returns field action handler if it was specified.
         *
         * @param {Object} record - Record object with which action is associated.
         * @returns {Function|Undefined}
         */
        getFieldHandler: function (record) {
            if (this.hasFieldAction()) {
                return this.applyFieldAction.bind(this, record._rowIndex);
            }
        },

        /**
         * Creates action callback based on its' data.
         *
         * @param {Object} action - Actions' object.
         * @returns {Function|Boolean} Callback function or false
         *      value if it was impossible create a callback.
         */
        _getFieldCallback: function (action) {
            var args     = action.params || [],
                callback = action.target;

            if (action.provider && action.target) {
                args.unshift(action.target);

                callback = registry.async(action.provider);
            }

            if (!_.isFunction(callback)) {
                return false;
            }

            return function () {
                callback.apply(callback, args);
            };
        },

        /**
         * Ment to preprocess data associated with a current columns' field.
         *
         * @param {Object} record - Data to be preprocessed.
         * @returns {String}
         */
        getLabel: function (record) {
            return record[this.index];
        },

        /**
         * Returns list of classes that should be applied to a field.
         *
         * @returns {Object}
         */
        getFieldClass: function () {
            return this.fieldClass;
        },

        /**
         * Returns path to the columns' header template.
         *
         * @returns {String}
         */
        getHeader: function () {
            return this.headerTmpl;
        },

        /**
         * Returns path to the columns' body template.
         *
         * @returns {String}
         */
        getBody: function () {
            return this.bodyTmpl;
        },

        /**
         * Listener of the providers' sorting state changes.
         *
         * @param {Srting} field - Field by which current sorting is performed.
         */
        onSortChange: function (field) {
            if (field !== this.index) {
                this.sort(false);
            }
        }
    });
});
Clear cache :-)

Thursday, January 21, 2016

One single field validation or Validate Form Only Certain Fields in Magneto2

If you need to validate one field of form before submitting form that is on change or on blur one or single field validation in Magento2 form use below code i took one ex of email validation if you need to validate a email filed while editing field it self use this code so error msg or validation will happen once you change to other field no need for submitting all form

Thursday, November 12, 2015

I Started Forum for Magento2

Hi Guys i started working on magento2 you guys can follow me on click Here

Tuesday, July 14, 2015

Early Magento Session Instantiation or PHPSESSID in Magento

While doing security fix in magento we come across one unknown session is getting create which name has php default session PHPSESSID after debugging we come to when customer session is int at that time we are not passing session name so to block PHPSESSID need to add else condition in Mage_Core_Model_Session_Abstract_Varien::start()
 if (!empty($sessionName)) {
            $this->setSessionName($sessionName);
        }else{
   return $this;
  }

else{ return $this; }
got some clue from http://alanstorm.com/magento_sessions_early but as per this block they are doing same change in event level i did it in core abstract file itself

Thursday, May 7, 2015

Magento Grouped Products Containing Associated Configurable Products


for

http://brimllc.com/2010/12/magento-grouped-products-containing-associated-configurable-products/

in group.php add below code

if($subProduct->getTypeId() == 'configurable' ){
      $buyRequestconfig['super_attribute']=$buyRequest['super_attribute'][$subProduct->getId()];
      $buyRequestconfig['product']=$subProduct->getId();
      //$buyRequestconfig['product_id']=$subProduct->getId();
      $buyRequestconfig['qty'] = $buyRequest['super_group'][$subProduct->getId()];
      $buyRequestconfig['form_key'] = $buyRequest['form_key'];
      $buyRequestconfig['uenc'] = $buyRequest['uenc'];
      //$cart = Mage::getModel("checkout/cart");
      //$cart->addProduct($subProduct, $buyRequestconfig); 
      //print_r($buyRequest); exit;
/*        $products[] = $subProduct->getTypeInstance(true)
          ->_prepareProduct(
           $buyRequestconfig,
           $subProduct,
           $processMode
          );
      
 */      
      $subProduct = $subProduct->getTypeInstance(true)->getProductByAttributes($buyRequestconfig['super_attribute'], $subProduct);
       $productsInfo[$subProduct->getId()]=1;
     }

and also in 

configurable.phtml

<?php 
/**
 * This template handles individual configurable products that have been associated with a grouped product.
 */
?>

<?php
$_product    = $this->getProduct();
$_attributes = Mage::helper('core')->decorateArray($this->getAllowAttributes());
$_formId = "product_addtocart_wrapper_".$_product->getId();
$_formJsVar = "productAddToCartForm".$_product->getId();
?>
<div class="price-box"><?php //echo $this->getPriceHtml($_product); ?></div>
<div id="<?php echo $_formId ?>">

<h3><?php echo $_product->getName() ?></h3>

<div class="no-display">
 <input type="hidden" name="product" value="<?php echo $_product->getId() ?>" />
    <input type="hidden" name="related_product" id="related-products-field" value="" />
</div>

<?php if ($_product->isSaleable() && count($_attributes)):?>
    <dl>
    <?php foreach($_attributes as $_attribute): ?>
        <dt><label><?php echo $_attribute->getLabel() ?><span class="required"> *</span></label></dt>
        <dd<?php if ($_attribute->decoratedIsLast){?> class="last"<?php }?>>
          <select name="super_attribute[<?php echo $_product->getId() ?>][<?php echo $_attribute->getAttributeId() ?>]" id="attribute<?php echo $_attribute->getAttributeId() ?>" class="go-qty-required-entry  required-entry super-attribute-select">
            <option><?php echo $this->__('Choose an Option...') ?></option>
          </select>
        </dd>
    <?php endforeach; ?>
    </dl>
    <script type="text/javascript">
        var spConfig = new Product.GroupedConfig(<?php echo $this->getJsonConfig() ?>, <?php echo $_product->getId() ?>);
        spConfig.setOptionsPrice(new Product.OptionsPrice(<?php echo Mage::helper('groupedconfigured')->getProductViewJsonConfig($_product) ?>));
    </script>
    <?php echo $this->getPriceHtml($_product) ?>
    
   
    <input id="super_group_<?php echo $_product->getId(); ?>" type="hidden" name="super_group[<?php echo $_product->getId() ?>]" maxlength="12" value="1<?php //echo $_item->getQty()*1 ?>" title="<?php echo $this->__('Qty') ?>" class="input-text qty" />                            
    <script type="text/javascript">
    //<![CDATA[
            var <?php echo $_formJsVar ?> = new VarienForm('<?php echo $_formId ?>');
            <?php echo $_formJsVar ?>.submit = function(){
                    if (this.validator.validate()) {
                            this.form.submit();
                    }
            }.bind(<?php echo $_formJsVar ?>);
    //]]>
    </script>
<?php endif;?>
</div>


which will support magento1.9

Monday, April 13, 2015

Concatenate two fields in admin grid with filter in magento

i override Mage/Adminhtml/Block/Sales/Order/Grid.php to local and You can use this technique for any Magento core file. This way, you can avoid overriding the core file. This way, you can also avoid the risk of over writing your custom code by the system during the Magento system upgrade operation. Now, go for the main action. Open the Grid.php file from its new local directory and look at the following block of code carefully:
protected function _getCollectionClass()
{
    return 'sales/order_grid_collection';
}
 
protected function _prepareCollection()
{
    $collection = Mage::getResourceModel($this->_getCollectionClass());
    /* adding customer name section */       
$customerFirstNameAttr = Mage::getSingleton('customer/customer')->getResource()->getAttribute('firstname');
$customerLastNameAttr = Mage::getSingleton('customer/customer')->getResource()->getAttribute('lastname');
$collection->getSelect()
                    ->joinLeft(
                        array('cusFirstnameTb' => $customerFirstNameAttr->getBackend()->getTable()),
                        'main_table.customer_id = cusFirstnameTb.entity_id AND cusFirstnameTb.attribute_id = '.$customerFirstNameAttr->getId(). ' AND cusFirstnameTb.entity_type_id = '.Mage::getSingleton('customer/customer')->getResource()->getTypeId(),
                        array('cusFirstnameTb.value')
                    );   
     
$collection->getSelect()
                    ->joinLeft(
                        array('cusLastnameTb' => $customerLastNameAttr->getBackend()->getTable()),
                        'main_table.customer_id = cusLastnameTb.entity_id AND cusLastnameTb.attribute_id = '.$customerLastNameAttr->getId(). ' AND cusLastnameTb.entity_type_id = '.Mage::getSingleton('customer/customer')->getResource()->getTypeId(),
                        array('customer_name' => "CONCAT(cusFirstnameTb.value, ' ', cusLastnameTb.value)")
                    ); 
    /* end adding customer name section */ 
    $this->setCollection($collection);
    return parent::_prepareCollection();
}
Now take a deep look at the following portion from the above code section. You’ll understand that this following section is the newly added custom code:
/* adding customer name section */       
    $customerFirstNameAttr = Mage::getSingleton('customer/customer')->getResource()->getAttribute('firstname');
    $customerLastNameAttr = Mage::getSingleton('customer/customer')->getResource()->getAttribute('lastname');
    $collection->getSelect()
                        ->joinLeft(
                            array('cusFirstnameTb' => $customerFirstNameAttr->getBackend()->getTable()),
                            'main_table.customer_id = cusFirstnameTb.entity_id AND cusFirstnameTb.attribute_id = '.$customerFirstNameAttr->getId(). ' AND cusFirstnameTb.entity_type_id = '.Mage::getSingleton('customer/customer')->getResource()->getTypeId(),
                            array('cusFirstnameTb.value')
                        );   
         
    $collection->getSelect()
                        ->joinLeft(
                            array('cusLastnameTb' => $customerLastNameAttr->getBackend()->getTable()),
                            'main_table.customer_id = cusLastnameTb.entity_id AND cusLastnameTb.attribute_id = '.$customerLastNameAttr->getId(). ' AND cusLastnameTb.entity_type_id = '.Mage::getSingleton('customer/customer')->getResource()->getTypeId(),
                            array('customer_name' => "CONCAT(cusFirstnameTb.value, ' ', cusLastnameTb.value)")
                        ); 
/* end adding customer name section */ 
in the admin sales order grid with the name “customer_name” by inserting the following code snippet in the _prepareColumns() method of the Mage_Adminhtml_Block_Sales_Order_Grid class :
$this->addColumn('customer_name', array(
    'header'    => Mage::helper('adminhtml')->__('Customer Name'),
    'index'     => 'customer_name',
    'filter_condition_callback' => array($this, 'customerNameFilter'),
    'width'     => '120px',
)); 
public function customerNameFilter($collection, $column){
    $filterValue = $column->getFilter()->getValue();
    if(!is_null($filterValue)){
        $filterValue = trim($filterValue);
        $filterValue = preg_replace('/[\s]+/', ' ', $filterValue);
 
        $whereArr = array();
        $whereArr[] = $collection->getConnection()->quoteInto("cusFirstnameTb.value = ?", $filterValue);
        $whereArr[] = $collection->getConnection()->quoteInto("cusLastnameTb.value = ?", $filterValue);
        $whereArr[] = $collection->getConnection()->quoteInto("CONCAT(cusFirstnameTb.value, ' ', cusLastnameTb.value) = ?", $filterValue);
        $where = implode(' OR ', $whereArr);
        $collection->getSelect()->where($where);
    }
}

Thursday, February 5, 2015

Magento Auto Login and Auto Authorize for Rest API

We can skip login and authorize page when your doing rest api call in magento we can just make it admin login and create the token by using that token and secret key we can access need rest api for more information you can contact me pradeep.kumarrcs67@gmail.com +91-9916038230