Showing posts with label Magento2. Show all posts
Showing posts with label Magento2. Show all posts

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