Dynamic Form indexing in "onchange" function

Hello, I’ve made a dynamic form using wbraganca\dynamicform\DynamicFormWidget library.
Everything works fine as adding the fields and this stuff. But i have a problem with my javascript function.
So i have a dynamic form that has a dropdown field -> Nomenclature where u select a product and I want the next dropdown field -> Storage in same dynamic form to change it’s options when u select from Nomenclature. The problem is how to select the Storage field.

That is the form file:

<?php

use wbraganca\dynamicform\DynamicFormWidget;
use yii\helpers\Html;

/* @var $this yii\web\View */
/* @var $items app\models\DeliveryItem */
/* @var $form yii\bootstrap4\ActiveForm */
/* @var $nomenclature app\models\Nomenclature */
/* @var $storage app\models\Storage */

?>

<?php DynamicFormWidget::begin([
    'widgetContainer' => 'dynamicform_items', // required: only alphanumeric characters plus "_" [A-Za-z0-9_]
    'widgetBody' => '.container-items', // required: css class selector
    'widgetItem' => '.item', // required: css class
    'limit' => 3, // the maximum times, an element can be cloned (default 999)
    'min' => 1, // 0 or 1 (default 1)
    'insertButton' => '.add-item', // css class
    'deleteButton' => '.remove-item', // css class
    'model' => $items[0],
    'formId' => 'dynamic-form',
    'formFields' => [
        'nomenclature_id',
        'storage_id',
        'value',
        'price',
    ],
]); ?>

<div class="panel panel-default">
    <div class="panel-heading mb-1">
        <h5>Предмети</h5>
        <div class="clearfix"></div>
    </div>
    <div class="panel-body container-items"><!-- widgetContainer -->
        <button type="button" class="add-item btn btn-success btn-sm mb-1"><i class="fa fa-plus"></i> Добави предмет
        </button>

        <?php foreach ($items as $i => $item): ?>
            <div class="item panel panel-default mb-3"><!-- widgetBody -->
                <div class="panel-heading mb-1">
                    <span class="panel-title-item">Предмет: <?= ($i + 1) ?></span>
                    <button type="button" class="float-right remove-item btn btn-danger btn-sm"><i
                                class="fa fa-minus"></i></button>
                    <div class="clearfix"></div>
                </div>
                <div class="panel-body">
                    <?php
                    // necessary for update action.
                    if (!$item->isNewRecord) {
                        echo Html::activeHiddenInput($item, "[{$i}]id");
                    }
                    ?>

                    <?= $form->field($item, "[{$i}]nomenclature_id", ['options' => ['id' => $i]])->dropdownList(
                        $nomenclature,
                        [ 'prompt' => 'Избери номенклатура...',
                            'onchange' => '$.post("storages?id='.'"+$(this).val(), function(data) {
                                if(value.length != 0 && data.length != 0)
                                {
                                  $("select#deliveryitem-'.$i.'-storage_id").html(data);
                                  document.getElementById("deliveryitem-'.$i.'-storage_id").disabled = false;
                                }
                                else
                                {
                                    $("select#deliveryitem-'.$i.'-storage_id").html("<option>Избери номенклатура</option>");
                                    document.getElementById("deliveryitem-'.$i.'-storage_id").disabled = true;
                                }
                             });'
                        ]
                    ); ?>

                    <?= $form->field($item, "[{$i}]storage_id", ['options' => ['id' => $i]])->dropdownList(
                        $storage, [
                        'prompt' => 'Избери склад...',
                        'disabled' => true,
                    ]) ?>

                    <?= $form->field($item, "[{$i}]value", ['options' => ['id' => $i]])->textInput(['maxlength' => true]) ?>

                    <?= $form->field($item, "[{$i}]price", ['options' => ['id' => $i]])->textInput(['maxlength' => true]) ?>
                </div>
            </div>
        <?php endforeach; ?>
    </div>
    <button type="button" class="add-item btn btn-success btn-sm"><i class="fa fa-plus"></i> Добави предмет</button>
</div>
<?php DynamicFormWidget::end(); ?>

This is from the inspect mode and this one is the first dynamic form. everything is allright. Works Fine!

<select id="deliveryitem-0-nomenclature_id" class="form-control is-valid" name="DeliveryItem[0][nomenclature_id]" onchange="$.post(&quot;storages?id=&quot;+$(this).val(), function(data) {
                                if(value.length != 0 &amp;&amp; data.length != 0)
                                {
                                  $(&quot;select#deliveryitem-0-storage_id&quot;).html(data);
                                  document.getElementById(&quot;deliveryitem-0-storage_id&quot;).disabled = false;
                                }
                                else
                                {
                                    $(&quot;select#deliveryitem-0-storage_id&quot;).html(&quot;<option>Избери номенклатура</option>&quot;);
                                    document.getElementById(&quot;deliveryitem-0-storage_id&quot;).disabled = true;
                                }
                             });" aria-invalid="false">
</select>

This is the second dynamic form that “$i” is not incremented and still selects the Storage field from the first dynamic form.

<select id="deliveryitem-1-nomenclature_id" class="form-control is-valid" name="DeliveryItem[1][nomenclature_id]" onchange="$.post(&quot;storages?id=&quot;+$(this).val(), function(data) {
                                if(value.length != 0 &amp;&amp; data.length != 0)
                                {
                                  $(&quot;select#deliveryitem-0-storage_id&quot;).html(data);
                                  document.getElementById(&quot;deliveryitem-0-storage_id&quot;).disabled = false;
                                }
                                else
                                {
                                    $(&quot;select#deliveryitem-0-storage_id&quot;).html(&quot;<option>Избери номенклатура</option>&quot;);
                                    document.getElementById(&quot;deliveryitem-0-storage_id&quot;).disabled = true;
                                }
                             });" aria-invalid="false">
</select>

So for the first dynamic form everything works fine. It selects the Storage field and imports all the html data that i need inside. But when adding new dynamic form it still selects the Storage from first dynamic form. And the “$i” inside of “onchange” does not increment. But everywhere else it increments. How to fix this? Do I need to make this selection for Storage field inside the javascript for the dynamic form and import data from there? Thanks!

Hi @BomFunK,

As far as I know, the dynamic form repeats the items dynamically by duplicating the first item. That means, when the first item has a field with id, then it will be repeated. And as a result, any javascript that tries to locate the element by its id can easily fail since there can be multiple elements with the same id.

So, I think you have to modify your javascript so that it will work without referring to the ids of the elements.

As @softark says you had to change the way you refer to the new element.

Take a look to https://demos.krajee.com/widget-details/depdrop for easy way to make dependent drop-down.