gugoan
gugoan

Reputation: 780

Change properties from another field

I need you to change the PRODUCT field (dropdownlist) is changed the MIN and MAX properties kartik\SLIDER component

---- form ----

<?=
        $form->field($model, 'product_id', [
            'inputOptions' => [
                'class' => 'selectpicker '
            ]
        ]
        )->dropDownList(app\models\Product::getHierarchy(), ['prompt' => 'Selecione', 'class'=>'form-control required']);
?>

use kartik\slider\Slider;
echo $form->field($model, 'commission_percent')->widget(Slider::classname(), [
            'name'=>'commission_percent',
            'value'=>7,
            'sliderColor'=>Slider::TYPE_GREY,
            'handleColor'=>Slider::TYPE_SUCCESS,
            'pluginOptions'=>[
                'handle'=>'round',
                'tooltip'=>'always',
                'min'=>10,
                'max'=>50,
                'step'=>1,
            ]
        ]);

---- rules ----

['commission_percent', 'number','min'=>30,'max'=>40, 'when' => function($model) {
                return $model->product_id == 14;
            }],

EDITED

Each product has a max value and minimum commission amount. I do not know how to catch these values and transfer to the properties max and min of SLIDER.

EDITED 2

My controller actionListx return:

Invalid Parameter – yii\base\InvalidParamException Response content must not be an array.

My _form:

<?php
$productId = Html::getInputId($model, 'product_id');
$comissionId = Html::getInputId($model, 'commission_percent');
$url = \Yii::$app->getUrlManager()->createUrl('/dailyproductivity/listx');
$js = <<<JS
$('#{$productId}').on('change', function () {
    var form = $('#dailyproductivity-form');
    $.ajax({
        url: '{$url}',
        type: 'post',
        data: form.serialize(),
        success: function(data) {
            var min = data.min;
            var max = data.max;

            $("#{$comissionId}").data('slider').options.min = min;
            $("#{$comissionId}").data('slider').options.max = max;
            $("#{$comissionId}").slider('setValue', min);
        }
    });
});
JS;
$this->registerJs($js);
?>

My ProductivityController:

public function actionListx()
    {
        $model = new Dailyproductivity();

        if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
            Yii::$app->response->format = Response::FORMAT_JSON;

            $product = Product::findOne($model->product_id);

            if ($product !== null) {
                return [
                    'min' => $product->min_value,
                    'max' => $product->max_value,
                ];
            }
        }

        return [
        'min' => '0',
        'max' => '100'
    ];
}

Print

enter image description here

Upvotes: 0

Views: 909

Answers (1)

Clyff
Clyff

Reputation: 4076

If you are not saving this min and max values and the correspond ids somewhere in your db (and i think you should), you can do that with pure js. Here is a example:

<?php
$productId = Html::getInputId($model, 'product_id');
$comissionId = Html::getInputId($model, 'commission_percent');
$js = <<<JS
$('#{$productId}').on('change', function () {
    var id = $(this).val();

    if (id == 14) {
        var min = 30;
        var max = 40;
    } else {
        var min = 0;
        var max = 100;
    }

    $("#{$comissionId}").data('slider').options.min = min;
    $("#{$comissionId}").data('slider').options.max = max;
    $("#{$comissionId}").slider('setValue', min);
});
JS;
$this->registerJs($js);

And make sure to add the new rule in your model:

public function rules()
{
    return [
        // the other rules
        // ...
        ['commission_percent', 'number','min'=>0,'max'=>100] // the general values
        ['commission_percent', 'validate']
    ];
}

/**
 * @param string $attribute
 */
public function validate($attribute)
{
    if ($this->product_id == 14) {
        $min = 30;
        $max = 40;

        if ($this->attribute < $min || $this->attribute > $max) {
            $this->addError($attribute, 'error message'));
        }
    }
}

But if you have a lot of products and each one have a specific value of min and max, instead of creating a bunch of if statements, you can create a new action that checks the model that have this two values (min and max) saved and return them. And you can access it with a ajax call.

Here is a example of this ajax (assuming you added the min_value and max_value attributes in your Product model:

in your view:

$productId = Html::getInputId($model, 'product_id');
$comissionId = Html::getInputId($model, 'commission_percent');
$url = Url::to(['controller/action-with-ajax']);

$js = <<<JS
$('#{$productId}').on('change', function () {
    var form = $('#my-form-id');
    $.ajax({
        url: '{$url}',
        type: 'post',
        data: form.serialize(),
        success: function(data) {
            var min = data.min;
            var max = data.max;

            $("#{$comissionId}").data('slider').options.min = min;
            $("#{$comissionId}").data('slider').options.max = max;
            $("#{$comissionId}").slider('setValue', min);
        }
    });
});
JS;
$this->registerJs($js);

And your controller:

public function actionWithAjax()
{
    $model = new Model(); // the model you are using in this form

    if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
        Yii::$app->response->format = Response::FORMAT_JSON;

        if ($product = Product::findOne($model->product_id)) !== null) {
            return [
                'min' => $product->min_value,
                'max' => $product->max_value,
            ];
        }
    }

    return [
        'min' => '0',
        'max' => '100'
    ];
}

Upvotes: 3

Related Questions