FORM with GET method causes repeated stacking of URL Parameters

  1. Problem Statement
  2. Explanation
  3. Solution

Problem Statement

You are using an ActiveForm in yii (both v1.x or 2), with a GET method like below:

// In Yii 2
$form = ActiveForm::begin([
    'id' => 'order-search-form',
    'method' => 'get',
]);
echo $form->field($searchModel, 'id');
echo Html::submitButton('Find', ['class' => 'btn btn-primary']);
ActiveForm::end();

// In Yii 1.x
$form = $this->beginWidget('CActiveForm', [
    'id' => 'order-search-form',
    'method' => 'get',
]);
echo $form->textInput($searchModel, 'id');
echo CHtml::submitButton('Find', ['class' => 'btn btn-primary']);
$this->endWidget();

On form submission you encounter this situation:

  • Initial uri is order/index.
  • After submitting form with id=111 your URL reads order/index?id=111.
  • After submitting form again your URL reads order/index?id=111&id=111

... and so on. The id parameter above keeps on stacking repeatedly, and is not the correct way you want to be submitting a form with GET method.

Explanation

The reason for the above behavior is due to a unique validation needed in Yii's Html::beginForm method. The query parameters in the action are ignored for GET method so Yii's Html::beginForm uses hidden inputs for each GET parameter to add them back. These hidden inputs gets stacked over the last URI call with every submission.

Solution

To avoid repeated parameter stacking, ensure you pass the action method while defining your form like below:

// In Yii 2
$form = ActiveForm::begin([
        'method' => 'get',
        'action' => Url::to(['order/index']),
]);

// In Yii 1.x
$form = $this->beginWidget('CActiveForm', [
        'method' => 'get',
        'action' => $this->createUrl('order/index'),
]);

This will automatically use the action URI set above for each form submission rather than relying on the URL from the address bar. Thus the URL parameter repetition and stacking will not happen.