feature_image_Fixing-Yii2-DynamicForm-Extension-Preventing-Cloned-Rows-from-Copying-Data
Home » Blog » Yii2.0 framework » Fixing Yii2 DynamicForm Extension: Preventing Cloned Rows from Copying Data

Fixing Yii2 DynamicForm Extension: Preventing Cloned Rows from Copying Data

Updated:   Yii2.0 framework 2 min read

Your support helps keep this blog running! Secure payments via Paypal and Stripe.


The wbraganca/yii2-dynamicform extension is one of the most popular Yii2 tools for handling tabular input forms. It makes it easy to add and remove rows dynamically for related models, like invoice line items or order details.

However, if you’ve ever used it in an update form, you may have run into a frustrating bug:

  • When adding a new row, the first row gets cloned with its data.
  • The hidden primary key (id) field is also copied, so Yii2 thinks the new row is an update to the first record instead of inserting a new one.
  • As a result, only the last new row is saved, and it overwrites the first row.

Let’s fix that.

Why this happens

Looking at the extension’s source code (yii2-dynamic-form.js), new rows are created by cloning the first row in the container:

$toclone = $(widgetOptions.template);
$newclone = $toclone.clone(false, false);

This means every input, including hidden IDs and values, is carried into the new row. Unless those values are cleared, Yii2 will treat them as existing records.

The Fix: Clear Values After Cloning

The solution is simple: reset all cloned input values and clear the hidden primary key field before inserting the new row. Here’s the modified _addItem function:

var _addItem = function(widgetOptions, e, $elem) {
var count = _count($elem, widgetOptions);

if (count < widgetOptions.limit) {
    $toclone = $(widgetOptions.template);
    $newclone = $toclone.clone(false, false);

    // clear all cloned field values
    $newclone.find('input, textarea, select').each(function () {
        var type = $(this).attr('type');
        if (type === 'checkbox' || type === 'radio') {
            $(this).prop('checked', false);
        } else {
            $(this).val('');
        }
    });

    // clear PK hidden field
    $newclone.find('input[type="hidden"][name$="[id]"]').val('');

    if (widgetOptions.insertPosition === 'top') {
        $elem.closest('.' + widgetOptions.widgetContainer)
             .find(widgetOptions.widgetBody).prepend($newclone);
    } else {
        $elem.closest('.' + widgetOptions.widgetContainer)
             .find(widgetOptions.widgetBody).append($newclone);
    }

    _updateAttributes(widgetOptions);
    _restoreSpecialJs(widgetOptions);
    _fixFormValidaton(widgetOptions);
    $elem.closest('.' + widgetOptions.widgetContainer)
         .triggerHandler(events.afterInsert, $newclone);
} else {
    $elem.closest('.' + widgetOptions.widgetContainer)
         .triggerHandler(events.limitReached, widgetOptions.limit);
}
};

Note

If you use the minified version of the yii2-dynamic-form.js file, you will need to regenerate yii2-dynamic-form.min.js. If you have Yii2 cache enabled, you will need to clear it to see the changes (“web/assets”).

Result

With this fix:

  • Every new row is inserted blank (no copied values).
  • The hidden id field is cleared, so Yii2 knows it’s a new record.
  • Saving works as expected: new rows are inserted, existing rows are updated, and nothing is overwritten.

Conclusion

This small tweak makes yii2-dynamicform work reliably in both create and update scenarios. If you’re maintaining projects that rely on this extension, patching the JavaScript is essential to avoid data corruption.

You can either:

  • Patch the _addItem function directly in yii2-dynamic-form.js, or
  • Hook into the afterInsert event and add your cleanup code there.

For production systems, I recommend maintaining a patched copy of yii2-dynamic-form.js to ensure consistent behavior across all forms.


Your support helps keep this blog running! Secure payments via Paypal and Stripe.


Senior WordPress Developer (Freelancer)

Senior WordPress Developer (Freelancer)

I’m a professional WordPress and WooCommerce developer based in Chiang Mai, Thailand, with over a decade of experience creating fast, secure, and scalable websites. From custom themes and plugins to full WooCommerce stores, I help businesses build a strong and reliable online presence. Need a freelance WordPress developer you can count on? View my portfolio or get in touch to discuss your project.