ActiveForm Update label of submit button dependend on selection of form dropdowns

Hi there,

The database is a huge list of items which all have 4 properties (size, covertype, color, weight). The form is for filtering these items and after submitting the form the user is displayed all items which correspong the the choices he made in the form.

I have a simple ActiveForm with 4 dropdowns. One dropdown per property. It is mandatory to select a size and a covertype. Color and weight selections are optional.

At the moment the user makes his selections in the dropdowns and after hitting the submit button he is displayed all items in the database which have the properties he selected.

My goal is to dynamically change the label of the submit button after a selection was made in one of the dropdowns, to display how many items in the database are corresponding to the current selection.

For example:

  1. When in none of the dropdowns a selection was made, then the button is simply disabled.

  2. When the user has selected a size and a covertype the the ‘Submit’-button’s label is sth. like “Show 32 items”. The user can then press the submit button or narrow his search further.

  3. When the user has also selected a color then the ‘Submit’-buttons label updates to “Show 12 items”.

  4. When the user also selects something in the last dropdown (weight) the the label updates again “Show 3 items”.

  5. In the case the user selected the properties in such a way that no item in the database can be found which fulfills his selections then the button should show “No items found” and be disabled.

I think that is a common way how searches on popular websites work. For example if you are looking for real estate, cars or hotels. You make some selections and you know how many results will be found before you submit your search.

I tried around with ajaxvalidation but when i enable ajaxvalidation my submit-button isnt doing anything any longer XD

Here is some of my code. Stripped down to the important parts.

SiteController.php

public function actionIndex()
    { 
        $model = new ItemFilter();
        
        if ($model->load(Yii::$app->request->post())) 
        {
            return $this->actionShowitems($model);
        }
            
        return $this->render('index', ['model' => $model]);
    }

index.php

...
...
<?php $form = ActiveForm::begin([
            'id' => 'item-filter',
            //'enableAjaxValidation' => true,
            'enableClientValidation' => true,
        ],); ?>
        
        <div class="row">
            <div class="col-lg-8">
                <?= $form->field($model, 'size')
                    ->label(false)
                    ->dropdownList($sizes, ['prompt'=>'Choose a size...']); 
                ?>
            </div>
        </div>
        
        <div class="row">
            <div class="col-lg-8">
                <?= $form->field($model, 'cover')
                    ->label(false)
                    ->dropdownList($coverTypes, ['prompt'=>'Choose a covertype...']); 
                ?>
            </div>
        </div>
        
        <div class="row">
            <div class="col-lg-8">
                <?= $form->field($model, 'color')
                    ->label(false)
                    ->dropdownList($colors, ['prompt'=>'Choose a color...']); 
                ?>
            </div>
        </div>
        
        <div class="row">
            <div class="col-lg-8">
                <?= $form->field($model, 'weight')
                    ->label(false)
                    ->dropdownList($weights, ['prompt'=>'Choose a weight...']); 
                ?>
            </div>
        </div>
        
        
        <div class="row">        
            <div class="col-lg-offset-2 col-lg-10">
               <?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
            </div>
        </div>
        
        <?php ActiveForm::end() ?>

ItemFilter.php

class ItemFilter extends Model
{
    public $size;
    public $cover;
    public $color;
    public $weight;
    
    /**
     * @return array the validation rules.
     */
    public function rules()
    {
        return [            
            [['size', 'cover'], 'required'],
            [['color', 'weight'], 'default'],
        ];
    }
}

Any help would be really appreciated.

Does anybody have an idea how to achieve my goal? Would could be a way to achieve it? Using ajaxValidation or pjax? Or do i have to do something with renderPartial to just update the button?

Hi @raufaser, welcome to the forum!

I would do something like the following if I had to implement the search page as you want.

  1. In the view, write some JavaScript function that starts an ajax request with the contents of the form, and trigger it when there’s a change in one of the 4 dropdowns.
  2. In the controller, responding to the ajax request, count the items that satisfy the search parameters and send it back as the response.
  3. Again in the view, read the ajax response (i.e. item count) and change the label of the submit button accordingly.

But probably I would do something like the following just to satisfy the user needs.

  1. Use Gii’s CRUD generator for the item model to create the index view that has the search form and the gridview (or listview, more probably) that shows the search result.
  2. Change the text inputs to dropdowns in the search form.
  3. Write a simple JavaScript function to trigger the form submission when there’s a change in the dropdowns.

IMO, this is much simpler and more user friendly. If I were a user, I would want to see the search result on the fly rather than checking the item count before seeing the result in details.

If you are concerned about the performance of the search, setting a decent pagination size around 10 to 20 will solve the problem, I hope.