2

I am creating a module where I am listing a custom table, in admin area. I have a status field in the database. What I want is to disable/remove some of the select option from the status field,when user try to edit, based on the condition.

This is my column which shows status:

    <column name="Sub_Status" component="Magento_Ui/js/grid/columns/select">
            <settings>
                <options class="vendor\module\Model\Status\Source\Status" />
                <editor>
                    <editorType>select</editorType>
                </editor>
                <dataType>select</dataType>
                <label translate="true">Status</label>
            </settings>
      </column>

I tried to manipulate data on the related class Status.php

<?php

namespace vendor\module\Model\Status\Source;

use Magento\Framework\Data\OptionSourceInterface;

class Status implements OptionSourceInterface
{
    protected $status;
    //Here you can __construct Model

    public function toOptionArray()
    {
        $result1 = //has all the db records;
        $currentDate = date("m-d-Y");
        for($i=0;$i<count($result1);$i++){
            $subsOrderDate=$result1[$i]['Subcription_Order_Date'];
            $subsOrderSKU=$result1[$i]['Sub_Sku'];
            $check = 'false';
            if($subsOrderDate<$currentDate){
                $check = 'true';
            }
            switch($check){
                case 'true':                
                    $result[] = ['value' => 4, 'label' => __('Pending')];
                    break;
                case 'false':
                    $result[] = ['value' => 3, 'label' => __('On Hold')];
                    break;
                
                default:
                    $result[] = [
                        ['value' => 0, 'label' => __('Cancelled')],
                        ['value' => 1, 'label' => __('Original Order')],
                        ['value' => 2, 'label' => __('Payment Failed')],
                        ['value' => 3, 'label' => __('On Hold')],
                        ['value' => 4, 'label' => __('Pending')]
                    ];
            }
        }
return $result;
}
}


But no luck..How can i achieve this. please help.

2
  • you mean you want conditions to be checked on Edit form page, not on Grid and show all options on grid?sorry, your question is a bit confusing to me. Nov 4, 2020 at 7:33
  • @AbdulSamadAbbasi It is simple, when admin edit the rows(using inline edit) i want to remove some of the option from the dropdown list. EX- let sayd, if condition matches i want there only one option "cancelled" there, rest of them should not be there.
    – Nit
    Nov 4, 2020 at 8:12

1 Answer 1

0

I think you don't do that in toOptionArray(). Here's what I think should work. Your column in listing UI form:

    <column name="column_name" class ="Vendor\Module\Ui\Component\Listing\Grid\Column\ClassName" >
            <settings>
                <options class="Vendor\Module\Model\FreeShippingBar\Source\Status"/>
                <filter>select</filter>
                <editor>
                    <editorType>select</editorType>
                </editor>
                <dataType>select</dataType>
                <label translate="true">Column Name</label>
            </settings>
        </column>

In the class file path given in <cloumn> tag on first line:


use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Ui\Component\Listing\Columns\Column;

class ClassName extends Column
{
    /**
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @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'])) {
            foreach ($dataSource['data']['items'] as &$items) {
                $item='';
                foreach ($items['column_name'] as $status) {
                    if ($status == "pending"/*status value in database*/ && $items['date']==/*getCurrentDate*/) {
                        $item .= "Onhold<br>";
                        $item .= "Cancelled<br>";
                    } elseif ($status == "onhold" && $items['date']==/*getCurrentDate*/) {
                        $item .= "Display<br>";
                    } 
                }
                $items['column_name'] = $item;
            }
        }
        return $dataSource;
    }
}

Acttually, the conditions I checked maybe not for you but just to get you started that how it works. Whatever you return from here $dataSource will be displayed on grid. You can try this and let me know if it does your job.

5
  • great..but can you confirm that this will change the dropdown value not the value coming from the database?? I am confused.
    – Nit
    Nov 6, 2020 at 6:53
  • It will only display on grid, nothing will be changed. For example, if value is 20, it'll stay 20 but on grid it will show Display instead of 20 just to make sense. Nov 6, 2020 at 6:56
  • let me make you more clear..Suppose I have 4 status..pending,onhold,success,cancelled. If a user has pending status currently, and the condition matches (which is a date comparison from database date value and current date) i want to show only 2 status to be changed onhold,cancelled.
    – Nit
    Nov 6, 2020 at 7:09
  • I've edited my code, it's a bit messy but you can get the idea. All the conditions you want to check before displaying in grid can be implemented here. I haven't tested the edited part but think it should work or you can ask if it doesn't. Nov 6, 2020 at 7:28
  • sure buddy, will let you know once i try this
    – Nit
    Nov 6, 2020 at 8:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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